Re: [PATCH RFC] NFSD: Instantiate a filecache entry when creating a file

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2022-03-24 at 18:08 -0400, Chuck Lever wrote:
> There have been reports of races that cause NFSv4 OPEN(CREATE) to
> return an error even though the requested file was created. NFSv4
> does not seem to provide a status code for this case.
> 
> There are plenty of things that can go wrong between the
> vfs_create() call in do_nfsd_create() and nfs4_vfs_get_file(), but
> one of them is another client looking up and modifying the file's
> mode bits in that window. If that happens, the creator might lose
> access to the file before it can be opened.
> 
> Instead of opening the newly created file in nfsd4_process_open2(),
> open it as soon as the file is created, and leave it sitting in the
> file cache.
> 
> This patch is not optimal, of course - we should replace the
> vfs_create() call in do_nfsd_create() with a call that creates the
> file and returns a "struct file *" that can be planted immediately
> in nf->nf_file.
> 
> But first, I would like to hear opinions about the approach
> suggested above.
> 
> BugLink: https://bugzilla.linux-nfs.org/show_bug.cgi?id=382
> Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx>
> ---
>  fs/nfsd/vfs.c |    9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
> index 02a544645b52..80b568fa12f1 100644
> --- a/fs/nfsd/vfs.c
> +++ b/fs/nfsd/vfs.c
> @@ -1410,6 +1410,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct
> svc_fh *fhp,
>         __be32          err;
>         int             host_err;
>         __u32           v_mtime=0, v_atime=0;
> +       struct nfsd_file *nf;
>  
>         /* XXX: Shouldn't this be nfserr_inval? */
>         err = nfserr_perm;
> @@ -1535,6 +1536,14 @@ do_nfsd_create(struct svc_rqst *rqstp, struct
> svc_fh *fhp,
>                 iap->ia_atime.tv_nsec = 0;
>         }
>  
> +       /* Attempt to instantiate a filecache entry while we still
> hold
> +        * the parent's inode mutex. */
> +       err = nfsd_file_acquire(rqstp, resfhp, NFSD_MAY_WRITE, &nf);
> +       if (err)
> +               /* This would be bad */
> +               goto out;
> +       nfsd_file_put(nf);

Why rely on the file cache to carry the nfsd_file? Isn't it much easier
just to pass it back directly to the caller?

There are only 2 callers of do_nfsd_create(), so you'd have
nfsd3_proc_create() that will just call nfsd_file_put() as per above,
whereas the NFSv4 specific do_open_lookup() could just stash it in the
struct nfsd4_open so that it can get passed into do_open_permission()
and eventually nfsd4_process_open2().

> +
>   set_attr:
>         err = nfsd_create_setattr(rqstp, resfhp, iap);
>  
> 
> 

-- 
Trond Myklebust
Linux NFS client maintainer, Hammerspace
trond.myklebust@xxxxxxxxxxxxxxx






[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux