fh_verify only allows you to filter on a single type of inode, so have nfsd4_delegreturn not filter by type. Once fh_verify returns, do the appropriate check of the type and return an error if it's not a regular file or directory. Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx> --- fs/nfsd/nfs4state.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 17d09d72632b..c52e807f9672 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -7425,12 +7425,24 @@ nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfs4_delegation *dp; stateid_t *stateid = &dr->dr_stateid; struct nfs4_stid *s; + umode_t mode; __be32 status; struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); - if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) + if ((status = fh_verify(rqstp, &cstate->current_fh, 0, 0))) return status; + mode = d_inode(cstate->current_fh.fh_dentry)->i_mode & S_IFMT; + switch(mode) { + case S_IFREG: + case S_IFDIR: + break; + case S_IFLNK: + return nfserr_symlink; + default: + return nfserr_inval; + } + status = nfsd4_lookup_stateid(cstate, stateid, SC_TYPE_DELEG, 0, &s, nn); if (status) goto out; -- 2.44.0