linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] NFSD support for FedFS junctions
@ 2011-08-29 18:48 Chuck Lever
  2011-08-29 18:48 ` [PATCH 1/3] NFSD: Cleanup for nfsd4_path() Chuck Lever
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Chuck Lever @ 2011-08-29 18:48 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs

Hi Bruce-

Sometime soon we are going to have working and easy-to-install FedFS
user space components.  These kernel patches are going to be needed
to make server-side FedFS support work.

Would you consider these for 3.2?

---

Trond Myklebust (3):
      NFSD: Add a cache for fs_locations information
      NFSD: Remove the ex_pathname field from struct svc_export
      NFSD: Cleanup for nfsd4_path()


 fs/nfsd/export.c            |   15 +-----
 fs/nfsd/nfs4xdr.c           |  106 ++++++++++++++++++++++++++++++++-----------
 fs/nfsd/nfsd.h              |    7 +++
 fs/nfsd/vfs.c               |   15 ++++++
 include/linux/nfsd/export.h |    2 -
 5 files changed, 103 insertions(+), 42 deletions(-)

-- 
Chuck Lever

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] NFSD: Cleanup for nfsd4_path()
  2011-08-29 18:48 [PATCH 0/3] NFSD support for FedFS junctions Chuck Lever
@ 2011-08-29 18:48 ` Chuck Lever
  2011-08-29 18:49 ` [PATCH 2/3] NFSD: Remove the ex_pathname field from struct svc_export Chuck Lever
  2011-08-29 18:55 ` [PATCH 0/3] NFSD support for FedFS junctions Chuck Lever
  2 siblings, 0 replies; 4+ messages in thread
From: Chuck Lever @ 2011-08-29 18:48 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs

From: Trond Myklebust <Trond.Myklebust@netapp.com>

The current code is sort of hackish in that it assumes a referral is always
matched to an export. When we add support for junctions that may not be the
case.
We can replace nfsd4_path() with a function that encodes the components
directly from the dentries. Since nfsd4_path is currently the only user of
the 'ex_pathname' field in struct svc_export, this has the added benefit
of allowing us to get rid of that.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---

 fs/nfsd/export.c            |    4 +-
 fs/nfsd/nfs4xdr.c           |  106 ++++++++++++++++++++++++++++++++-----------
 include/linux/nfsd/export.h |    1 
 3 files changed, 81 insertions(+), 30 deletions(-)

diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index f4cc1e2..d9a6611 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -1010,7 +1010,7 @@ rqst_exp_parent(struct svc_rqst *rqstp, struct path *path)
 	return exp;
 }
 
-static struct svc_export *find_fsidzero_export(struct svc_rqst *rqstp)
+struct svc_export *rqst_find_fsidzero_export(struct svc_rqst *rqstp)
 {
 	u32 fsidv[2];
 
@@ -1030,7 +1030,7 @@ exp_pseudoroot(struct svc_rqst *rqstp, struct svc_fh *fhp)
 	struct svc_export *exp;
 	__be32 rv;
 
-	exp = find_fsidzero_export(rqstp);
+	exp = rqst_find_fsidzero_export(rqstp);
 	if (IS_ERR(exp))
 		return nfserrno(PTR_ERR(exp));
 	rv = fh_compose(fhp, exp, exp->ex_path.dentry, NULL);
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index c8bf405..f7b068e 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1697,36 +1697,89 @@ static __be32 nfsd4_encode_fs_location4(struct nfsd4_fs_location *location,
 }
 
 /*
- * Return the path to an export point in the pseudo filesystem namespace
- * Returned string is safe to use as long as the caller holds a reference
- * to @exp.
+ * Encode a path in RFC3530 'pathname4' format
  */
-static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp, __be32 *stat)
+static __be32 nfsd4_encode_path(const struct path *root,
+		const struct path *path, __be32 **pp, int *buflen)
 {
-	struct svc_fh tmp_fh;
-	char *path = NULL, *rootpath;
-	size_t rootlen;
+	struct path cur = {
+		.mnt = path->mnt,
+		.dentry = path->dentry,
+	};
+	__be32 *p = *pp;
+	struct dentry **components = NULL;
+	unsigned int ncomponents = 0;
+	__be32 err = nfserr_resource;
 
-	fh_init(&tmp_fh, NFS4_FHSIZE);
-	*stat = exp_pseudoroot(rqstp, &tmp_fh);
-	if (*stat)
-		return NULL;
-	rootpath = tmp_fh.fh_export->ex_pathname;
+	dprintk("nfsd4_encode_components(");
 
-	path = exp->ex_pathname;
+	path_get(&cur);
+	/* First walk the path up to the nfsd root, and store the
+	 * dentries/path components in an array.
+	 */
+	for (;;) {
+		if (cur.dentry == root->dentry && cur.mnt == root->mnt)
+			break;
+		if (cur.dentry == cur.mnt->mnt_root) {
+			if (follow_up(&cur))
+				continue;
+			goto out_free;
+		}
+		if ((ncomponents & 15) == 0) {
+			struct dentry **new;
+			new = krealloc(components,
+					sizeof(*new) * (ncomponents + 16),
+					GFP_KERNEL);
+			if (!new)
+				goto out_free;
+			components = new;
+		}
+		components[ncomponents++] = cur.dentry;
+		cur.dentry = dget_parent(cur.dentry);
+	}
 
-	rootlen = strlen(rootpath);
-	if (strncmp(path, rootpath, rootlen)) {
-		dprintk("nfsd: fs_locations failed;"
-			"%s is not contained in %s\n", path, rootpath);
-		*stat = nfserr_notsupp;
-		path = NULL;
-		goto out;
+	*buflen -= 4;
+	if (*buflen < 0)
+		goto out_free;
+	WRITE32(ncomponents);
+
+	while (ncomponents) {
+		struct dentry *dentry = components[ncomponents - 1];
+		unsigned int len = dentry->d_name.len;
+
+		*buflen -= 4 + (XDR_QUADLEN(len) << 2);
+		if (*buflen < 0)
+			goto out_free;
+		WRITE32(len);
+		WRITEMEM(dentry->d_name.name, len);
+		dprintk("/%s", dentry->d_name.name);
+		dput(dentry);
+		ncomponents--;
 	}
-	path += rootlen;
-out:
-	fh_put(&tmp_fh);
-	return path;
+
+	*pp = p;
+	err = 0;
+out_free:
+	dprintk(")\n");
+	while (ncomponents)
+		dput(components[--ncomponents]);
+	kfree(components);
+	path_put(&cur);
+	return err;
+}
+
+static __be32 nfsd4_encode_fsloc_fsroot(struct svc_rqst *rqstp,
+		const struct path *path, __be32 **pp, int *buflen)
+{
+	struct svc_export *exp_ps;
+	__be32 res;
+
+	exp_ps = rqst_find_fsidzero_export(rqstp);
+	if (IS_ERR(exp_ps))
+		return nfserrno(PTR_ERR(exp_ps));
+	res = nfsd4_encode_path(&exp_ps->ex_path, path, pp, buflen);
+	exp_put(exp_ps);
+	return res;
 }
 
 /*
@@ -1740,11 +1793,8 @@ static __be32 nfsd4_encode_fs_locations(struct svc_rqst *rqstp,
 	int i;
 	__be32 *p = *pp;
 	struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs;
-	char *root = nfsd4_path(rqstp, exp, &status);
 
-	if (status)
-		return status;
-	status = nfsd4_encode_components('/', root, &p, buflen);
+	status = nfsd4_encode_fsloc_fsroot(rqstp, &exp->ex_path, &p, buflen);
 	if (status)
 		return status;
 	if ((*buflen -= 4) < 0)
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
index 8a31a20..7ba3fd4 100644
--- a/include/linux/nfsd/export.h
+++ b/include/linux/nfsd/export.h
@@ -137,6 +137,7 @@ struct svc_export *	rqst_exp_get_by_name(struct svc_rqst *,
 					     struct path *);
 struct svc_export *	rqst_exp_parent(struct svc_rqst *,
 					struct path *);
+struct svc_export *	rqst_find_fsidzero_export(struct svc_rqst *);
 int			exp_rootfh(struct auth_domain *, 
 					char *path, struct knfsd_fh *, int maxsize);
 __be32			exp_pseudoroot(struct svc_rqst *, struct svc_fh *);


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] NFSD: Remove the ex_pathname field from struct svc_export
  2011-08-29 18:48 [PATCH 0/3] NFSD support for FedFS junctions Chuck Lever
  2011-08-29 18:48 ` [PATCH 1/3] NFSD: Cleanup for nfsd4_path() Chuck Lever
@ 2011-08-29 18:49 ` Chuck Lever
  2011-08-29 18:55 ` [PATCH 0/3] NFSD support for FedFS junctions Chuck Lever
  2 siblings, 0 replies; 4+ messages in thread
From: Chuck Lever @ 2011-08-29 18:49 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs

From: Trond Myklebust <Trond.Myklebust@netapp.com>

There are no more users...

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---

 fs/nfsd/export.c            |   11 -----------
 include/linux/nfsd/export.h |    1 -
 2 files changed, 0 insertions(+), 12 deletions(-)

diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index d9a6611..bf985f7 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -318,7 +318,6 @@ static void svc_export_put(struct kref *ref)
 	struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
 	path_put(&exp->ex_path);
 	auth_domain_put(exp->ex_client);
-	kfree(exp->ex_pathname);
 	nfsd4_fslocs_free(&exp->ex_fslocs);
 	kfree(exp);
 }
@@ -528,11 +527,6 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
 
 	exp.ex_client = dom;
 
-	err = -ENOMEM;
-	exp.ex_pathname = kstrdup(buf, GFP_KERNEL);
-	if (!exp.ex_pathname)
-		goto out2;
-
 	/* expiry */
 	err = -EINVAL;
 	exp.h.expiry_time = get_expiry(&mesg);
@@ -613,8 +607,6 @@ out4:
 	nfsd4_fslocs_free(&exp.ex_fslocs);
 	kfree(exp.ex_uuid);
 out3:
-	kfree(exp.ex_pathname);
-out2:
 	path_put(&exp.ex_path);
 out1:
 	auth_domain_put(dom);
@@ -678,7 +670,6 @@ static void svc_export_init(struct cache_head *cnew, struct cache_head *citem)
 	new->ex_client = item->ex_client;
 	new->ex_path.dentry = dget(item->ex_path.dentry);
 	new->ex_path.mnt = mntget(item->ex_path.mnt);
-	new->ex_pathname = NULL;
 	new->ex_fslocs.locations = NULL;
 	new->ex_fslocs.locations_count = 0;
 	new->ex_fslocs.migrated = 0;
@@ -696,8 +687,6 @@ static void export_update(struct cache_head *cnew, struct cache_head *citem)
 	new->ex_fsid = item->ex_fsid;
 	new->ex_uuid = item->ex_uuid;
 	item->ex_uuid = NULL;
-	new->ex_pathname = item->ex_pathname;
-	item->ex_pathname = NULL;
 	new->ex_fslocs.locations = item->ex_fslocs.locations;
 	item->ex_fslocs.locations = NULL;
 	new->ex_fslocs.locations_count = item->ex_fslocs.locations_count;
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
index 7ba3fd4..f85308e 100644
--- a/include/linux/nfsd/export.h
+++ b/include/linux/nfsd/export.h
@@ -96,7 +96,6 @@ struct svc_export {
 	struct auth_domain *	ex_client;
 	int			ex_flags;
 	struct path		ex_path;
-	char			*ex_pathname;
 	uid_t			ex_anon_uid;
 	gid_t			ex_anon_gid;
 	int			ex_fsid;


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 0/3] NFSD support for FedFS junctions
  2011-08-29 18:48 [PATCH 0/3] NFSD support for FedFS junctions Chuck Lever
  2011-08-29 18:48 ` [PATCH 1/3] NFSD: Cleanup for nfsd4_path() Chuck Lever
  2011-08-29 18:49 ` [PATCH 2/3] NFSD: Remove the ex_pathname field from struct svc_export Chuck Lever
@ 2011-08-29 18:55 ` Chuck Lever
  2 siblings, 0 replies; 4+ messages in thread
From: Chuck Lever @ 2011-08-29 18:55 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs

Sorry for the threading and patch numbering weirdness.  Our corporate mail server hiccup'd while I was sending these.

On Aug 29, 2011, at 2:48 PM, Chuck Lever wrote:

> Hi Bruce-
> 
> Sometime soon we are going to have working and easy-to-install FedFS
> user space components.  These kernel patches are going to be needed
> to make server-side FedFS support work.
> 
> Would you consider these for 3.2?
> 
> ---
> 
> Trond Myklebust (3):
>      NFSD: Add a cache for fs_locations information
>      NFSD: Remove the ex_pathname field from struct svc_export
>      NFSD: Cleanup for nfsd4_path()
> 
> 
> fs/nfsd/export.c            |   15 +-----
> fs/nfsd/nfs4xdr.c           |  106 ++++++++++++++++++++++++++++++++-----------
> fs/nfsd/nfsd.h              |    7 +++
> fs/nfsd/vfs.c               |   15 ++++++
> include/linux/nfsd/export.h |    2 -
> 5 files changed, 103 insertions(+), 42 deletions(-)
> 
> -- 
> Chuck Lever
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Chuck Lever
chuck[dot]lever[at]oracle[dot]com





^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2011-08-29 18:56 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-08-29 18:48 [PATCH 0/3] NFSD support for FedFS junctions Chuck Lever
2011-08-29 18:48 ` [PATCH 1/3] NFSD: Cleanup for nfsd4_path() Chuck Lever
2011-08-29 18:49 ` [PATCH 2/3] NFSD: Remove the ex_pathname field from struct svc_export Chuck Lever
2011-08-29 18:55 ` [PATCH 0/3] NFSD support for FedFS junctions Chuck Lever

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).