[PATCH v5 16/18] nfsd: move v0 checking out of nfsd_check_obj_isreg()
NeilBrown <[email protected]> Fri, 17 Jul 2026 19:28:04 +1000
| Newsgroups | gmane.linux.nfs |
|---|---|
| Message-ID | <[email protected]> |
From: NeilBrown <neil-+NVA1uvv1dVBDLzU/[email protected]> A future patch will use nfsd_check_obj_isreg() in a context where the protocol version is not easily available. So move the version check out and put it at the end of do_open_lookup(). Also change to return errno error code and use nfserrno() to convert to nfs error codes. Use -ELOOP for nfserr_symlink, which is an error indication a problem with symlinks. -EFTYPE is a good match for nfserr_wrong_type. Signed-off-by: NeilBrown <neil-+NVA1uvv1dVBDLzU/[email protected]> --- fs/nfsd/nfs4proc.c | 29 ++++++++++++----------------- fs/nfsd/vfs.c | 4 +++- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index ec925f60b2ae..760354818189 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -169,23 +169,17 @@ do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs return fh_verify(rqstp, current_fh, S_IFREG, accmode); } -static __be32 nfsd_check_obj_isreg(struct dentry *child, u32 minor_version) +static __be32 nfsd_check_obj_isreg(struct dentry *child) { umode_t mode = d_inode(child)->i_mode; if (S_ISREG(mode)) - return nfs_ok; + return 0; if (S_ISDIR(mode)) - return nfserr_isdir; + return -EISDIR; if (S_ISLNK(mode)) - return nfserr_symlink; - - /* RFC 7530 - 16.16.6 */ - if (minor_version == 0) - return nfserr_symlink; - else - return nfserr_wrong_type; - + return -ELOOP; + return -EFTYPE; } static void nfsd4_set_open_owner_reply_cache(struct nfsd4_compound_state *cstate, struct nfsd4_open *open, struct svc_fh *resfh) @@ -213,8 +207,6 @@ static __be32 nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, struct svc_fh *resfhp, struct nfsd4_open *open) { - struct nfsd4_compoundres *resp = rqstp->rq_resp; - struct nfsd4_compound_state *cstate = &resp->cstate; struct iattr *iap = &open->op_iattr; struct nfsd_attrs attrs = { .na_iattr = iap, @@ -354,8 +346,8 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, * op_filp and consequently a valid ->f_path.dentry. */ - status = nfsd_check_obj_isreg(child, cstate->minorversion); - if (status == nfs_ok) { + status = nfserrno(nfsd_check_obj_isreg(child)); + if (!status) { open->op_filp = dentry_open(&path, oflags, current_cred()); if (IS_ERR(open->op_filp)) { @@ -534,8 +526,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru } if (status) goto out; - status = nfsd_check_obj_isreg((*resfh)->fh_dentry, - cstate->minorversion); + status = nfserrno(nfsd_check_obj_isreg((*resfh)->fh_dentry)); if (status) goto out; @@ -547,6 +538,10 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru status = do_open_permission(rqstp, *resfh, open, accmode); set_change_info(&open->op_cinfo, current_fh); out: + if (status == nfserr_wrong_type && cstate->minorversion == 0) + /* RFC 7530 - 16.16.6 */ + return nfserr_symlink; + return status; } diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 7898af35874b..b346f683143e 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -63,7 +63,7 @@ u64 nfsd_io_cache_write __read_mostly = NFSD_IO_BUFFERED; * it's an error we don't expect, log it once and return nfserr_io. */ __be32 -nfserrno (int errno) +nfserrno(int errno) { static struct { __be32 nfserr; @@ -107,6 +107,8 @@ nfserrno (int errno) { nfserr_perm, -ENOKEY }, { nfserr_no_grace, -ENOGRACE}, { nfserr_io, -EBADMSG }, + { nfserr_symlink, -ELOOP }, + { nfserr_wrong_type, -EFTYPE }, }; int i; -- 2.50.0.107.gf914562f5916.dirty