Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03550fac authored by J. Bruce Fields's avatar J. Bruce Fields
Browse files

nfsd: move most of fh_verify to separate function



Move the code that actually parses the filehandle and looks up the
dentry and export to a separate function.  This simplifies the reference
counting a little and moves fh_verify() a little closer to the kernel
ideal of small, minimally-indentended functions.  Clean up a few other
minor style sins along the way.

Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
Cc: Neil Brown <neilb@suse.de>
parent c3bb257d
Loading
Loading
Loading
Loading
+123 −105
Original line number Diff line number Diff line
@@ -113,28 +113,19 @@ static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp,
}

/*
 * Perform sanity checks on the dentry in a client's file handle.
 *
 * Note that the file handle dentry may need to be freed even after
 * an error return.
 *
 * This is only called at the start of an nfsproc call, so fhp points to
 * a svc_fh which is all 0 except for the over-the-wire file handle.
 * Use the given filehandle to look up the corresponding export and
 * dentry.  On success, the results are used to set fh_export and
 * fh_dentry.
 */
__be32
fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp)
{
	struct knfsd_fh	*fh = &fhp->fh_handle;
	struct svc_export *exp = NULL;
	struct dentry	*dentry;
	__be32		error = 0;

	dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp));

	if (!fhp->fh_dentry) {
	struct fid *fid = NULL, sfid;
	struct svc_export *exp;
	struct dentry *dentry;
	int fileid_type;
	int data_left = fh->fh_size/4;
	__be32 error;

	error = nfserr_stale;
	if (rqstp->rq_vers > 2)
@@ -144,13 +135,14 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)

	if (fh->fh_version == 1) {
		int len;
			if (--data_left<0) goto out;
			switch (fh->fh_auth_type) {
			case 0: break;
			default: goto out;
			}

		if (--data_left < 0)
			return error;
		if (fh->fh_auth_type != 0)
			return error;
		len = key_len(fh->fh_fsid_type) / 4;
			if (len == 0) goto out;
		if (len == 0)
			return error;
		if  (fh->fh_fsid_type == FSID_MAJOR_MINOR) {
			/* deprecated, convert to type 3 */
			len = key_len(FSID_ENCODE_DEV)/4;
@@ -158,16 +150,18 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
			fh->fh_fsid[0] = new_encode_dev(MKDEV(ntohl(fh->fh_fsid[0]), ntohl(fh->fh_fsid[1])));
			fh->fh_fsid[1] = fh->fh_fsid[2];
		}
			if ((data_left -= len)<0) goto out;
			exp = rqst_exp_find(rqstp, fh->fh_fsid_type,
					    fh->fh_auth);
		data_left -= len;
		if (data_left < 0)
			return error;
		exp = rqst_exp_find(rqstp, fh->fh_fsid_type, fh->fh_auth);
		fid = (struct fid *)(fh->fh_auth + len);
	} else {
		__u32 tfh[2];
		dev_t xdev;
		ino_t xino;

		if (fh->fh_size != NFS_FHSIZE)
				goto out;
			return error;
		/* assume old filehandle format */
		xdev = old_decode_dev(fh->ofh_xdev);
		xino = u32_to_ino_t(fh->ofh_xino);
@@ -177,12 +171,10 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)

	error = nfserr_stale;
	if (PTR_ERR(exp) == -ENOENT)
			goto out;
		return error;

		if (IS_ERR(exp)) {
			error = nfserrno(PTR_ERR(exp));
			goto out;
		}
	if (IS_ERR(exp))
		return nfserrno(PTR_ERR(exp));

	error = nfsd_setuser_and_check_port(rqstp, exp);
	if (error)
@@ -232,7 +224,36 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
	fhp->fh_dentry = dentry;
	fhp->fh_export = exp;
	nfsd_nr_verified++;
		cache_get(&exp->h);
	return 0;
out:
	exp_put(exp);
	return error;
}

/*
 * Perform sanity checks on the dentry in a client's file handle.
 *
 * Note that the file handle dentry may need to be freed even after
 * an error return.
 *
 * This is only called at the start of an nfsproc call, so fhp points to
 * a svc_fh which is all 0 except for the over-the-wire file handle.
 */
__be32
fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
{
	struct svc_export *exp;
	struct dentry	*dentry;
	__be32		error;

	dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp));

	if (!fhp->fh_dentry) {
		error = nfsd_set_fh_dentry(rqstp, fhp);
		if (error)
			goto out;
		dentry = fhp->fh_dentry;
		exp = fhp->fh_export;
	} else {
		/*
		 * just rechecking permissions
@@ -242,7 +263,6 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
		dprintk("nfsd: fh_verify - just checking\n");
		dentry = fhp->fh_dentry;
		exp = fhp->fh_export;
		cache_get(&exp->h);
		/*
		 * Set user creds for this exportpoint; necessary even
		 * in the "just checking" case because this may be a
@@ -281,8 +301,6 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
			access, ntohl(error));
	}
out:
	if (exp && !IS_ERR(exp))
		exp_put(exp);
	if (error == nfserr_stale)
		nfsdstats.fh_stale++;
	return error;