All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chuck Lever III <chuck.lever@oracle.com>
To: Neil Brown <neilb@suse.de>
Cc: Jeff Layton <jlayton@kernel.org>,
	Linux NFS Mailing List <linux-nfs@vger.kernel.org>
Subject: Re: [PATCH 7/8] NFSD: use (un)lock_inode instead of fh_(un)lock for file operations
Date: Wed, 6 Jul 2022 16:30:12 +0000	[thread overview]
Message-ID: <0B0BE802-9B4A-4732-B798-2F13A8A6B93C@oracle.com> (raw)
In-Reply-To: <165708109260.1940.6599746560136720935.stgit@noble.brown>



> On Jul 6, 2022, at 12:18 AM, NeilBrown <neilb@suse.de> wrote:
> 
> When locking a file to access ACLs and xattrs etc, use explicit locking
> with inode_lock() instead of fh_lock().  This means that the calls to
> fh_fill_pre/post_attr() are also explicit which improves readability and
> allows us to place them only where they are needed.  Only the xattr
> calls need pre/post information.
> 
> When locking a file we don't need I_MUTEX_PARENT as the file is not a
> parent of anything, so we can use inode_lock() directly rather than the
> inode_lock_nested() call that fh_lock() uses.
> 
> Signed-off-by: NeilBrown <neilb@suse.de>
> ---
> fs/nfsd/nfs2acl.c   |    6 +++---
> fs/nfsd/nfs3acl.c   |    4 ++--
> fs/nfsd/nfs4acl.c   |    7 +++----
> fs/nfsd/nfs4state.c |    8 ++++----
> fs/nfsd/vfs.c       |   25 ++++++++++++-------------
> 5 files changed, 24 insertions(+), 26 deletions(-)
> 
> diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
> index b5760801d377..9edd3c1a30fb 100644
> --- a/fs/nfsd/nfs2acl.c
> +++ b/fs/nfsd/nfs2acl.c
> @@ -111,7 +111,7 @@ static __be32 nfsacld_proc_setacl(struct svc_rqst *rqstp)
> 	if (error)
> 		goto out_errno;
> 
> -	fh_lock(fh);
> +	inode_lock(inode);
> 
> 	error = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS,
> 			      argp->acl_access);
> @@ -122,7 +122,7 @@ static __be32 nfsacld_proc_setacl(struct svc_rqst *rqstp)
> 	if (error)
> 		goto out_drop_lock;
> 
> -	fh_unlock(fh);
> +	inode_unlock(inode);
> 
> 	fh_drop_write(fh);
> 
> @@ -136,7 +136,7 @@ static __be32 nfsacld_proc_setacl(struct svc_rqst *rqstp)
> 	return rpc_success;
> 
> out_drop_lock:
> -	fh_unlock(fh);
> +	inode_unlock(inode);
> 	fh_drop_write(fh);
> out_errno:
> 	resp->status = nfserrno(error);
> diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
> index 35b2ebda14da..9446c6743664 100644
> --- a/fs/nfsd/nfs3acl.c
> +++ b/fs/nfsd/nfs3acl.c
> @@ -101,7 +101,7 @@ static __be32 nfsd3_proc_setacl(struct svc_rqst *rqstp)
> 	if (error)
> 		goto out_errno;
> 
> -	fh_lock(fh);
> +	inode_lock(inode);
> 
> 	error = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS,
> 			      argp->acl_access);
> @@ -111,7 +111,7 @@ static __be32 nfsd3_proc_setacl(struct svc_rqst *rqstp)
> 			      argp->acl_default);
> 
> out_drop_lock:
> -	fh_unlock(fh);
> +	inode_unlock(inode);
> 	fh_drop_write(fh);
> out_errno:
> 	resp->status = nfserrno(error);
> diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
> index 5c9b7e01e8ca..a33cacf62ea0 100644
> --- a/fs/nfsd/nfs4acl.c
> +++ b/fs/nfsd/nfs4acl.c
> @@ -781,19 +781,18 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
> 	if (host_error < 0)
> 		goto out_nfserr;
> 
> -	fh_lock(fhp);
> +	inode_lock(inode);
> 
> 	host_error = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS, pacl);
> 	if (host_error < 0)
> 		goto out_drop_lock;
> 
> -	if (S_ISDIR(inode->i_mode)) {
> +	if (S_ISDIR(inode->i_mode))
> 		host_error = set_posix_acl(&init_user_ns, inode,
> 					   ACL_TYPE_DEFAULT, dpacl);
> -	}
> 
> out_drop_lock:
> -	fh_unlock(fhp);
> +	inode_unlock(inode);
> 
> 	posix_acl_release(pacl);
> 	posix_acl_release(dpacl);
> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> index 9d1a3e131c49..307317ba9aff 100644
> --- a/fs/nfsd/nfs4state.c
> +++ b/fs/nfsd/nfs4state.c
> @@ -7322,21 +7322,21 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
> static __be32 nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock)
> {
> 	struct nfsd_file *nf;
> +	struct inode *inode = fhp->fh_dentry->d_inode;

I don't think this is correct.

nfsd_file_acquire() calls fh_verify(), which can updated fhp->fh_dentry.
Anyway, is it guaranteed that fh_dentry is not NULL here?

It would be more defensive to set @inode /after/ the call to
nfsd_file_acquire().


> 	__be32 err;
> 
> 	err = nfsd_file_acquire(rqstp, fhp, NFSD_MAY_READ, &nf);
> 	if (err)
> 		return err;
> -	fh_lock(fhp); /* to block new leases till after test_lock: */
> -	err = nfserrno(nfsd_open_break_lease(fhp->fh_dentry->d_inode,
> -							NFSD_MAY_READ));
> +	inode_lock(inode); /* to block new leases till after test_lock: */
> +	err = nfserrno(nfsd_open_break_lease(inode, NFSD_MAY_READ));
> 	if (err)
> 		goto out;
> 	lock->fl_file = nf->nf_file;
> 	err = nfserrno(vfs_test_lock(nf->nf_file, lock));
> 	lock->fl_file = NULL;
> out:
> -	fh_unlock(fhp);
> +	inode_unlock(inode);
> 	nfsd_file_put(nf);
> 	return err;
> }
> diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
> index 2ca748aa83bb..2526615285ca 100644
> --- a/fs/nfsd/vfs.c
> +++ b/fs/nfsd/vfs.c
> @@ -444,7 +444,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
> 			return err;
> 	}
> 
> -	fh_lock(fhp);
> +	inode_lock(inode);
> 	if (size_change) {
> 		/*
> 		 * RFC5661, Section 18.30.4:
> @@ -480,7 +480,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
> 	host_err = notify_change(&init_user_ns, dentry, iap, NULL);
> 
> out_unlock:
> -	fh_unlock(fhp);
> +	inode_unlock(inode);
> 	if (size_change)
> 		put_write_access(inode);
> out:
> @@ -2196,12 +2196,8 @@ nfsd_listxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char **bufp,
> }
> 
> /*
> - * Removexattr and setxattr need to call fh_lock to both lock the inode
> - * and set the change attribute. Since the top-level vfs_removexattr
> - * and vfs_setxattr calls already do their own inode_lock calls, call
> - * the _locked variant. Pass in a NULL pointer for delegated_inode,
> - * and let the client deal with NFS4ERR_DELAY (same as with e.g.
> - * setattr and remove).
> + * Pass in a NULL pointer for delegated_inode, and let the client deal
> + * with NFS4ERR_DELAY (same as with e.g.  setattr and remove).
>  */
> __be32
> nfsd_removexattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char *name)
> @@ -2217,12 +2213,14 @@ nfsd_removexattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char *name)
> 	if (ret)
> 		return nfserrno(ret);
> 
> -	fh_lock(fhp);
> +	inode_lock(fhp->fh_dentry->d_inode);
> +	fh_fill_pre_attrs(fhp);
> 
> 	ret = __vfs_removexattr_locked(&init_user_ns, fhp->fh_dentry,
> 				       name, NULL);
> 
> -	fh_unlock(fhp);
> +	fh_fill_post_attrs(fhp);
> +	inode_unlock(fhp->fh_dentry->d_inode);
> 	fh_drop_write(fhp);
> 
> 	return nfsd_xattr_errno(ret);
> @@ -2242,12 +2240,13 @@ nfsd_setxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char *name,
> 	ret = fh_want_write(fhp);
> 	if (ret)
> 		return nfserrno(ret);
> -	fh_lock(fhp);
> +	inode_lock(fhp->fh_dentry->d_inode);
> +	fh_fill_pre_attrs(fhp);
> 
> 	ret = __vfs_setxattr_locked(&init_user_ns, fhp->fh_dentry, name, buf,
> 				    len, flags, NULL);
> -
> -	fh_unlock(fhp);
> +	fh_fill_post_attrs(fhp);
> +	inode_unlock(fhp->fh_dentry->d_inode);
> 	fh_drop_write(fhp);
> 
> 	return nfsd_xattr_errno(ret);
> 
> 

--
Chuck Lever




  parent reply	other threads:[~2022-07-06 16:30 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-06  4:18 [PATCH 0/8] NFSD: clean up locking NeilBrown
2022-07-06  4:18 ` [PATCH 6/8] NFSD: use explicit lock/unlock for directory ops NeilBrown
2022-07-06 14:05   ` Jeff Layton
2022-07-06 16:29   ` Chuck Lever III
2022-07-15 16:11   ` Jeff Layton
2022-07-15 18:22     ` Jeff Layton
2022-07-17 23:59       ` NeilBrown
2022-07-17 23:43     ` NeilBrown
2022-07-06  4:18 ` [PATCH 8/8] NFSD: discard fh_locked flag and fh_lock/fh_unlock NeilBrown
2022-07-06 14:12   ` Jeff Layton
2022-07-06  4:18 ` [PATCH 7/8] NFSD: use (un)lock_inode instead of fh_(un)lock for file operations NeilBrown
2022-07-06 14:10   ` Jeff Layton
2022-07-06 16:30   ` Chuck Lever III [this message]
2022-07-07  1:33     ` NeilBrown
2022-07-06  4:18 ` [PATCH 2/8] NFSD: change nfsd_create() to unlock directory before returning NeilBrown
2022-07-06 13:24   ` Jeff Layton
2022-07-06 16:29   ` Chuck Lever III
2022-07-06  4:18 ` [PATCH 1/8] NFSD: drop rqstp arg to do_set_nfs4_acl() NeilBrown
2022-07-06 13:17   ` Jeff Layton
2022-07-06  4:18 ` [PATCH 4/8] NFSD: only call fh_unlock() once in nfsd_link() NeilBrown
2022-07-06 13:31   ` Jeff Layton
2022-07-06 16:29   ` Chuck Lever III
2022-07-06  4:18 ` [PATCH 3/8] NFSD: always drop directory lock in nfsd_unlink() NeilBrown
2022-07-06 13:30   ` Jeff Layton
2022-07-06  4:18 ` [PATCH 5/8] NFSD: reduce locking in nfsd_lookup() NeilBrown
2022-07-06 13:47   ` Jeff Layton
2022-07-07  1:26     ` NeilBrown
2022-07-06 16:29   ` Chuck Lever III
2022-07-07  1:29     ` NeilBrown
2022-07-06 16:29 ` [PATCH 0/8] NFSD: clean up locking Chuck Lever III
2022-07-12  2:33   ` NeilBrown
2022-07-12 14:17     ` Chuck Lever III
2022-07-13  4:32       ` NeilBrown
2022-07-13 14:15         ` Chuck Lever III
2022-07-13 19:13           ` Jeff Layton
2022-07-14 14:32             ` Chuck Lever III
2022-07-15  2:36           ` NeilBrown
2022-07-15 13:01             ` Jeff Layton
2022-07-15 13:53               ` Jeff Layton
2022-07-15 14:06             ` Chuck Lever III

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0B0BE802-9B4A-4732-B798-2F13A8A6B93C@oracle.com \
    --to=chuck.lever@oracle.com \
    --cc=jlayton@kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=neilb@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.