lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <21904951-0cac-4a79-9be6-7dbf2f9849b6@oracle.com>
Date: Sat, 18 Oct 2025 15:33:04 -0400
From: Chuck Lever <chuck.lever@...cle.com>
To: Jeff Layton <jlayton@...nel.org>, Miklos Szeredi <miklos@...redi.hu>,
        Alexander Viro <viro@...iv.linux.org.uk>,
        Christian Brauner <brauner@...nel.org>, Jan Kara <jack@...e.cz>,
        Alexander Aring <alex.aring@...il.com>,
        Trond Myklebust
 <trondmy@...nel.org>,
        Anna Schumaker <anna@...nel.org>, Steve French <sfrench@...ba.org>,
        Paulo Alcantara <pc@...guebit.org>,
        Ronnie Sahlberg <ronniesahlberg@...il.com>,
        Shyam Prasad N <sprasad@...rosoft.com>, Tom Talpey <tom@...pey.com>,
        Bharath SM <bharathsm@...rosoft.com>,
        Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
        "Rafael J. Wysocki" <rafael@...nel.org>,
        Danilo Krummrich <dakr@...nel.org>,
        David Howells <dhowells@...hat.com>, Tyler Hicks <code@...icks.com>,
        NeilBrown <neil@...wn.name>, Olga Kornievskaia <okorniev@...hat.com>,
        Dai Ngo <Dai.Ngo@...cle.com>, Amir Goldstein <amir73il@...il.com>,
        Namjae Jeon <linkinjeon@...nel.org>, Steve French <smfrench@...il.com>,
        Sergey Senozhatsky <senozhatsky@...omium.org>,
        Carlos Maiolino <cem@...nel.org>,
        Kuniyuki Iwashima <kuniyu@...gle.com>,
        "David S. Miller" <davem@...emloft.net>,
        Eric Dumazet <edumazet@...gle.com>, Jakub Kicinski <kuba@...nel.org>,
        Paolo Abeni <pabeni@...hat.com>, Simon Horman <horms@...nel.org>
Cc: linux-fsdevel@...r.kernel.org, linux-kernel@...r.kernel.org,
        linux-nfs@...r.kernel.org, linux-cifs@...r.kernel.org,
        samba-technical@...ts.samba.org, netfs@...ts.linux.dev,
        ecryptfs@...r.kernel.org, linux-unionfs@...r.kernel.org,
        linux-xfs@...r.kernel.org, netdev@...r.kernel.org
Subject: Re: [PATCH v2 09/11] nfsd: allow filecache to hold S_IFDIR files

On 10/17/25 7:32 AM, Jeff Layton wrote:
> The filecache infrastructure will only handle S_IFREG files at the
> moment. Directory delegations will require adding support for opening
> S_IFDIR inodes.
> 
> Plumb a "type" argument into nfsd_file_do_acquire() and have all of the
> existing callers set it to S_IFREG. Add a new nfsd_file_acquire_dir()
> wrapper that nfsd can call to request a nfsd_file that holds a directory
> open.
> 
> For now, there is no need for a fsnotify_mark for directories, as
> CB_NOTIFY is not yet supported. Change nfsd_file_do_acquire() to avoid
> allocating one for non-S_IFREG inodes.
> 
> Signed-off-by: Jeff Layton <jlayton@...nel.org>
> ---
>  fs/nfsd/filecache.c | 57 ++++++++++++++++++++++++++++++++++++++++-------------
>  fs/nfsd/filecache.h |  2 ++
>  fs/nfsd/vfs.c       |  5 +++--
>  fs/nfsd/vfs.h       |  2 +-
>  4 files changed, 49 insertions(+), 17 deletions(-)
> 
> diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c
> index a238b6725008a5c2988bd3da874d1f34ee778437..93798575b8075c63f95cd415b6d24df706ada0f6 100644
> --- a/fs/nfsd/filecache.c
> +++ b/fs/nfsd/filecache.c
> @@ -1086,7 +1086,7 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct net *net,
>  		     struct auth_domain *client,
>  		     struct svc_fh *fhp,
>  		     unsigned int may_flags, struct file *file,
> -		     struct nfsd_file **pnf, bool want_gc)
> +		     umode_t type, bool want_gc, struct nfsd_file **pnf)
>  {
>  	unsigned char need = may_flags & NFSD_FILE_MAY_MASK;
>  	struct nfsd_file *new, *nf;
> @@ -1097,13 +1097,13 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct net *net,
>  	int ret;
>  
>  retry:
> -	if (rqstp) {
> -		status = fh_verify(rqstp, fhp, S_IFREG,
> +	if (rqstp)
> +		status = fh_verify(rqstp, fhp, type,
>  				   may_flags|NFSD_MAY_OWNER_OVERRIDE);
> -	} else {
> -		status = fh_verify_local(net, cred, client, fhp, S_IFREG,
> +	else
> +		status = fh_verify_local(net, cred, client, fhp, type,
>  					 may_flags|NFSD_MAY_OWNER_OVERRIDE);
> -	}
> +
>  	if (status != nfs_ok)
>  		return status;
>  	inode = d_inode(fhp->fh_dentry);
> @@ -1176,15 +1176,18 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct net *net,
>  
>  open_file:
>  	trace_nfsd_file_alloc(nf);
> -	nf->nf_mark = nfsd_file_mark_find_or_create(inode);
> -	if (nf->nf_mark) {
> +
> +	if (type == S_IFREG)
> +		nf->nf_mark = nfsd_file_mark_find_or_create(inode);
> +
> +	if (type != S_IFREG || nf->nf_mark) {
>  		if (file) {
>  			get_file(file);
>  			nf->nf_file = file;
>  			status = nfs_ok;
>  			trace_nfsd_file_opened(nf, status);
>  		} else {
> -			ret = nfsd_open_verified(fhp, may_flags, &nf->nf_file);
> +			ret = nfsd_open_verified(fhp, type, may_flags, &nf->nf_file);
>  			if (ret == -EOPENSTALE && stale_retry) {
>  				stale_retry = false;
>  				nfsd_file_unhash(nf);
> @@ -1246,7 +1249,7 @@ nfsd_file_acquire_gc(struct svc_rqst *rqstp, struct svc_fh *fhp,
>  		     unsigned int may_flags, struct nfsd_file **pnf)
>  {
>  	return nfsd_file_do_acquire(rqstp, SVC_NET(rqstp), NULL, NULL,
> -				    fhp, may_flags, NULL, pnf, true);
> +				    fhp, may_flags, NULL, S_IFREG, true, pnf);
>  }
>  
>  /**
> @@ -1271,7 +1274,7 @@ nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
>  		  unsigned int may_flags, struct nfsd_file **pnf)
>  {
>  	return nfsd_file_do_acquire(rqstp, SVC_NET(rqstp), NULL, NULL,
> -				    fhp, may_flags, NULL, pnf, false);
> +				    fhp, may_flags, NULL, S_IFREG, false, pnf);
>  }
>  
>  /**
> @@ -1314,8 +1317,8 @@ nfsd_file_acquire_local(struct net *net, struct svc_cred *cred,
>  	const struct cred *save_cred = get_current_cred();
>  	__be32 beres;
>  
> -	beres = nfsd_file_do_acquire(NULL, net, cred, client,
> -				     fhp, may_flags, NULL, pnf, false);
> +	beres = nfsd_file_do_acquire(NULL, net, cred, client, fhp, may_flags,
> +				     NULL, S_IFREG, false, pnf);
>  	put_cred(revert_creds(save_cred));
>  	return beres;
>  }
> @@ -1344,7 +1347,33 @@ nfsd_file_acquire_opened(struct svc_rqst *rqstp, struct svc_fh *fhp,
>  			 struct nfsd_file **pnf)
>  {
>  	return nfsd_file_do_acquire(rqstp, SVC_NET(rqstp), NULL, NULL,
> -				    fhp, may_flags, file, pnf, false);
> +				    fhp, may_flags, file, S_IFREG, false, pnf);
> +}
> +
> +/**
> + * nfsd_file_acquire_dir - Get a struct nfsd_file with an open directory
> + * @rqstp: the RPC transaction being executed
> + * @fhp: the NFS filehandle of the file to be opened
> + * @pnf: OUT: new or found "struct nfsd_file" object
> + *
> + * The nfsd_file_object returned by this API is reference-counted
> + * but not garbage-collected. The object is unhashed after the
> + * final nfsd_file_put(). This opens directories only, and only
> + * in O_RDONLY mode.
> + *
> + * Return values:
> + *   %nfs_ok - @pnf points to an nfsd_file with its reference
> + *   count boosted.
> + *
> + * On error, an nfsstat value in network byte order is returned.
> + */
> +__be32
> +nfsd_file_acquire_dir(struct svc_rqst *rqstp, struct svc_fh *fhp,
> +		      struct nfsd_file **pnf)
> +{
> +	return nfsd_file_do_acquire(rqstp, SVC_NET(rqstp), NULL, NULL, fhp,
> +				    NFSD_MAY_READ|NFSD_MAY_64BIT_COOKIE,
> +				    NULL, S_IFDIR, false, pnf);
>  }
>  
>  /*
> diff --git a/fs/nfsd/filecache.h b/fs/nfsd/filecache.h
> index e3d6ca2b60308e5e91ba4bb32d935f54527d8bda..b383dbc5b9218d21a29b852572f80fab08de9fa9 100644
> --- a/fs/nfsd/filecache.h
> +++ b/fs/nfsd/filecache.h
> @@ -82,5 +82,7 @@ __be32 nfsd_file_acquire_opened(struct svc_rqst *rqstp, struct svc_fh *fhp,
>  __be32 nfsd_file_acquire_local(struct net *net, struct svc_cred *cred,
>  			       struct auth_domain *client, struct svc_fh *fhp,
>  			       unsigned int may_flags, struct nfsd_file **pnf);
> +__be32 nfsd_file_acquire_dir(struct svc_rqst *rqstp, struct svc_fh *fhp,
> +		  struct nfsd_file **pnf);
>  int nfsd_file_cache_stats_show(struct seq_file *m, void *v);
>  #endif /* _FS_NFSD_FILECACHE_H */
> diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
> index eeb138569eba5df6de361cf6ba29604722e14af9..12c33223b612664dbb3b18b591e97fc708165763 100644
> --- a/fs/nfsd/vfs.c
> +++ b/fs/nfsd/vfs.c
> @@ -959,15 +959,16 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
>  /**
>   * nfsd_open_verified - Open a regular file for the filecache
>   * @fhp: NFS filehandle of the file to open
> + * @type: S_IFMT inode type allowed (0 means any type is allowed)
>   * @may_flags: internal permission flags
>   * @filp: OUT: open "struct file *"
>   *
>   * Returns zero on success, or a negative errno value.
>   */
>  int
> -nfsd_open_verified(struct svc_fh *fhp, int may_flags, struct file **filp)
> +nfsd_open_verified(struct svc_fh *fhp, umode_t type, int may_flags, struct file **filp)
>  {
> -	return __nfsd_open(fhp, S_IFREG, may_flags, filp);
> +	return __nfsd_open(fhp, type, may_flags, filp);
>  }
>  
>  /*
> diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
> index fa46f8b5f132079e3a2c45e71ecf9cc43181f6b0..ded2900d423f80d33fb6c8b809bc5d9fc842ebfd 100644
> --- a/fs/nfsd/vfs.h
> +++ b/fs/nfsd/vfs.h
> @@ -114,7 +114,7 @@ __be32		nfsd_setxattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
>  int 		nfsd_open_break_lease(struct inode *, int);
>  __be32		nfsd_open(struct svc_rqst *, struct svc_fh *, umode_t,
>  				int, struct file **);
> -int		nfsd_open_verified(struct svc_fh *fhp, int may_flags,
> +int		nfsd_open_verified(struct svc_fh *fhp, umode_t type, int may_flags,
>  				struct file **filp);
>  __be32		nfsd_splice_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
>  				struct file *file, loff_t offset,
> 

Reviewed-by: Chuck Lever <chuck.lever@...cle.com>

These can probably go in via Christian's tree. I don't think there
are going to be conflicts between these and what's in nfsd-testing
now.

-- 
Chuck Lever

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ