diff options
-rw-r--r-- | fs/nfsd/nfs4proc.c | 10 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 7 |
2 files changed, 13 insertions, 4 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 844813a7e12a..ef76ba632387 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -279,11 +279,15 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru | |||
279 | if (open->op_createmode == NFS4_CREATE_EXCLUSIVE && status == 0) | 279 | if (open->op_createmode == NFS4_CREATE_EXCLUSIVE && status == 0) |
280 | open->op_bmval[1] = (FATTR4_WORD1_TIME_ACCESS | | 280 | open->op_bmval[1] = (FATTR4_WORD1_TIME_ACCESS | |
281 | FATTR4_WORD1_TIME_MODIFY); | 281 | FATTR4_WORD1_TIME_MODIFY); |
282 | } else { | 282 | } else |
283 | /* | ||
284 | * Note this may exit with the parent still locked. | ||
285 | * We will hold the lock until nfsd4_open's final | ||
286 | * lookup, to prevent renames or unlinks until we've had | ||
287 | * a chance to an acquire a delegation if appropriate. | ||
288 | */ | ||
283 | status = nfsd_lookup(rqstp, current_fh, | 289 | status = nfsd_lookup(rqstp, current_fh, |
284 | open->op_fname.data, open->op_fname.len, *resfh); | 290 | open->op_fname.data, open->op_fname.len, *resfh); |
285 | fh_unlock(current_fh); | ||
286 | } | ||
287 | if (status) | 291 | if (status) |
288 | goto out; | 292 | goto out; |
289 | status = nfsd_check_obj_isreg(*resfh); | 293 | status = nfsd_check_obj_isreg(*resfh); |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index e85b463fac4a..a41302a00650 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -207,7 +207,12 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
207 | goto out_nfserr; | 207 | goto out_nfserr; |
208 | } | 208 | } |
209 | } else { | 209 | } else { |
210 | fh_lock(fhp); | 210 | /* |
211 | * In the nfsd4_open() case, this may be held across | ||
212 | * subsequent open and delegation acquisition which may | ||
213 | * need to take the child's i_mutex: | ||
214 | */ | ||
215 | fh_lock_nested(fhp, I_MUTEX_PARENT); | ||
211 | dentry = lookup_one_len(name, dparent, len); | 216 | dentry = lookup_one_len(name, dparent, len); |
212 | host_err = PTR_ERR(dentry); | 217 | host_err = PTR_ERR(dentry); |
213 | if (IS_ERR(dentry)) | 218 | if (IS_ERR(dentry)) |