aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs3proc.c2
-rw-r--r--fs/nfsd/nfs4proc.c26
-rw-r--r--fs/nfsd/nfs4recover.c2
-rw-r--r--fs/nfsd/vfs.c6
4 files changed, 19 insertions, 17 deletions
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 64db601c2bd2..7f5bad0393b1 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -258,7 +258,7 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
258 /* Now create the file and set attributes */ 258 /* Now create the file and set attributes */
259 nfserr = nfsd_create_v3(rqstp, dirfhp, argp->name, argp->len, 259 nfserr = nfsd_create_v3(rqstp, dirfhp, argp->name, argp->len,
260 attr, newfhp, 260 attr, newfhp,
261 argp->createmode, argp->verf, NULL); 261 argp->createmode, argp->verf, NULL, NULL);
262 262
263 RETURN_STATUS(nfserr); 263 RETURN_STATUS(nfserr);
264} 264}
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 0a7bbdc4a10a..50bc94243ca1 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -93,6 +93,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
93{ 93{
94 struct svc_fh resfh; 94 struct svc_fh resfh;
95 __be32 status; 95 __be32 status;
96 int created = 0;
96 97
97 fh_init(&resfh, NFS4_FHSIZE); 98 fh_init(&resfh, NFS4_FHSIZE);
98 open->op_truncate = 0; 99 open->op_truncate = 0;
@@ -105,28 +106,27 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
105 status = nfsd_create_v3(rqstp, current_fh, open->op_fname.data, 106 status = nfsd_create_v3(rqstp, current_fh, open->op_fname.data,
106 open->op_fname.len, &open->op_iattr, 107 open->op_fname.len, &open->op_iattr,
107 &resfh, open->op_createmode, 108 &resfh, open->op_createmode,
108 (u32 *)open->op_verf.data, &open->op_truncate); 109 (u32 *)open->op_verf.data, &open->op_truncate, &created);
109 } 110 } else {
110 else {
111 status = nfsd_lookup(rqstp, current_fh, 111 status = nfsd_lookup(rqstp, current_fh,
112 open->op_fname.data, open->op_fname.len, &resfh); 112 open->op_fname.data, open->op_fname.len, &resfh);
113 fh_unlock(current_fh); 113 fh_unlock(current_fh);
114 } 114 }
115 if (status)
116 goto out;
115 117
116 if (!status) { 118 set_change_info(&open->op_cinfo, current_fh);
117 set_change_info(&open->op_cinfo, current_fh);
118 119
119 /* set reply cache */ 120 /* set reply cache */
120 fh_dup2(current_fh, &resfh); 121 fh_dup2(current_fh, &resfh);
121 open->op_stateowner->so_replay.rp_openfh_len = 122 open->op_stateowner->so_replay.rp_openfh_len = resfh.fh_handle.fh_size;
122 resfh.fh_handle.fh_size; 123 memcpy(open->op_stateowner->so_replay.rp_openfh,
123 memcpy(open->op_stateowner->so_replay.rp_openfh, 124 &resfh.fh_handle.fh_base, resfh.fh_handle.fh_size);
124 &resfh.fh_handle.fh_base,
125 resfh.fh_handle.fh_size);
126 125
126 if (!created)
127 status = do_open_permission(rqstp, current_fh, open, MAY_NOP); 127 status = do_open_permission(rqstp, current_fh, open, MAY_NOP);
128 }
129 128
129out:
130 fh_put(&resfh); 130 fh_put(&resfh);
131 return status; 131 return status;
132} 132}
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index e9d07704680e..81b8565d3837 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -274,7 +274,7 @@ nfsd4_clear_clid_dir(struct dentry *dir, struct dentry *dentry)
274 * any regular files anyway, just in case the directory was created by 274 * any regular files anyway, just in case the directory was created by
275 * a kernel from the future.... */ 275 * a kernel from the future.... */
276 nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file); 276 nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file);
277 mutex_lock(&dir->d_inode->i_mutex); 277 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
278 status = vfs_rmdir(dir->d_inode, dentry); 278 status = vfs_rmdir(dir->d_inode, dentry);
279 mutex_unlock(&dir->d_inode->i_mutex); 279 mutex_unlock(&dir->d_inode->i_mutex);
280 return status; 280 return status;
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index f21e917bb8ed..bb4d926e4487 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1177,7 +1177,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1177 /* 1177 /*
1178 * Get the dir op function pointer. 1178 * Get the dir op function pointer.
1179 */ 1179 */
1180 err = nfserr_perm; 1180 err = 0;
1181 switch (type) { 1181 switch (type) {
1182 case S_IFREG: 1182 case S_IFREG:
1183 host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); 1183 host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
@@ -1237,7 +1237,7 @@ __be32
1237nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, 1237nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1238 char *fname, int flen, struct iattr *iap, 1238 char *fname, int flen, struct iattr *iap,
1239 struct svc_fh *resfhp, int createmode, u32 *verifier, 1239 struct svc_fh *resfhp, int createmode, u32 *verifier,
1240 int *truncp) 1240 int *truncp, int *created)
1241{ 1241{
1242 struct dentry *dentry, *dchild = NULL; 1242 struct dentry *dentry, *dchild = NULL;
1243 struct inode *dirp; 1243 struct inode *dirp;
@@ -1331,6 +1331,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1331 host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); 1331 host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
1332 if (host_err < 0) 1332 if (host_err < 0)
1333 goto out_nfserr; 1333 goto out_nfserr;
1334 if (created)
1335 *created = 1;
1334 1336
1335 if (EX_ISSYNC(fhp->fh_export)) { 1337 if (EX_ISSYNC(fhp->fh_export)) {
1336 err = nfserrno(nfsd_sync_dir(dentry)); 1338 err = nfserrno(nfsd_sync_dir(dentry));