Loading fs/nfsd/export.c +10 −15 Original line number Original line Diff line number Diff line Loading @@ -1299,24 +1299,19 @@ rqst_exp_find(struct svc_rqst *rqstp, int fsid_type, u32 *fsidv) } } struct svc_export * struct svc_export * rqst_exp_parent(struct svc_rqst *rqstp, struct vfsmount *mnt, rqst_exp_parent(struct svc_rqst *rqstp, struct path *path) struct dentry *dentry) { { struct svc_export *exp; struct dentry *saved = dget(path->dentry); struct path path = {.mnt = mnt, .dentry = dentry}; struct svc_export *exp = rqst_exp_get_by_name(rqstp, path); dget(dentry); exp = rqst_exp_get_by_name(rqstp, &path); while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(dentry)) { struct dentry *parent; parent = dget_parent(dentry); while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) { dput(dentry); struct dentry *parent = dget_parent(path->dentry); dentry = parent; dput(path->dentry); exp = rqst_exp_get_by_name(rqstp, &path); path->dentry = parent; exp = rqst_exp_get_by_name(rqstp, path); } } dput(dentry); dput(path->dentry); path->dentry = saved; return exp; return exp; } } Loading fs/nfsd/vfs.c +12 −11 Original line number Original line Diff line number Diff line Loading @@ -169,28 +169,29 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, /* checking mountpoint crossing is very different when stepping up */ /* checking mountpoint crossing is very different when stepping up */ struct svc_export *exp2 = NULL; struct svc_export *exp2 = NULL; struct dentry *dp; struct dentry *dp; struct vfsmount *mnt = mntget(exp->ex_path.mnt); struct path path = {.mnt = mntget(exp->ex_path.mnt), dentry = dget(dparent); .dentry = dget(dparent)}; while(dentry == mnt->mnt_root && follow_up(&mnt, &dentry)) while (path.dentry == path.mnt->mnt_root && follow_up(&path.mnt, &path.dentry)) ; ; dp = dget_parent(dentry); dp = dget_parent(path.dentry); dput(dentry); dput(path.dentry); dentry = dp; path.dentry = dp; exp2 = rqst_exp_parent(rqstp, mnt, dentry); exp2 = rqst_exp_parent(rqstp, &path); if (PTR_ERR(exp2) == -ENOENT) { if (PTR_ERR(exp2) == -ENOENT) { dput(dentry); dentry = dget(dparent); dentry = dget(dparent); } else if (IS_ERR(exp2)) { } else if (IS_ERR(exp2)) { host_err = PTR_ERR(exp2); host_err = PTR_ERR(exp2); dput(dentry); path_put(&path); mntput(mnt); goto out_nfserr; goto out_nfserr; } else { } else { dentry = dget(path.dentry); exp_put(exp); exp_put(exp); exp = exp2; exp = exp2; } } mntput(mnt); path_put(&path); } } } else { } else { fh_lock(fhp); fh_lock(fhp); Loading include/linux/nfsd/export.h +1 −2 Original line number Original line Diff line number Diff line Loading @@ -127,8 +127,7 @@ void exp_readunlock(void); struct svc_export * rqst_exp_get_by_name(struct svc_rqst *, struct svc_export * rqst_exp_get_by_name(struct svc_rqst *, struct path *); struct path *); struct svc_export * rqst_exp_parent(struct svc_rqst *, struct svc_export * rqst_exp_parent(struct svc_rqst *, struct vfsmount *mnt, struct path *); struct dentry *dentry); int exp_rootfh(struct auth_domain *, int exp_rootfh(struct auth_domain *, char *path, struct knfsd_fh *, int maxsize); char *path, struct knfsd_fh *, int maxsize); __be32 exp_pseudoroot(struct svc_rqst *, struct svc_fh *); __be32 exp_pseudoroot(struct svc_rqst *, struct svc_fh *); Loading Loading
fs/nfsd/export.c +10 −15 Original line number Original line Diff line number Diff line Loading @@ -1299,24 +1299,19 @@ rqst_exp_find(struct svc_rqst *rqstp, int fsid_type, u32 *fsidv) } } struct svc_export * struct svc_export * rqst_exp_parent(struct svc_rqst *rqstp, struct vfsmount *mnt, rqst_exp_parent(struct svc_rqst *rqstp, struct path *path) struct dentry *dentry) { { struct svc_export *exp; struct dentry *saved = dget(path->dentry); struct path path = {.mnt = mnt, .dentry = dentry}; struct svc_export *exp = rqst_exp_get_by_name(rqstp, path); dget(dentry); exp = rqst_exp_get_by_name(rqstp, &path); while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(dentry)) { struct dentry *parent; parent = dget_parent(dentry); while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) { dput(dentry); struct dentry *parent = dget_parent(path->dentry); dentry = parent; dput(path->dentry); exp = rqst_exp_get_by_name(rqstp, &path); path->dentry = parent; exp = rqst_exp_get_by_name(rqstp, path); } } dput(dentry); dput(path->dentry); path->dentry = saved; return exp; return exp; } } Loading
fs/nfsd/vfs.c +12 −11 Original line number Original line Diff line number Diff line Loading @@ -169,28 +169,29 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, /* checking mountpoint crossing is very different when stepping up */ /* checking mountpoint crossing is very different when stepping up */ struct svc_export *exp2 = NULL; struct svc_export *exp2 = NULL; struct dentry *dp; struct dentry *dp; struct vfsmount *mnt = mntget(exp->ex_path.mnt); struct path path = {.mnt = mntget(exp->ex_path.mnt), dentry = dget(dparent); .dentry = dget(dparent)}; while(dentry == mnt->mnt_root && follow_up(&mnt, &dentry)) while (path.dentry == path.mnt->mnt_root && follow_up(&path.mnt, &path.dentry)) ; ; dp = dget_parent(dentry); dp = dget_parent(path.dentry); dput(dentry); dput(path.dentry); dentry = dp; path.dentry = dp; exp2 = rqst_exp_parent(rqstp, mnt, dentry); exp2 = rqst_exp_parent(rqstp, &path); if (PTR_ERR(exp2) == -ENOENT) { if (PTR_ERR(exp2) == -ENOENT) { dput(dentry); dentry = dget(dparent); dentry = dget(dparent); } else if (IS_ERR(exp2)) { } else if (IS_ERR(exp2)) { host_err = PTR_ERR(exp2); host_err = PTR_ERR(exp2); dput(dentry); path_put(&path); mntput(mnt); goto out_nfserr; goto out_nfserr; } else { } else { dentry = dget(path.dentry); exp_put(exp); exp_put(exp); exp = exp2; exp = exp2; } } mntput(mnt); path_put(&path); } } } else { } else { fh_lock(fhp); fh_lock(fhp); Loading
include/linux/nfsd/export.h +1 −2 Original line number Original line Diff line number Diff line Loading @@ -127,8 +127,7 @@ void exp_readunlock(void); struct svc_export * rqst_exp_get_by_name(struct svc_rqst *, struct svc_export * rqst_exp_get_by_name(struct svc_rqst *, struct path *); struct path *); struct svc_export * rqst_exp_parent(struct svc_rqst *, struct svc_export * rqst_exp_parent(struct svc_rqst *, struct vfsmount *mnt, struct path *); struct dentry *dentry); int exp_rootfh(struct auth_domain *, int exp_rootfh(struct auth_domain *, char *path, struct knfsd_fh *, int maxsize); char *path, struct knfsd_fh *, int maxsize); __be32 exp_pseudoroot(struct svc_rqst *, struct svc_fh *); __be32 exp_pseudoroot(struct svc_rqst *, struct svc_fh *); Loading