Commit 289ede45 authored by J. Bruce Fields's avatar J. Bruce Fields
Browse files

nfsd: minor nfsd_lookup cleanup



Break out some of nfsd_lookup_dentry into helper functions.

Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
parent fed83811
Loading
Loading
Loading
Loading
+36 −24
Original line number Diff line number Diff line
@@ -141,6 +141,40 @@ out:
	return err;
}

static void follow_to_parent(struct path *path)
{
	struct dentry *dp;

	while (path->dentry == path->mnt->mnt_root && follow_up(path))
		;
	dp = dget_parent(path->dentry);
	dput(path->dentry);
	path->dentry = dp;
}

static int nfsd_lookup_parent(struct svc_rqst *rqstp, struct dentry *dparent, struct svc_export **exp, struct dentry **dentryp)
{
	struct svc_export *exp2;
	struct path path = {.mnt = mntget((*exp)->ex_path.mnt),
			    .dentry = dget(dparent)};

	follow_to_parent(&path);

	exp2 = rqst_exp_parent(rqstp, &path);
	if (PTR_ERR(exp2) == -ENOENT) {
		*dentryp = dget(dparent);
	} else if (IS_ERR(exp2)) {
		path_put(&path);
		return PTR_ERR(exp2);
	} else {
		*dentryp = dget(path.dentry);
		exp_put(*exp);
		*exp = exp2;
	}
	path_put(&path);
	return 0;
}

__be32
nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp,
		   const char *name, unsigned int len,
@@ -173,31 +207,9 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp,
			dentry = dget(dparent); /* .. == . just like at / */
		else {
			/* checking mountpoint crossing is very different when stepping up */
			struct svc_export *exp2 = NULL;
			struct dentry *dp;
			struct path path = {.mnt = mntget(exp->ex_path.mnt),
					    .dentry = dget(dparent)};

			while (path.dentry == path.mnt->mnt_root &&
			       follow_up(&path))
				;
			dp = dget_parent(path.dentry);
			dput(path.dentry);
			path.dentry = dp;

			exp2 = rqst_exp_parent(rqstp, &path);
			if (PTR_ERR(exp2) == -ENOENT) {
				dentry = dget(dparent);
			} else if (IS_ERR(exp2)) {
				host_err = PTR_ERR(exp2);
				path_put(&path);
			host_err = nfsd_lookup_parent(rqstp, dparent, &exp, &dentry);
			if (host_err)
				goto out_nfserr;
			} else {
				dentry = dget(path.dentry);
				exp_put(exp);
				exp = exp2;
			}
			path_put(&path);
		}
	} else {
		fh_lock(fhp);