Merge branch 'for-2.6.30' of git://linux-nfs.org/~bfields/linux
* 'for-2.6.30' of git://linux-nfs.org/~bfields/linux: (81 commits) nfsd41: define nfsd4_set_statp as noop for !CONFIG_NFSD_V4 nfsd41: define NFSD_DRC_SIZE_SHIFT in set_max_drc nfsd41: Documentation/filesystems/nfs41-server.txt nfsd41: CREATE_EXCLUSIVE4_1 nfsd41: SUPPATTR_EXCLCREAT attribute nfsd41: support for 3-word long attribute bitmask nfsd: dynamically skip encoded fattr bitmap in _nfsd4_verify nfsd41: pass writable attrs mask to nfsd4_decode_fattr nfsd41: provide support for minor version 1 at rpc level nfsd41: control nfsv4.1 svc via /proc/fs/nfsd/versions nfsd41: add OPEN4_SHARE_ACCESS_WANT nfs4_stateid bmap nfsd41: access_valid nfsd41: clientid handling nfsd41: check encode size for sessions maxresponse cached nfsd41: stateid handling nfsd: pass nfsd4_compound_state* to nfs4_preprocess_{state,seq}id_op nfsd41: destroy_session operation nfsd41: non-page DRC for solo sequence responses nfsd41: Add a create session replay cache nfsd41: create_session operation ...
This commit is contained in:
@@ -366,8 +366,9 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
|
||||
}
|
||||
|
||||
/* Revoke setuid/setgid on chown */
|
||||
if (((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) ||
|
||||
((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid)) {
|
||||
if (!S_ISDIR(inode->i_mode) &&
|
||||
(((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) ||
|
||||
((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid))) {
|
||||
iap->ia_valid |= ATTR_KILL_PRIV;
|
||||
if (iap->ia_valid & ATTR_MODE) {
|
||||
/* we're setting mode too, just clear the s*id bits */
|
||||
@@ -960,7 +961,7 @@ static void kill_suid(struct dentry *dentry)
|
||||
static __be32
|
||||
nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
|
||||
loff_t offset, struct kvec *vec, int vlen,
|
||||
unsigned long cnt, int *stablep)
|
||||
unsigned long *cnt, int *stablep)
|
||||
{
|
||||
struct svc_export *exp;
|
||||
struct dentry *dentry;
|
||||
@@ -974,7 +975,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
|
||||
err = nfserr_perm;
|
||||
|
||||
if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
|
||||
(!lock_may_write(file->f_path.dentry->d_inode, offset, cnt)))
|
||||
(!lock_may_write(file->f_path.dentry->d_inode, offset, *cnt)))
|
||||
goto out;
|
||||
#endif
|
||||
|
||||
@@ -1009,7 +1010,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
|
||||
host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset);
|
||||
set_fs(oldfs);
|
||||
if (host_err >= 0) {
|
||||
nfsdstats.io_write += cnt;
|
||||
nfsdstats.io_write += host_err;
|
||||
fsnotify_modify(file->f_path.dentry);
|
||||
}
|
||||
|
||||
@@ -1054,9 +1055,10 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
|
||||
}
|
||||
|
||||
dprintk("nfsd: write complete host_err=%d\n", host_err);
|
||||
if (host_err >= 0)
|
||||
if (host_err >= 0) {
|
||||
err = 0;
|
||||
else
|
||||
*cnt = host_err;
|
||||
} else
|
||||
err = nfserrno(host_err);
|
||||
out:
|
||||
return err;
|
||||
@@ -1098,7 +1100,7 @@ out:
|
||||
*/
|
||||
__be32
|
||||
nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
|
||||
loff_t offset, struct kvec *vec, int vlen, unsigned long cnt,
|
||||
loff_t offset, struct kvec *vec, int vlen, unsigned long *cnt,
|
||||
int *stablep)
|
||||
{
|
||||
__be32 err = 0;
|
||||
@@ -1179,6 +1181,21 @@ nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *resfhp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* HPUX client sometimes creates a file in mode 000, and sets size to 0.
|
||||
* setting size to 0 may fail for some specific file systems by the permission
|
||||
* checking which requires WRITE permission but the mode is 000.
|
||||
* we ignore the resizing(to 0) on the just new created file, since the size is
|
||||
* 0 after file created.
|
||||
*
|
||||
* call this only after vfs_create() is called.
|
||||
* */
|
||||
static void
|
||||
nfsd_check_ignore_resizing(struct iattr *iap)
|
||||
{
|
||||
if ((iap->ia_valid & ATTR_SIZE) && (iap->ia_size == 0))
|
||||
iap->ia_valid &= ~ATTR_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a file (regular, directory, device, fifo); UNIX sockets
|
||||
* not yet implemented.
|
||||
@@ -1274,6 +1291,8 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
||||
switch (type) {
|
||||
case S_IFREG:
|
||||
host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
|
||||
if (!host_err)
|
||||
nfsd_check_ignore_resizing(iap);
|
||||
break;
|
||||
case S_IFDIR:
|
||||
host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
|
||||
@@ -1427,6 +1446,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
||||
/* setattr will sync the child (or not) */
|
||||
}
|
||||
|
||||
nfsd_check_ignore_resizing(iap);
|
||||
|
||||
if (createmode == NFS3_CREATE_EXCLUSIVE) {
|
||||
/* Cram the verifier into atime/mtime */
|
||||
iap->ia_valid = ATTR_MTIME|ATTR_ATIME
|
||||
|
Reference in New Issue
Block a user