All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@kernel.org>
To: cel@kernel.org, Neil Brown <neilb@suse.de>,
	Olga Kornievskaia	 <okorniev@redhat.com>,
	Dai Ngo <dai.ngo@oracle.com>, Tom Talpey <tom@talpey.com>
Cc: linux-nfs@vger.kernel.org, Chuck Lever <chuck.lever@oracle.com>
Subject: Re: [RFC PATCH 4/4] NFSD: Return NFS4ERR_FILE_OPEN only when linking an open file
Date: Thu, 23 Jan 2025 15:52:26 -0500	[thread overview]
Message-ID: <0a1607952bc35549c925da8599ce366feb951850.camel@kernel.org> (raw)
In-Reply-To: <20250123195242.1378601-5-cel@kernel.org>

On Thu, 2025-01-23 at 14:52 -0500, cel@kernel.org wrote:
> From: Chuck Lever <chuck.lever@oracle.com>
> 
> RFC 8881 Section 18.9.4 paragraphs 1 - 2 tell us that RENAME should
> return NFS4ERR_FILE_OPEN only when the target object is a file that
> is currently open. If the target is a directory, some other status
> must be returned.
> 
> Generally I expect that a delegation recall will be triggered in
> some of these circumstances. In other cases, the VFS might return
> -EBUSY for other reasons, and NFSD has to ensure that errno does
> not leak to clients as a status code that is not permitted by spec.
> 
> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
> ---
>  fs/nfsd/vfs.c | 44 +++++++++++++++++++++++++++++++-------------
>  1 file changed, 31 insertions(+), 13 deletions(-)
> 
> diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
> index 5cfb5eb54c23..566b9adf2259 100644
> --- a/fs/nfsd/vfs.c
> +++ b/fs/nfsd/vfs.c
> @@ -1699,9 +1699,17 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
>  	return err;
>  }
>  
> -/*
> - * Create a hardlink
> - * N.B. After this call _both_ ffhp and tfhp need an fh_put
> +/**
> + * nfsd_link - create a link
> + * @rqstp: RPC transaction context
> + * @ffhp: the file handle of the directory where the new link is to be created
> + * @name: the filename of the new link
> + * @len: the length of @name in octets
> + * @tfhp: the file handle of an existing file object
> + *
> + * After this call _both_ ffhp and tfhp need an fh_put.
> + *
> + * Returns a generic NFS status code in network byte-order.
>   */
>  __be32
>  nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
> @@ -1709,6 +1717,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
>  {
>  	struct dentry	*ddir, *dnew, *dold;
>  	struct inode	*dirp;
> +	int		type;
>  	__be32		err;
>  	int		host_err;
>  
> @@ -1728,11 +1737,11 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
>  	if (isdotent(name, len))
>  		goto out;
>  
> +	err = nfs_ok;
> +	type = d_inode(tfhp->fh_dentry)->i_mode & S_IFMT;
>  	host_err = fh_want_write(tfhp);
> -	if (host_err) {
> -		err = nfserrno(host_err);
> +	if (host_err)
>  		goto out;
> -	}
>  
>  	ddir = ffhp->fh_dentry;
>  	dirp = d_inode(ddir);
> @@ -1740,7 +1749,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
>  
>  	dnew = lookup_one_len(name, ddir, len);
>  	if (IS_ERR(dnew)) {
> -		err = nfserrno(PTR_ERR(dnew));
> +		host_err = PTR_ERR(dnew);
>  		goto out_unlock;
>  	}
>  
> @@ -1756,17 +1765,26 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
>  	fh_fill_post_attrs(ffhp);
>  	inode_unlock(dirp);
>  	if (!host_err) {
> -		err = nfserrno(commit_metadata(ffhp));
> -		if (!err)
> -			err = nfserrno(commit_metadata(tfhp));
> -	} else {
> -		err = nfserrno(host_err);
> +		host_err = commit_metadata(ffhp);
> +		if (!host_err)
> +			host_err = commit_metadata(tfhp);
>  	}
> +
>  	dput(dnew);
>  out_drop_write:
>  	fh_drop_write(tfhp);
> +	if (host_err == -EBUSY) {
> +		/*
> +		 * See RFC 8881 Section 18.9.4 para 1-2: NFSv4 LINK
> +		 * status distinguishes between reg file and dir.
> +		 */
> +		if (type != S_IFDIR)
> +			err = nfserr_file_open;
> +		else
> +			err = nfserr_acces;

I guess nothing in NFS protocol spec prohibits you from hardlinking a
directory, but hopefully any Linux filesystem will be returning -EPERM
when someone tries it! IOW, I suspect the above will probably be dead
code, but I don't think it'll hurt anything.

> +	}
>  out:
> -	return err;
> +	return err != nfs_ok ? err : nfserrno(host_err);
>  
>  out_dput:
>  	dput(dnew);

-- 
Jeff Layton <jlayton@kernel.org>

  reply	other threads:[~2025-01-23 20:52 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-23 19:52 [RFC PATCH 0/4] Avoid returning NFS4ERR_FILE_OPEN when not appropriate cel
2025-01-23 19:52 ` [RFC PATCH 1/4] NFSD: nfsd_unlink() clobbers non-zero status returned from fh_fill_pre_attrs() cel
2025-01-23 19:52 ` [RFC PATCH 2/4] NFSD: Never return NFS4ERR_FILE_OPEN when removing a directory cel
2025-01-23 20:43   ` Jeff Layton
2025-01-23 21:06     ` Chuck Lever
2025-01-24 10:42       ` Amir Goldstein
2025-01-24 14:11         ` Chuck Lever
2025-01-23 19:52 ` [RFC PATCH 3/4] NFSD: Return NFS4ERR_FILE_OPEN only when renaming over an open file cel
2025-01-24 10:47   ` Amir Goldstein
2025-01-23 19:52 ` [RFC PATCH 4/4] NFSD: Return NFS4ERR_FILE_OPEN only when linking " cel
2025-01-23 20:52   ` Jeff Layton [this message]
2025-01-24 11:22     ` Amir Goldstein
2025-01-24 14:04       ` Chuck Lever
2025-01-24 20:36         ` Amir Goldstein

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=0a1607952bc35549c925da8599ce366feb951850.camel@kernel.org \
    --to=jlayton@kernel.org \
    --cc=cel@kernel.org \
    --cc=chuck.lever@oracle.com \
    --cc=dai.ngo@oracle.com \
    --cc=linux-nfs@vger.kernel.org \
    --cc=neilb@suse.de \
    --cc=okorniev@redhat.com \
    --cc=tom@talpey.com \
    /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.