summaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs3proc.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2022-07-26 16:45:30 +1000
committerChuck Lever <chuck.lever@oracle.com>2022-08-04 10:28:20 -0400
commitdebf16f0c671cb8db154a9ebcd6014cfff683b80 (patch)
tree18ca8bf2bfc9fc03ddad5114d2ebd5bf9872ffd8 /fs/nfsd/nfs3proc.c
parent19d008b46941b8c668402170522e0f7a9258409c (diff)
downloadlinux-stable-debf16f0c671cb8db154a9ebcd6014cfff683b80.tar.gz
linux-stable-debf16f0c671cb8db154a9ebcd6014cfff683b80.tar.bz2
linux-stable-debf16f0c671cb8db154a9ebcd6014cfff683b80.zip
NFSD: use explicit lock/unlock for directory ops
When creating or unlinking a name in a directory use explicit inode_lock_nested() instead of fh_lock(), and explicit calls to fh_fill_pre_attrs() and fh_fill_post_attrs(). This is already done for renames, with lock_rename() as the explicit locking. Also move the 'fill' calls closer to the operation that might change the attributes. This way they are avoided on some error paths. For the v2-only code in nfsproc.c, the fill calls are not replaced as they aren't needed. Making the locking explicit will simplify proposed future changes to locking for directories. It also makes it easily visible exactly where pre/post attributes are used - not all callers of fh_lock() actually need the pre/post attributes. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Diffstat (limited to 'fs/nfsd/nfs3proc.c')
-rw-r--r--fs/nfsd/nfs3proc.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 3de9b008626c..a41cca619338 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -260,7 +260,7 @@ nfsd3_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp,
if (host_err)
return nfserrno(host_err);
- fh_lock_nested(fhp, I_MUTEX_PARENT);
+ inode_lock_nested(inode, I_MUTEX_PARENT);
child = lookup_one_len(argp->name, parent, argp->len);
if (IS_ERR(child)) {
@@ -318,11 +318,13 @@ nfsd3_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp,
if (!IS_POSIXACL(inode))
iap->ia_mode &= ~current_umask();
+ fh_fill_pre_attrs(fhp);
host_err = vfs_create(&init_user_ns, inode, child, iap->ia_mode, true);
if (host_err < 0) {
status = nfserrno(host_err);
goto out;
}
+ fh_fill_post_attrs(fhp);
/* A newly created file already has a file size of zero. */
if ((iap->ia_valid & ATTR_SIZE) && (iap->ia_size == 0))
@@ -340,7 +342,7 @@ set_attr:
status = nfsd_create_setattr(rqstp, fhp, resfhp, &attrs);
out:
- fh_unlock(fhp);
+ inode_unlock(inode);
if (child && !IS_ERR(child))
dput(child);
fh_drop_write(fhp);