mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
nfsd: Use lookup_one() rather than lookup_one_len()
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>
This commit is contained in:
parent
5741909697
commit
8ad9248471
7 changed files with 31 additions and 20 deletions
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue