]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
nfsd: Use lookup_one() rather than lookup_one_len()
authorNeilBrown <neil@brown.name>
Wed, 19 Mar 2025 03:01:33 +0000 (14:01 +1100)
committerChristian Brauner <brauner@kernel.org>
Mon, 7 Apr 2025 07:25:32 +0000 (09:25 +0200)
nfsd uses some VFS interfaces (such as vfs_mkdir) which take an explicit
mnt_idmap, and it passes &nop_mnt_idmap as nfsd doesn't yet support
idmapped mounts.

It also uses the lookup_one_len() family of functions which implicitly
use &nop_mnt_idmap.  This mixture of implicit and explicit could be
confusing.  When we eventually update nfsd to support idmap mounts it
would be best if all places which need an idmap determined from the
mount point were similar and easily found.

So this patch changes nfsd to use lookup_one(), lookup_one_unlocked(),
and lookup_one_positive_unlocked(), passing &nop_mnt_idmap.

This has the benefit of removing some uses of the lookup_one_len
functions where permission checking is actually needed.  Many callers
don't care about permission checking and using these function only where
permission checking is needed is a valuable simplification.

This change requires passing the name in a qstr.  Currently this is a
little clumsy, but if nfsd is changed to use qstr more broadly it will
result in a net improvement.

Signed-off-by: NeilBrown <neil@brown.name>
Link: https://lore.kernel.org/r/20250319031545.2999807-3-neil@brown.name
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/nfsd/nfs3proc.c
fs/nfsd/nfs3xdr.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4recover.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfsproc.c
fs/nfsd/vfs.c

index 372bdcf5e07a5c835da240ecebb02e3576eb2ca6..ac1731eb34ab7085e4ba8a23e7f9e6e70cff9dac 100644 (file)
@@ -284,7 +284,9 @@ nfsd3_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp,
 
        inode_lock_nested(inode, I_MUTEX_PARENT);
 
-       child = lookup_one_len(argp->name, parent, argp->len);
+       child = lookup_one(&nop_mnt_idmap,
+                          &QSTR_LEN(argp->name, argp->len),
+                          parent);
        if (IS_ERR(child)) {
                status = nfserrno(PTR_ERR(child));
                goto out;
index a7a07470c1f846408e1b31d97bc7a55fa471bb5a..ef4971d71ac4bfee5171537eda80dec6e367060d 100644 (file)
@@ -1001,7 +1001,9 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
                } else
                        dchild = dget(dparent);
        } else
-               dchild = lookup_positive_unlocked(name, dparent, namlen);
+               dchild = lookup_one_positive_unlocked(&nop_mnt_idmap,
+                                                     &QSTR_LEN(name, namlen),
+                                                     dparent);
        if (IS_ERR(dchild))
                return rv;
        if (d_mountpoint(dchild))
index b397246dae7b7e8c2a0ba436bb3813213cfe4fa2..fd560dcf6059d92068fbf866090240a9b33d654a 100644 (file)
@@ -266,7 +266,9 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp,
 
        inode_lock_nested(inode, I_MUTEX_PARENT);
 
-       child = lookup_one_len(open->op_fname, parent, open->op_fnamelen);
+       child = lookup_one(&nop_mnt_idmap,
+                          &QSTR_LEN(open->op_fname, open->op_fnamelen),
+                          parent);
        if (IS_ERR(child)) {
                status = nfserrno(PTR_ERR(child));
                goto out;
index c1d9bd07285f4be852c6d8b61f1c8516b8441515..acde3edab73366bbb1e3dc2de1ad71edb2511801 100644 (file)
@@ -218,7 +218,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
        /* lock the parent */
        inode_lock(d_inode(dir));
 
-       dentry = lookup_one_len(dname, dir, HEXDIR_LEN-1);
+       dentry = lookup_one(&nop_mnt_idmap, &QSTR(dname), dir);
        if (IS_ERR(dentry)) {
                status = PTR_ERR(dentry);
                goto out_unlock;
@@ -316,7 +316,8 @@ nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
        list_for_each_entry_safe(entry, tmp, &ctx.names, list) {
                if (!status) {
                        struct dentry *dentry;
-                       dentry = lookup_one_len(entry->name, dir, HEXDIR_LEN-1);
+                       dentry = lookup_one(&nop_mnt_idmap,
+                                           &QSTR(entry->name), dir);
                        if (IS_ERR(dentry)) {
                                status = PTR_ERR(dentry);
                                break;
@@ -339,16 +340,16 @@ nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
 }
 
 static int
-nfsd4_unlink_clid_dir(char *name, int namlen, struct nfsd_net *nn)
+nfsd4_unlink_clid_dir(char *name, struct nfsd_net *nn)
 {
        struct dentry *dir, *dentry;
        int status;
 
-       dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);
+       dprintk("NFSD: nfsd4_unlink_clid_dir. name %s\n", name);
 
        dir = nn->rec_file->f_path.dentry;
        inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
-       dentry = lookup_one_len(name, dir, namlen);
+       dentry = lookup_one(&nop_mnt_idmap, &QSTR(name), dir);
        if (IS_ERR(dentry)) {
                status = PTR_ERR(dentry);
                goto out_unlock;
@@ -408,7 +409,7 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
        if (status < 0)
                goto out_drop_write;
 
-       status = nfsd4_unlink_clid_dir(dname, HEXDIR_LEN-1, nn);
+       status = nfsd4_unlink_clid_dir(dname, nn);
        nfs4_reset_creds(original_cred);
        if (status == 0) {
                vfs_fsync(nn->rec_file, 0);
index e67420729ecd609c46c3f5d411dea73aa0047ffc..fe876395985aac664209ed50e455a368a2d6320d 100644 (file)
@@ -3812,7 +3812,9 @@ nfsd4_encode_entry4_fattr(struct nfsd4_readdir *cd, const char *name,
        __be32 nfserr;
        int ignore_crossmnt = 0;
 
-       dentry = lookup_positive_unlocked(name, cd->rd_fhp->fh_dentry, namlen);
+       dentry = lookup_one_positive_unlocked(&nop_mnt_idmap,
+                                             &QSTR_LEN(name, namlen),
+                                             cd->rd_fhp->fh_dentry);
        if (IS_ERR(dentry))
                return nfserrno(PTR_ERR(dentry));
 
index 6dda081eb24c00b834ab0965c3a35a12115bceb7..6370ac0a85fd5adf0c91990f6b698cfc3dff8390 100644 (file)
@@ -312,7 +312,8 @@ nfsd_proc_create(struct svc_rqst *rqstp)
        }
 
        inode_lock_nested(dirfhp->fh_dentry->d_inode, I_MUTEX_PARENT);
-       dchild = lookup_one_len(argp->name, dirfhp->fh_dentry, argp->len);
+       dchild = lookup_one(&nop_mnt_idmap, &QSTR_LEN(argp->name, argp->len),
+                           dirfhp->fh_dentry);
        if (IS_ERR(dchild)) {
                resp->status = nfserrno(PTR_ERR(dchild));
                goto out_unlock;
@@ -331,7 +332,7 @@ nfsd_proc_create(struct svc_rqst *rqstp)
                 */
                resp->status = nfserr_acces;
                if (!newfhp->fh_dentry) {
-                       printk(KERN_WARNING 
+                       printk(KERN_WARNING
                                "nfsd_proc_create: file handle not verified\n");
                        goto out_unlock;
                }
index 9abdc4b758138be025ae1d88eb5f91f4f00b114a..160a839af4050f1756f7e4c2d5f6f5eda8da8d14 100644 (file)
@@ -264,7 +264,8 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp,
                                goto out_nfserr;
                }
        } else {
-               dentry = lookup_one_len_unlocked(name, dparent, len);
+               dentry = lookup_one_unlocked(&nop_mnt_idmap,
+                                            &QSTR_LEN(name, len), dparent);
                host_err = PTR_ERR(dentry);
                if (IS_ERR(dentry))
                        goto out_nfserr;
@@ -922,7 +923,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
         * directories, but we never have and it doesn't seem to have
         * caused anyone a problem.  If we were to change this, note
         * also that our filldir callbacks would need a variant of
-        * lookup_one_len that doesn't check permissions.
+        * lookup_one_positive_unlocked() that doesn't check permissions.
         */
        if (type == S_IFREG)
                may_flags |= NFSD_MAY_OWNER_OVERRIDE;
@@ -1554,7 +1555,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
                return nfserrno(host_err);
 
        inode_lock_nested(dentry->d_inode, I_MUTEX_PARENT);
-       dchild = lookup_one_len(fname, dentry, flen);
+       dchild = lookup_one(&nop_mnt_idmap, &QSTR_LEN(fname, flen), dentry);
        host_err = PTR_ERR(dchild);
        if (IS_ERR(dchild)) {
                err = nfserrno(host_err);
@@ -1659,7 +1660,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
 
        dentry = fhp->fh_dentry;
        inode_lock_nested(dentry->d_inode, I_MUTEX_PARENT);
-       dnew = lookup_one_len(fname, dentry, flen);
+       dnew = lookup_one(&nop_mnt_idmap, &QSTR_LEN(fname, flen), dentry);
        if (IS_ERR(dnew)) {
                err = nfserrno(PTR_ERR(dnew));
                inode_unlock(dentry->d_inode);
@@ -1734,7 +1735,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
        dirp = d_inode(ddir);
        inode_lock_nested(dirp, I_MUTEX_PARENT);
 
-       dnew = lookup_one_len(name, ddir, len);
+       dnew = lookup_one(&nop_mnt_idmap, &QSTR_LEN(name, len), ddir);
        if (IS_ERR(dnew)) {
                host_err = PTR_ERR(dnew);
                goto out_unlock;
@@ -1867,7 +1868,7 @@ retry:
        if (err != nfs_ok)
                goto out_unlock;
 
-       odentry = lookup_one_len(fname, fdentry, flen);
+       odentry = lookup_one(&nop_mnt_idmap, &QSTR_LEN(fname, flen), fdentry);
        host_err = PTR_ERR(odentry);
        if (IS_ERR(odentry))
                goto out_nfserr;
@@ -1880,7 +1881,7 @@ retry:
                goto out_dput_old;
        type = d_inode(odentry)->i_mode & S_IFMT;
 
-       ndentry = lookup_one_len(tname, tdentry, tlen);
+       ndentry = lookup_one(&nop_mnt_idmap, &QSTR_LEN(tname, tlen), tdentry);
        host_err = PTR_ERR(ndentry);
        if (IS_ERR(ndentry))
                goto out_dput_old;
@@ -1998,7 +1999,7 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
        dirp = d_inode(dentry);
        inode_lock_nested(dirp, I_MUTEX_PARENT);
 
-       rdentry = lookup_one_len(fname, dentry, flen);
+       rdentry = lookup_one(&nop_mnt_idmap, &QSTR_LEN(fname, flen), dentry);
        host_err = PTR_ERR(rdentry);
        if (IS_ERR(rdentry))
                goto out_unlock;