Netdev List
 help / color / mirror / Atom feed
* [PATCH 11/12] nfs: introduce mount option 'rpcmount'
From: Kirill A. Shutsemov @ 2010-12-20 11:54 UTC (permalink / raw)
  To: Trond Myklebust, J. Bruce Fields, Neil Brown
  Cc: Pavel Emelyanov, linux-nfs, David S. Miller, netdev, linux-kernel,
	Kirill A. Shutemov
In-Reply-To: <1292846078-31793-1-git-send-email-kirill@shutemov.name>

From: Kirill A. Shutemov <kirill@shutemov.name>

It specifies rpc_pipefs to use. init_rpc_pipefs, by default.

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 fs/nfs/callback.c         |    6 ++--
 fs/nfs/callback.h         |    3 +-
 fs/nfs/client.c           |   46 ++++++++++++++++++++++++++++++++++++--------
 fs/nfs/internal.h         |   10 +++++++-
 fs/nfs/mount_clnt.c       |    3 +-
 fs/nfs/namespace.c        |    3 +-
 fs/nfs/nfs4namespace.c    |   22 +++++++++++---------
 fs/nfs/super.c            |   20 +++++++++++++++++++
 include/linux/nfs_fs_sb.h |    1 +
 9 files changed, 86 insertions(+), 28 deletions(-)

diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index bef6abd..ef6d206 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -16,7 +16,6 @@
 #include <linux/freezer.h>
 #include <linux/kthread.h>
 #include <linux/sunrpc/svcauth_gss.h>
-#include <linux/sunrpc/rpc_pipe_fs.h>
 #if defined(CONFIG_NFS_V4_1)
 #include <linux/sunrpc/bc_xprt.h>
 #endif
@@ -239,7 +238,8 @@ static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt,
 /*
  * Bring up the callback thread if it is not already up.
  */
-int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
+int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt,
+		struct vfsmount *rpcmount)
 {
 	struct svc_serv *serv = NULL;
 	struct svc_rqst *rqstp;
@@ -254,7 +254,7 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
 		nfs_callback_bc_serv(minorversion, xprt, cb_info);
 		goto out;
 	}
-	serv = svc_create(&nfs4_callback_program, init_rpc_pipefs,
+	serv = svc_create(&nfs4_callback_program, rpcmount,
 			NFS4_CALLBACK_BUFSIZE, NULL);
 	if (!serv) {
 		ret = -ENOMEM;
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index 85a7cfd..ae27385 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -133,7 +133,8 @@ extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getat
 extern __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy);
 
 #ifdef CONFIG_NFS_V4
-extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt);
+extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt,
+		struct vfsmount *rpcmount);
 extern void nfs_callback_down(int minorversion);
 extern int nfs4_validate_delegation_stateid(struct nfs_delegation *delegation,
 					    const nfs4_stateid *stateid);
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index fbc013d..ccc400a 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -107,6 +107,7 @@ struct nfs_client_initdata {
 	const struct nfs_rpc_ops *rpc_ops;
 	int proto;
 	u32 minorversion;
+	struct vfsmount *rpcmount;
 };
 
 /*
@@ -143,6 +144,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
 	clp->cl_rpcclient = ERR_PTR(-EINVAL);
 
 	clp->cl_proto = cl_init->proto;
+	clp->cl_rpcmount = mntget(cl_init->rpcmount);
 
 #ifdef CONFIG_NFS_V4
 	INIT_LIST_HEAD(&clp->cl_delegations);
@@ -231,6 +233,7 @@ static void nfs_free_client(struct nfs_client *clp)
 	if (clp->cl_machine_cred != NULL)
 		put_rpccred(clp->cl_machine_cred);
 
+	mntput(clp->cl_rpcmount);
 	kfree(clp->cl_hostname);
 	kfree(clp);
 
@@ -457,6 +460,9 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
 		/* Match the full socket address */
 		if (!nfs_sockaddr_cmp(sap, clap))
 			continue;
+		/* Match rpc_pipefs mount point */
+		if (clp->cl_rpcmount->mnt_sb != data->rpcmount->mnt_sb)
+			continue;
 
 		atomic_inc(&clp->cl_count);
 		return clp;
@@ -615,7 +621,7 @@ static int nfs_create_rpc_client(struct nfs_client *clp,
 		.program	= &nfs_program,
 		.version	= clp->rpc_ops->version,
 		.authflavor	= flavor,
-		.rpcmount	= init_rpc_pipefs,
+		.rpcmount	= clp->cl_rpcmount,
 	};
 
 	if (discrtry)
@@ -650,7 +656,7 @@ static void nfs_destroy_server(struct nfs_server *server)
 /*
  * Version 2 or 3 lockd setup
  */
-static int nfs_start_lockd(struct nfs_server *server)
+static int nfs_start_lockd(struct nfs_server *server, struct vfsmount *rpcmount)
 {
 	struct nlm_host *host;
 	struct nfs_client *clp = server->nfs_client;
@@ -661,7 +667,7 @@ static int nfs_start_lockd(struct nfs_server *server)
 		.nfs_version	= clp->rpc_ops->version,
 		.noresvport	= server->flags & NFS_MOUNT_NORESVPORT ?
 					1 : 0,
-		.rpcmount	= init_rpc_pipefs,
+		.rpcmount	= rpcmount,
 	};
 
 	if (nlm_init.nfs_version > 3)
@@ -809,8 +815,16 @@ static int nfs_init_server(struct nfs_server *server,
 		cl_init.rpc_ops = &nfs_v3_clientops;
 #endif
 
+	cl_init.rpcmount = get_rpc_pipefs(data->rpcmount);
+	if (IS_ERR(cl_init.rpcmount)) {
+		dprintk("<-- nfs_init_server() = error %ld\n",
+				PTR_ERR(cl_init.rpcmount));
+		return PTR_ERR(cl_init.rpcmount);
+	}
+
 	/* Allocate or find a client reference we can use */
 	clp = nfs_get_client(&cl_init);
+	mntput(cl_init.rpcmount);
 	if (IS_ERR(clp)) {
 		dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp));
 		return PTR_ERR(clp);
@@ -842,7 +856,7 @@ static int nfs_init_server(struct nfs_server *server,
 	server->acdirmax = data->acdirmax * HZ;
 
 	/* Start lockd here, before we might error out */
-	error = nfs_start_lockd(server);
+	error = nfs_start_lockd(server, clp->cl_rpcmount);
 	if (error < 0)
 		goto error;
 
@@ -1144,7 +1158,8 @@ static int nfs4_init_callback(struct nfs_client *clp)
 		}
 
 		error = nfs_callback_up(clp->cl_mvops->minor_version,
-					clp->cl_rpcclient->cl_xprt);
+					clp->cl_rpcclient->cl_xprt,
+					clp->cl_rpcmount);
 		if (error < 0) {
 			dprintk("%s: failed to start callback. Error = %d\n",
 				__func__, error);
@@ -1244,7 +1259,8 @@ static int nfs4_set_client(struct nfs_server *server,
 		const char *ip_addr,
 		rpc_authflavor_t authflavour,
 		int proto, const struct rpc_timeout *timeparms,
-		u32 minorversion)
+		u32 minorversion,
+		struct vfsmount *rpcmount)
 {
 	struct nfs_client_initdata cl_init = {
 		.hostname = hostname,
@@ -1253,6 +1269,7 @@ static int nfs4_set_client(struct nfs_server *server,
 		.rpc_ops = &nfs_v4_clientops,
 		.proto = proto,
 		.minorversion = minorversion,
+		.rpcmount = rpcmount,
 	};
 	struct nfs_client *clp;
 	int error;
@@ -1363,6 +1380,7 @@ static int nfs4_init_server(struct nfs_server *server,
 		const struct nfs_parsed_mount_data *data)
 {
 	struct rpc_timeout timeparms;
+	struct vfsmount *rpcmount;
 	int error;
 
 	dprintk("--> nfs4_init_server()\n");
@@ -1377,6 +1395,11 @@ static int nfs4_init_server(struct nfs_server *server,
 			server->caps |= NFS_CAP_READDIRPLUS;
 	server->options = data->options;
 
+	rpcmount = get_rpc_pipefs(data->rpcmount);
+	if (IS_ERR(rpcmount)) {
+		error = PTR_ERR(rpcmount);
+		goto error;
+	}
 	/* Get a client record */
 	error = nfs4_set_client(server,
 			data->nfs_server.hostname,
@@ -1386,7 +1409,9 @@ static int nfs4_init_server(struct nfs_server *server,
 			data->auth_flavors[0],
 			data->nfs_server.protocol,
 			&timeparms,
-			data->minorversion);
+			data->minorversion,
+			rpcmount);
+	mntput(rpcmount);
 	if (error < 0)
 		goto error;
 
@@ -1476,7 +1501,10 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
 				data->authflavor,
 				parent_server->client->cl_xprt->prot,
 				parent_server->client->cl_timeout,
-				parent_client->cl_mvops->minor_version);
+				parent_client->cl_mvops->minor_version,
+				parent_client->cl_rpcmount);
+
+
 	if (error < 0)
 		goto error;
 
@@ -1550,7 +1578,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
 		(unsigned long long) server->fsid.major,
 		(unsigned long long) server->fsid.minor);
 
-	error = nfs_start_lockd(server);
+	error = nfs_start_lockd(server, server->nfs_client->cl_rpcmount);
 	if (error < 0)
 		goto out_free_server;
 
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index e6356b7..cb31fd9 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -86,6 +86,7 @@ struct nfs_parsed_mount_data {
 	unsigned int		version;
 	unsigned int		minorversion;
 	char			*fscache_uniq;
+	char			*rpcmount;
 
 	struct {
 		struct sockaddr_storage	address;
@@ -120,6 +121,7 @@ struct nfs_mount_request {
 	int			noresvport;
 	unsigned int		*auth_flav_len;
 	rpc_authflavor_t	*auth_flavs;
+	struct vfsmount		*rpcmount;
 };
 
 extern int nfs_mount(struct nfs_mount_request *info);
@@ -160,10 +162,14 @@ static inline void nfs_fs_proc_exit(void)
 
 /* nfs4namespace.c */
 #ifdef CONFIG_NFS_V4
-extern struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry);
+extern struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent,
+		struct dentry *dentry,
+		struct vfsmount *rpcmount);
 #else
 static inline
-struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry)
+struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent,
+		struct dentry *dentry,
+		struct vfsmount *rpcmount)
 {
 	return ERR_PTR(-ENOENT);
 }
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index 67b4b8d..9fd4157 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -13,7 +13,6 @@
 #include <linux/in.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/sched.h>
-#include <linux/sunrpc/rpc_pipe_fs.h>
 #include <linux/nfs_fs.h>
 #include "internal.h"
 
@@ -162,7 +161,7 @@ int nfs_mount(struct nfs_mount_request *info)
 		.program	= &mnt_program,
 		.version	= info->version,
 		.authflavor	= RPC_AUTH_UNIX,
-		.rpcmount	= init_rpc_pipefs,
+		.rpcmount	= info->rpcmount,
 	};
 	struct rpc_clnt		*mnt_clnt;
 	int			status;
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index db6aa36..d47f6f5 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -135,7 +135,8 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
 		goto out_err;
 
 	if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL)
-		mnt = nfs_do_refmount(nd->path.mnt, nd->path.dentry);
+		mnt = nfs_do_refmount(nd->path.mnt, nd->path.dentry,
+				server->nfs_client->cl_rpcmount);
 	else
 		mnt = nfs_do_submount(nd->path.mnt, nd->path.dentry, fh,
 				      fattr);
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index 7a61fdb..92d5d63 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -14,7 +14,6 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/sunrpc/clnt.h>
-#include <linux/sunrpc/rpc_pipe_fs.h>
 #include <linux/vfs.h>
 #include <linux/inet.h>
 #include "internal.h"
@@ -99,14 +98,13 @@ static int nfs4_validate_fspath(const struct vfsmount *mnt_parent,
 }
 
 static size_t nfs_parse_server_name(char *string, size_t len,
-		struct sockaddr *sa, size_t salen)
+		struct sockaddr *sa, size_t salen, struct vfsmount *rpcmount)
 {
 	ssize_t ret;
 
 	ret = rpc_pton(string, len, sa, salen);
 	if (ret == 0) {
-		ret = nfs_dns_resolve_name(string, len, sa, salen,
-				init_rpc_pipefs);
+		ret = nfs_dns_resolve_name(string, len, sa, salen, rpcmount);
 		if (ret < 0)
 			ret = 0;
 	}
@@ -115,7 +113,8 @@ static size_t nfs_parse_server_name(char *string, size_t len,
 
 static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
 				     char *page, char *page2,
-				     const struct nfs4_fs_location *location)
+				     const struct nfs4_fs_location *location,
+				     struct vfsmount *rpcmount)
 {
 	const size_t addr_bufsize = sizeof(struct sockaddr_storage);
 	struct vfsmount *mnt = ERR_PTR(-ENOENT);
@@ -143,7 +142,7 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
 			continue;
 
 		mountdata->addrlen = nfs_parse_server_name(buf->data, buf->len,
-				mountdata->addr, addr_bufsize);
+				mountdata->addr, addr_bufsize, rpcmount);
 		if (mountdata->addrlen == 0)
 			continue;
 
@@ -174,7 +173,8 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
  */
 static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
 					    const struct dentry *dentry,
-					    const struct nfs4_fs_locations *locations)
+					    const struct nfs4_fs_locations *locations,
+					    struct vfsmount *rpcmount)
 {
 	struct vfsmount *mnt = ERR_PTR(-ENOENT);
 	struct nfs_clone_mount mountdata = {
@@ -213,7 +213,7 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
 		    location->rootpath.ncomponents == 0)
 			continue;
 
-		mnt = try_location(&mountdata, page, page2, location);
+		mnt = try_location(&mountdata, page, page2, location, rpcmount);
 		if (!IS_ERR(mnt))
 			break;
 	}
@@ -231,7 +231,9 @@ out:
  * @dentry - dentry of referral
  *
  */
-struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry)
+struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent,
+		struct dentry *dentry,
+		struct vfsmount *rpcmount)
 {
 	struct vfsmount *mnt = ERR_PTR(-ENOMEM);
 	struct dentry *parent;
@@ -264,7 +266,7 @@ struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentr
 	    fs_locations->fs_path.ncomponents <= 0)
 		goto out_free;
 
-	mnt = nfs_follow_referral(mnt_parent, dentry, fs_locations);
+	mnt = nfs_follow_referral(mnt_parent, dentry, fs_locations, rpcmount);
 out_free:
 	__free_page(page);
 	kfree(fs_locations);
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 4100630..32b7e35 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -35,6 +35,7 @@
 #include <linux/sunrpc/metrics.h>
 #include <linux/sunrpc/xprtsock.h>
 #include <linux/sunrpc/xprtrdma.h>
+#include <linux/sunrpc/rpc_pipe_fs.h>
 #include <linux/nfs_fs.h>
 #include <linux/nfs_mount.h>
 #include <linux/nfs4_mount.h>
@@ -106,6 +107,7 @@ enum {
 	Opt_lookupcache,
 	Opt_fscache_uniq,
 	Opt_local_lock,
+	Opt_rpcmount,
 
 	/* Special mount options */
 	Opt_userspace, Opt_deprecated, Opt_sloppy,
@@ -178,6 +180,7 @@ static const match_table_t nfs_mount_option_tokens = {
 	{ Opt_lookupcache, "lookupcache=%s" },
 	{ Opt_fscache_uniq, "fsc=%s" },
 	{ Opt_local_lock, "local_lock=%s" },
+	{ Opt_rpcmount, "rpcmount=%s" },
 
 	{ Opt_err, NULL }
 };
@@ -1484,6 +1487,13 @@ static int nfs_parse_mount_options(char *raw,
 				return 0;
 			};
 			break;
+		case Opt_rpcmount:
+			string = match_strdup(args);
+			if (string == NULL)
+				goto out_nomem;
+			kfree(mnt->rpcmount);
+			mnt->rpcmount = string;
+			break;
 
 		/*
 		 * Special options
@@ -1644,11 +1654,19 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
 	request.salen = args->mount_server.addrlen;
 	nfs_set_port(request.sap, &args->mount_server.port, 0);
 
+	request.rpcmount = get_rpc_pipefs(args->rpcmount);
+	if (IS_ERR(request.rpcmount)) {
+		dfprintk(MOUNT,	"NFS: unable get rpc_pipefs mount point, "
+				"error %ld\n", PTR_ERR(request.rpcmount));
+		return PTR_ERR(request.rpcmount);
+	}
+
 	/*
 	 * Now ask the mount server to map our export path
 	 * to a file handle.
 	 */
 	status = nfs_mount(&request);
+	mntput(request.rpcmount);
 	if (status != 0) {
 		dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n",
 				request.hostname, status);
@@ -2352,6 +2370,7 @@ out:
 	kfree(data->nfs_server.hostname);
 	kfree(data->mount_server.hostname);
 	kfree(data->fscache_uniq);
+	kfree(data->rpcmount);
 	security_free_mnt_opts(&data->lsm_opts);
 out_free_fh:
 	nfs_free_fhandle(mntfh);
@@ -2947,6 +2966,7 @@ out:
 	kfree(data->nfs_server.export_path);
 	kfree(data->nfs_server.hostname);
 	kfree(data->fscache_uniq);
+	kfree(data->rpcmount);
 out_free_data:
 	kfree(data);
 	dprintk("<-- nfs4_get_sb() = %d%s\n", error,
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 452d964..ee417c9 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -36,6 +36,7 @@ struct nfs_client {
 	struct list_head	cl_share_link;	/* link in global client list */
 	struct list_head	cl_superblocks;	/* List of nfs_server structs */
 
+	struct vfsmount		*cl_rpcmount;	/* rpc_pipefs mount point */
 	struct rpc_clnt *	cl_rpcclient;
 	const struct nfs_rpc_ops *rpc_ops;	/* NFS protocol vector */
 	int			cl_proto;	/* Network transport protocol */
-- 
1.7.3.4

^ permalink raw reply related

* [PATCH 12/12] sunrpc: make rpc_pipefs be mountable multiple times
From: Kirill A. Shutsemov @ 2010-12-20 11:54 UTC (permalink / raw)
  To: Trond Myklebust, J. Bruce Fields, Neil Brown
  Cc: Pavel Emelyanov, linux-nfs, David S. Miller, netdev, linux-kernel,
	Kirill A. Shutemov
In-Reply-To: <1292846078-31793-1-git-send-email-kirill@shutemov.name>

From: Kirill A. Shutemov <kirill@shutemov.name>

To support containers, allow multiple independent instances of
rpc_pipefs. Use '-o newinstance' to create new of the filesystem.
The same semantics as with devpts.

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 net/sunrpc/rpc_pipe.c |   80 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 79 insertions(+), 1 deletions(-)

diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index c48f7a5..836e725 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -16,6 +16,7 @@
 #include <linux/namei.h>
 #include <linux/fsnotify.h>
 #include <linux/kernel.h>
+#include <linux/parser.h>
 
 #include <asm/ioctls.h>
 #include <linux/fs.h>
@@ -38,6 +39,49 @@ static struct kmem_cache *rpc_inode_cachep __read_mostly;
 
 #define RPC_UPCALL_TIMEOUT (30*HZ)
 
+struct rpc_mount_opts {
+	int newinstance;
+};
+
+enum {
+	Opt_newinstance,
+
+	Opt_err
+};
+
+static const match_table_t tokens = {
+	{Opt_newinstance, "newinstance"},
+
+	{Opt_err, NULL}
+};
+
+static int
+parse_mount_options(char *data, struct rpc_mount_opts *opts)
+{
+	char *p;
+
+	opts->newinstance = 0;
+
+	while ((p = strsep(&data, ",")) != NULL) {
+		substring_t args[MAX_OPT_ARGS];
+		int token;
+
+		if (!*p)
+			continue;
+
+		token = match_token(p, tokens, args);
+		switch (token) {
+		case Opt_newinstance:
+			opts->newinstance = 1;
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
 static void rpc_purge_list(struct rpc_inode *rpci, struct list_head *head,
 		void (*destroy_msg)(struct rpc_pipe_msg *), int err)
 {
@@ -1025,11 +1069,45 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
 	return 0;
 }
 
+static int
+compare_rpc_mnt_sb(struct super_block *s, void *p)
+{
+	if (init_rpc_pipefs)
+		return init_rpc_pipefs->mnt_sb == s;
+	return 0;
+}
+
 static struct dentry *
 rpc_mount(struct file_system_type *fs_type,
 		int flags, const char *dev_name, void *data)
 {
-	return mount_single(fs_type, flags, data, rpc_fill_super);
+	int error;
+	struct rpc_mount_opts opts;
+	struct super_block *s;
+
+	error = parse_mount_options(data, &opts);
+	if (error)
+		return ERR_PTR(error);
+
+	if (opts.newinstance)
+		s = sget(fs_type, NULL, set_anon_super, NULL);
+	else
+		s = sget(fs_type, compare_rpc_mnt_sb, set_anon_super, NULL);
+
+	if (IS_ERR(s))
+		return ERR_CAST(s);
+
+	if (!s->s_root) {
+		s->s_flags = flags;
+		error = rpc_fill_super(s, data, flags & MS_SILENT ? 1 : 0);
+		if (error) {
+			deactivate_locked_super(s);
+			return ERR_PTR(error);
+		}
+		s->s_flags |= MS_ACTIVE;
+	}
+
+	return dget(s->s_root);
 }
 
 static struct file_system_type rpc_pipe_fs_type = {
-- 
1.7.3.4

^ permalink raw reply related

* [PATCH 07/12] sunrpc: get rpc_pipefs mount point for rpcb_create_local from callers
From: Kirill A. Shutsemov @ 2010-12-20 11:54 UTC (permalink / raw)
  To: Trond Myklebust, J. Bruce Fields, Neil Brown
  Cc: Pavel Emelyanov, linux-nfs, David S. Miller, netdev, linux-kernel,
	Kirill A. Shutemov
In-Reply-To: <1292846078-31793-1-git-send-email-kirill@shutemov.name>

From: Kirill A. Shutemov <kirill@shutemov.name>

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 include/linux/sunrpc/clnt.h |    4 ++--
 net/sunrpc/rpcb_clnt.c      |   15 ++++++++-------
 net/sunrpc/svc.c            |   34 +++++++++++++++++++++-------------
 3 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index f052712..59eda38 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -135,10 +135,10 @@ void		rpc_shutdown_client(struct rpc_clnt *);
 void		rpc_release_client(struct rpc_clnt *);
 void		rpc_task_release_client(struct rpc_task *);
 
-int		rpcb_register(u32, u32, int, unsigned short);
+int		rpcb_register(u32, u32, int, unsigned short, struct vfsmount *);
 int		rpcb_v4_register(const u32 program, const u32 version,
 				 const struct sockaddr *address,
-				 const char *netid);
+				 const char *netid, struct vfsmount *rpcmount);
 void		rpcb_getport_async(struct rpc_task *);
 
 void		rpc_call_start(struct rpc_task *);
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 732adef..eb29dfa 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -27,7 +27,6 @@
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/sched.h>
 #include <linux/sunrpc/xprtsock.h>
-#include <linux/sunrpc/rpc_pipe_fs.h>
 
 #ifdef RPC_DEBUG
 # define RPCDBG_FACILITY	RPCDBG_BIND
@@ -175,7 +174,7 @@ static DEFINE_MUTEX(rpcb_create_local_mutex);
  * Returns zero on success, otherwise a negative errno value
  * is returned.
  */
-static int rpcb_create_local(void)
+static int rpcb_create_local(struct vfsmount *rpcmount)
 {
 	struct rpc_create_args args = {
 		.net		= &init_net,
@@ -187,7 +186,7 @@ static int rpcb_create_local(void)
 		.version	= RPCBVERS_2,
 		.authflavor	= RPC_AUTH_UNIX,
 		.flags		= RPC_CLNT_CREATE_NOPING,
-		.rpcmount	= init_rpc_pipefs,
+		.rpcmount	= rpcmount,
 	};
 	struct rpc_clnt *clnt, *clnt4;
 	int result = 0;
@@ -308,7 +307,8 @@ static int rpcb_register_call(struct rpc_clnt *clnt, struct rpc_message *msg)
  * IN6ADDR_ANY (ie available for all AF_INET and AF_INET6
  * addresses).
  */
-int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
+int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port,
+		struct vfsmount *rpcmount)
 {
 	struct rpcbind_args map = {
 		.r_prog		= prog,
@@ -321,7 +321,7 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
 	};
 	int error;
 
-	error = rpcb_create_local();
+	error = rpcb_create_local(rpcmount);
 	if (error)
 		return error;
 
@@ -448,7 +448,8 @@ static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
  * advertises the service on all IPv4 and IPv6 addresses.
  */
 int rpcb_v4_register(const u32 program, const u32 version,
-		     const struct sockaddr *address, const char *netid)
+		     const struct sockaddr *address, const char *netid,
+		     struct vfsmount *rpcmount)
 {
 	struct rpcbind_args map = {
 		.r_prog		= program,
@@ -461,7 +462,7 @@ int rpcb_v4_register(const u32 program, const u32 version,
 	};
 	int error;
 
-	error = rpcb_create_local();
+	error = rpcb_create_local(rpcmount);
 	if (error)
 		return error;
 	if (rpcb_local_clnt4 == NULL)
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 0bd6088..e0ae040 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -743,7 +743,8 @@ EXPORT_SYMBOL_GPL(svc_exit_thread);
  */
 static int __svc_rpcb_register4(const u32 program, const u32 version,
 				const unsigned short protocol,
-				const unsigned short port)
+				const unsigned short port,
+				struct vfsmount *rpcmount)
 {
 	const struct sockaddr_in sin = {
 		.sin_family		= AF_INET,
@@ -765,14 +766,16 @@ static int __svc_rpcb_register4(const u32 program, const u32 version,
 	}
 
 	error = rpcb_v4_register(program, version,
-					(const struct sockaddr *)&sin, netid);
+					(const struct sockaddr *)&sin, netid,
+					rpcmount);
 
 	/*
 	 * User space didn't support rpcbind v4, so retry this
 	 * registration request with the legacy rpcbind v2 protocol.
 	 */
 	if (error == -EPROTONOSUPPORT)
-		error = rpcb_register(program, version, protocol, port);
+		error = rpcb_register(program, version, protocol, port,
+				rpcmount);
 
 	return error;
 }
@@ -790,7 +793,8 @@ static int __svc_rpcb_register4(const u32 program, const u32 version,
  */
 static int __svc_rpcb_register6(const u32 program, const u32 version,
 				const unsigned short protocol,
-				const unsigned short port)
+				const unsigned short port,
+				struct vfsmount *rpcmount)
 {
 	const struct sockaddr_in6 sin6 = {
 		.sin6_family		= AF_INET6,
@@ -812,7 +816,8 @@ static int __svc_rpcb_register6(const u32 program, const u32 version,
 	}
 
 	error = rpcb_v4_register(program, version,
-					(const struct sockaddr *)&sin6, netid);
+					(const struct sockaddr *)&sin6, netid,
+					rpcmount);
 
 	/*
 	 * User space didn't support rpcbind version 4, so we won't
@@ -835,19 +840,20 @@ static int __svc_register(const char *progname,
 			  const u32 program, const u32 version,
 			  const int family,
 			  const unsigned short protocol,
-			  const unsigned short port)
+			  const unsigned short port,
+			  struct vfsmount *rpcmount)
 {
 	int error = -EAFNOSUPPORT;
 
 	switch (family) {
 	case PF_INET:
 		error = __svc_rpcb_register4(program, version,
-						protocol, port);
+						protocol, port, rpcmount);
 		break;
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	case PF_INET6:
 		error = __svc_rpcb_register6(program, version,
-						protocol, port);
+						protocol, port, rpcmount);
 #endif	/* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
 	}
 
@@ -893,7 +899,8 @@ int svc_register(const struct svc_serv *serv, const int family,
 				continue;
 
 			error = __svc_register(progp->pg_name, progp->pg_prog,
-						i, family, proto, port);
+						i, family, proto, port,
+						serv->sv_rpcmount);
 			if (error < 0)
 				break;
 		}
@@ -910,18 +917,18 @@ int svc_register(const struct svc_serv *serv, const int family,
  * in this case to clear all existing entries for [program, version].
  */
 static void __svc_unregister(const u32 program, const u32 version,
-			     const char *progname)
+			     const char *progname, struct vfsmount *rpcmount)
 {
 	int error;
 
-	error = rpcb_v4_register(program, version, NULL, "");
+	error = rpcb_v4_register(program, version, NULL, "", rpcmount);
 
 	/*
 	 * User space didn't support rpcbind v4, so retry this
 	 * request with the legacy rpcbind v2 protocol.
 	 */
 	if (error == -EPROTONOSUPPORT)
-		error = rpcb_register(program, version, 0, 0);
+		error = rpcb_register(program, version, 0, 0, rpcmount);
 
 	dprintk("svc: %s(%sv%u), error %d\n",
 			__func__, progname, version, error);
@@ -950,7 +957,8 @@ static void svc_unregister(const struct svc_serv *serv)
 			if (progp->pg_vers[i]->vs_hidden)
 				continue;
 
-			__svc_unregister(progp->pg_prog, i, progp->pg_name);
+			__svc_unregister(progp->pg_prog, i, progp->pg_name,
+					serv->sv_rpcmount);
 		}
 	}
 
-- 
1.7.3.4


^ permalink raw reply related

* [PATCH 10/12] sunrpc: introduce get_rpc_pipefs()
From: Kirill A. Shutsemov @ 2010-12-20 11:54 UTC (permalink / raw)
  To: Trond Myklebust, J. Bruce Fields, Neil Brown
  Cc: Pavel Emelyanov, linux-nfs, David S. Miller, netdev, linux-kernel,
	Kirill A. Shutemov
In-Reply-To: <1292846078-31793-1-git-send-email-kirill@shutemov.name>

From: Kirill A. Shutemov <kirill@shutemov.name>

Get rpc_pipefs mount point by path.

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 include/linux/sunrpc/rpc_pipe_fs.h |    2 ++
 net/sunrpc/rpc_pipe.c              |   24 ++++++++++++++++++++++++
 2 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
index b09bfa5..922057c 100644
--- a/include/linux/sunrpc/rpc_pipe_fs.h
+++ b/include/linux/sunrpc/rpc_pipe_fs.h
@@ -46,6 +46,8 @@ RPC_I(struct inode *inode)
 
 extern struct vfsmount *init_rpc_pipefs;
 
+struct vfsmount *get_rpc_pipefs(const char *path);
+
 extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *);
 
 struct rpc_clnt;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index b1e299b..c48f7a5 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -931,6 +931,30 @@ static const struct super_operations s_ops = {
 
 #define RPCAUTH_GSSMAGIC 0x67596969
 
+struct vfsmount *get_rpc_pipefs(const char *p)
+{
+	int error;
+	struct vfsmount *rpcmount;
+	struct path path;
+
+	if (!p)
+		return mntget(init_rpc_pipefs);
+
+	error = kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
+	if (error)
+		return ERR_PTR(error);
+
+	if (path.mnt->mnt_sb->s_magic != RPCAUTH_GSSMAGIC) {
+		path_put(&path);
+		return ERR_PTR(-EINVAL);
+	}
+
+	rpcmount = mntget(path.mnt);
+	path_put(&path);
+
+	return rpcmount;
+}
+
 /*
  * We have a single directory with 1 node in it.
  */
-- 
1.7.3.4


^ permalink raw reply related

* [PATCH 08/12] sunrpc: tag pipefs field of cache_detail with rpc_pipefs mount point
From: Kirill A. Shutsemov @ 2010-12-20 11:54 UTC (permalink / raw)
  To: Trond Myklebust, J. Bruce Fields, Neil Brown
  Cc: Pavel Emelyanov, linux-nfs, David S. Miller, netdev, linux-kernel,
	Kirill A. Shutemov
In-Reply-To: <1292846078-31793-1-git-send-email-kirill@shutemov.name>

From: Kirill A. Shutemov <kirill@shutemov.name>

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 fs/nfs/cache_lib.c           |    3 +--
 include/linux/sunrpc/cache.h |    9 +++------
 net/sunrpc/cache.c           |   16 ++++++++++------
 3 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/fs/nfs/cache_lib.c b/fs/nfs/cache_lib.c
index dd7ca5f..0944d4e 100644
--- a/fs/nfs/cache_lib.c
+++ b/fs/nfs/cache_lib.c
@@ -123,7 +123,7 @@ int nfs_cache_register(struct cache_detail *cd)
 	ret = vfs_path_lookup(mnt->mnt_root, mnt, "/cache", 0, &nd);
 	if (ret)
 		goto err;
-	ret = sunrpc_cache_register_pipefs(nd.path.dentry,
+	ret = sunrpc_cache_register_pipefs(mnt, nd.path.dentry,
 			cd->name, 0600, cd);
 	path_put(&nd.path);
 	if (!ret)
@@ -136,6 +136,5 @@ err:
 void nfs_cache_unregister(struct cache_detail *cd)
 {
 	sunrpc_cache_unregister_pipefs(cd);
-	mntput(init_rpc_pipefs);
 }
 
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
index 6950c98..d34a621 100644
--- a/include/linux/sunrpc/cache.h
+++ b/include/linux/sunrpc/cache.h
@@ -64,10 +64,6 @@ struct cache_detail_procfs {
 	struct proc_dir_entry   *flush_ent, *channel_ent, *content_ent;
 };
 
-struct cache_detail_pipefs {
-	struct dentry *dir;
-};
-
 struct cache_detail {
 	struct module *		owner;
 	int			hash_size;
@@ -114,7 +110,7 @@ struct cache_detail {
 
 	union {
 		struct cache_detail_procfs procfs;
-		struct cache_detail_pipefs pipefs;
+		struct path pipefs;
 	} u;
 };
 
@@ -201,7 +197,8 @@ extern int cache_register_net(struct cache_detail *cd, struct net *net);
 extern void cache_unregister(struct cache_detail *cd);
 extern void cache_unregister_net(struct cache_detail *cd, struct net *net);
 
-extern int sunrpc_cache_register_pipefs(struct dentry *parent, const char *,
+extern int sunrpc_cache_register_pipefs(struct vfsmount *rpcmount,
+					struct dentry *parent, const char *,
 					mode_t, struct cache_detail *);
 extern void sunrpc_cache_unregister_pipefs(struct cache_detail *);
 
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index e433e75..ed50d49 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -28,6 +28,7 @@
 #include <linux/workqueue.h>
 #include <linux/mutex.h>
 #include <linux/pagemap.h>
+#include <linux/mount.h>
 #include <asm/ioctls.h>
 #include <linux/sunrpc/types.h>
 #include <linux/sunrpc/cache.h>
@@ -1753,7 +1754,8 @@ const struct file_operations cache_flush_operations_pipefs = {
 	.llseek		= no_llseek,
 };
 
-int sunrpc_cache_register_pipefs(struct dentry *parent,
+int sunrpc_cache_register_pipefs(struct vfsmount *rpcmount,
+				 struct dentry *parent,
 				 const char *name, mode_t umode,
 				 struct cache_detail *cd)
 {
@@ -1766,9 +1768,10 @@ int sunrpc_cache_register_pipefs(struct dentry *parent,
 	q.len = strlen(name);
 	q.hash = full_name_hash(q.name, q.len);
 	dir = rpc_create_cache_dir(parent, &q, umode, cd);
-	if (!IS_ERR(dir))
-		cd->u.pipefs.dir = dir;
-	else {
+	if (!IS_ERR(dir)) {
+		cd->u.pipefs.mnt = mntget(rpcmount);
+		cd->u.pipefs.dentry = dir;
+	} else {
 		sunrpc_destroy_cache_detail(cd);
 		ret = PTR_ERR(dir);
 	}
@@ -1778,8 +1781,9 @@ EXPORT_SYMBOL_GPL(sunrpc_cache_register_pipefs);
 
 void sunrpc_cache_unregister_pipefs(struct cache_detail *cd)
 {
-	rpc_remove_cache_dir(cd->u.pipefs.dir);
-	cd->u.pipefs.dir = NULL;
+	rpc_remove_cache_dir(cd->u.pipefs.dentry);
+	cd->u.pipefs.dentry = NULL;
+	mntput(cd->u.pipefs.mnt);
 	sunrpc_destroy_cache_detail(cd);
 }
 EXPORT_SYMBOL_GPL(sunrpc_cache_unregister_pipefs);
-- 
1.7.3.4


^ permalink raw reply related

* Re: Kernel panic eth2 mirred redirect to ifb0
From: Jarek Poplawski @ 2010-12-20 11:58 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Changli Gao, Paweł Staszewski, David S. Miller,
	Linux Network Development list
In-Reply-To: <20101220111141.GC7977@ff.dom.local>

On Mon, Dec 20, 2010 at 11:11:41AM +0000, Jarek Poplawski wrote:
> To tell the truth, Changli could assume we don't need to tell anything,
> because this mirred skb is almost not shared (except the refcount ;-).

Btw, since there was ifb involved, I doubt this skb could hit ixgbe
xmit before unsharing, and patching the driver could matter. Anyway,
Changli, I guess, Pawel needs some instructions on this last patch?

Jarek P.

^ permalink raw reply

* AW: [PATCH] ISDN cmx: Avoid potential NULL deref in dsp_cmx_send_member() and shrink code size.
From: Andreas.Eversberg @ 2010-12-20 11:26 UTC (permalink / raw)
  To: Jesper Juhl, Karsten Keil
  Cc: David S. Miller, Julia Lawall, Tejun Heo, netdev, linux-kernel

hi jesper,

thanx for finding the bug. i think the right solution to solve the problem would be:

                if (dsp->conf && dsp->conf->software && dsp->conf->hardware)
                        tx_data_only = 1;
->              if (dsp->echo.software && dsp->echo.hardware)
                        tx_data_only = 1;

this is how it looks in the 'socket' branch of mISDN git respository. it has been fixed already. but i cannot tell in which commit. my current head is this commit:
commit 45a51eed1c554a4891b48b88c270f4f95bd21df0

what branch do you use? 

regards,

andreas


-----Ursprüngliche Nachricht-----
Von: Jesper Juhl [mailto:jj@chaosbits.net] 
Gesendet: Samstag, 18. Dezember 2010 23:34
An: Karsten Keil
Cc: David S. Miller; Julia Lawall; Tejun Heo; netdev@vger.kernel.org; linux-kernel@vger.kernel.org; Andreas Eversberg
Betreff: [PATCH] ISDN cmx: Avoid potential NULL deref in dsp_cmx_send_member() and shrink code size.

Hi there,

In drivers/isdn/mISDN/dsp_cmx.c::dsp_cmx_send_member() we currently have 
this code:

           if (dsp->conf && dsp->conf->software && dsp->conf->hardware)
                   tx_data_only = 1;
           if (dsp->conf->software && dsp->echo.hardware)
                   tx_data_only = 1;

The first line implies that 'dsp->conf' may be NULL. If it is, then the 
third line will dereference a NULL pointer.

This patch reworks the code so that we avoid the potential NULL deref.
It also has the added benefit that the object file size shrinks a bit.

before:
   text    data     bss     dec     hex filename
  18840     112    5784   24736    60a0 drivers/isdn/mISDN/dsp_cmx.o
after:
   text    data     bss     dec     hex filename
  18816     112    5776   24704    6080 drivers/isdn/mISDN/dsp_cmx.o


Signed-off-by: Jesper Juhl <jj@chaosbits.net>
---
 dsp_cmx.c |    7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

 compile tested only

diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c
index 76d9e67..f76f595 100644
--- a/drivers/isdn/mISDN/dsp_cmx.c
+++ b/drivers/isdn/mISDN/dsp_cmx.c
@@ -1326,10 +1326,9 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
 			dsp->last_tx = 0;
 			return;
 		}
-		if (dsp->conf && dsp->conf->software && dsp->conf->hardware)
-			tx_data_only = 1;
-		if (dsp->conf->software && dsp->echo.hardware)
-			tx_data_only = 1;
+		if (dsp->conf && dsp->conf->software)
+			if (dsp->conf->hardware || dsp->echo.hardware)
+				tx_data_only = 1;
 	}
 
 #ifdef CMX_DEBUG



-- 
Jesper Juhl <jj@chaosbits.net>            http://www.chaosbits.net/
Don't top-post http://www.catb.org/~esr/jargon/html/T/top-post.html
Plain text mails only, please.

^ permalink raw reply related

* Re: Kernel panic eth2 mirred redirect to ifb0
From: Paweł Staszewski @ 2010-12-20 12:07 UTC (permalink / raw)
  To: Jarek Poplawski
  Cc: Eric Dumazet, Changli Gao, David S. Miller,
	Linux Network Development list
In-Reply-To: <20101220115855.GD7977@ff.dom.local>

[-- Attachment #1: Type: text/plain, Size: 1266 bytes --]

W dniu 2010-12-20 12:58, Jarek Poplawski pisze:
> On Mon, Dec 20, 2010 at 11:11:41AM +0000, Jarek Poplawski wrote:
>> To tell the truth, Changli could assume we don't need to tell anything,
>> because this mirred skb is almost not shared (except the refcount ;-).
> Btw, since there was ifb involved, I doubt this skb could hit ixgbe
> xmit before unsharing, and patching the driver could matter. Anyway,
> Changli, I guess, Pawel needs some instructions on this last patch?
>
> Jarek P.
>
>
With this patch:

diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index ca9036d..602cd32 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -6096,6 +6096,15 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
  	u32 mss_l4len_idx, l4len;

  	if (skb_is_gso(skb)) {
+		if (skb_shared(skb)) {
+			struct sk_buff *nskb;
+
+			nskb = skb_clone(skb, GFP_ATOMIC);
+			if (!nskb)
+				return -ENOMEM;
+			kfree_skb(skb);
+			skb = nskb;
+		}
  		if (skb_header_cloned(skb)) {
  			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
  			if (err)


I have the same panic as without.

This patch was added to clean 2.6.37-rc6 - without previous patch for 
sch_generic.h

Attached image with kernel panic.


Thanks
Pawel



[-- Attachment #2: panic-ixgbe-patch.JPG --]
[-- Type: image/jpeg, Size: 95991 bytes --]

^ permalink raw reply related

* Re: Kernel panic eth2 mirred redirect to ifb0
From: Jarek Poplawski @ 2010-12-20 12:22 UTC (permalink / raw)
  To: Paweł Staszewski
  Cc: Eric Dumazet, Changli Gao, David S. Miller,
	Linux Network Development list
In-Reply-To: <4D0F471D.8030607@itcare.pl>

On Mon, Dec 20, 2010 at 01:07:57PM +0100, Paweł Staszewski wrote:
> I have the same panic as without.
>
> This patch was added to clean 2.6.37-rc6 - without previous patch for  
> sch_generic.h
>
> Attached image with kernel panic.

This one is definitely the nicest ;-)

Thanks,
Jarek P.

^ permalink raw reply

* Re: Kernel panic eth2 mirred redirect to ifb0
From: Changli Gao @ 2010-12-20 12:30 UTC (permalink / raw)
  To: Paweł Staszewski
  Cc: Jarek Poplawski, Eric Dumazet, David S. Miller,
	Linux Network Development list
In-Reply-To: <4D0F471D.8030607@itcare.pl>

2010/12/20 Paweł Staszewski <pstaszewski@itcare.pl>:
> With this patch:
>
> diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
> index ca9036d..602cd32 100644
> --- a/drivers/net/ixgbe/ixgbe_main.c
> +++ b/drivers/net/ixgbe/ixgbe_main.c
> @@ -6096,6 +6096,15 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
>        u32 mss_l4len_idx, l4len;
>
>        if (skb_is_gso(skb)) {
> +               if (skb_shared(skb)) {
> +                       struct sk_buff *nskb;
> +
> +                       nskb = skb_clone(skb, GFP_ATOMIC);
> +                       if (!nskb)
> +                               return -ENOMEM;
> +                       kfree_skb(skb);
> +                       skb = nskb;
> +               }
>                if (skb_header_cloned(skb)) {
>                        err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
>                        if (err)
>
>
> I have the same panic as without.
>
> This patch was added to clean 2.6.37-rc6 - without previous patch for
> sch_generic.h
>
> Attached image with kernel panic.
>
>

Sigh. We have to revert my patch first. :(

-- 
Regards,
Changli Gao(xiaosuo@gmail.com)

^ permalink raw reply

* Re: Kernel panic eth2 mirred redirect to ifb0
From: Eric Dumazet @ 2010-12-20 12:45 UTC (permalink / raw)
  To: Jarek Poplawski
  Cc: Paweł Staszewski, Changli Gao, David S. Miller,
	Linux Network Development list
In-Reply-To: <20101220122256.GA9325@ff.dom.local>

Le lundi 20 décembre 2010 à 12:22 +0000, Jarek Poplawski a écrit :
> On Mon, Dec 20, 2010 at 01:07:57PM +0100, Paweł Staszewski wrote:
> > I have the same panic as without.
> >
> > This patch was added to clean 2.6.37-rc6 - without previous patch for  
> > sch_generic.h
> >
> > Attached image with kernel panic.
> 
> This one is definitely the nicest ;-)

Indeed, we finally can see where it happens ;)



^ permalink raw reply

* Re: Kernel panic eth2 mirred redirect to ifb0
From: Eric Dumazet @ 2010-12-20 12:54 UTC (permalink / raw)
  To: Jarek Poplawski
  Cc: Paweł Staszewski, Changli Gao, David S. Miller,
	Linux Network Development list
In-Reply-To: <1292849150.2800.25.camel@edumazet-laptop>

Le lundi 20 décembre 2010 à 13:45 +0100, Eric Dumazet a écrit :
> Le lundi 20 décembre 2010 à 12:22 +0000, Jarek Poplawski a écrit :
> > On Mon, Dec 20, 2010 at 01:07:57PM +0100, Paweł Staszewski wrote:
> > > I have the same panic as without.
> > >
> > > This patch was added to clean 2.6.37-rc6 - without previous patch for  
> > > sch_generic.h
> > >
> > > Attached image with kernel panic.
> > 
> > This one is definitely the nicest ;-)
> 
> Indeed, we finally can see where it happens ;)
> 

Shouldnt ifb adds some dev->features, like NETIF_F_FRAGLIST /
NETIF_F_SG ?



^ permalink raw reply

* [patch -next] typhoon: memory corruption in typhoon_get_drvinfo()
From: Dan Carpenter @ 2010-12-20 13:00 UTC (permalink / raw)
  To: David Dillow; +Cc: netdev, kernel-janitors

info->version only has space for 32 characters but my UTS_RELEASE is
"2.6.37-rc6-next-20101217-05817-ge935fc8-dirty" so it doesn't fit.
This is supposed to be the version of the driver, not the kernel
version.  This driver doesn't have a version so lets just leave it
blank.

Signed-off-by: Dan Carpenter <error27@gmail.com>
---
Found with static analysis.  Compile tested.

diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 5b83c3f..a3c46f6 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -1004,7 +1004,6 @@ typhoon_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 	}
 
 	strcpy(info->driver, KBUILD_MODNAME);
-	strcpy(info->version, UTS_RELEASE);
 	strcpy(info->bus_info, pci_name(pci_dev));
 }
 

^ permalink raw reply related

* Re: Kernel panic eth2 mirred redirect to ifb0
From: Jarek Poplawski @ 2010-12-20 13:02 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Paweł Staszewski, Changli Gao, David S. Miller,
	Linux Network Development list
In-Reply-To: <1292849687.2800.27.camel@edumazet-laptop>

On Mon, Dec 20, 2010 at 01:54:47PM +0100, Eric Dumazet wrote:
> Le lundi 20 décembre 2010 ?? 13:45 +0100, Eric Dumazet a écrit :
> > Le lundi 20 décembre 2010 ?? 12:22 +0000, Jarek Poplawski a écrit :
> > > On Mon, Dec 20, 2010 at 01:07:57PM +0100, Paweł Staszewski wrote:
> > > > I have the same panic as without.
> > > >
> > > > This patch was added to clean 2.6.37-rc6 - without previous patch for  
> > > > sch_generic.h
> > > >
> > > > Attached image with kernel panic.
> > > 
> > > This one is definitely the nicest ;-)
> > 
> > Indeed, we finally can see where it happens ;)
> > 
> 
> Shouldnt ifb adds some dev->features, like NETIF_F_FRAGLIST /
> NETIF_F_SG ?
> 

IMHO it should, (probably even more, like loopback) but we should
consider mirred can xmit to other than ifb too.

Jarek P.

^ permalink raw reply

* [patch -next] vmxnet3: locking problems in xmit
From: Dan Carpenter @ 2010-12-20 13:03 UTC (permalink / raw)
  To: Shreyas Bhatewara; +Cc: VMware, Inc., netdev, kernel-janitors

There were several paths that didn't release their locks.

Signed-off-by: Dan Carpenter <error27@gmail.com>

diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index 23154cf..939e546 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -980,7 +980,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
 		}
 	} else {
 		tq->stats.drop_hdr_inspect_err++;
-		goto drop_pkt;
+		goto unlock_drop_pkt;
 	}
 
 	/* fill tx descs related to addr & len */
@@ -1052,6 +1052,8 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
 
 hdr_too_big:
 	tq->stats.drop_oversized_hdr++;
+unlock_drop_pkt:
+	spin_unlock_irqrestore(&tq->tx_lock, flags);
 drop_pkt:
 	tq->stats.drop_total++;
 	dev_kfree_skb(skb);

^ permalink raw reply related

* Re: Kernel panic eth2 mirred redirect to ifb0
From: Jarek Poplawski @ 2010-12-20 13:37 UTC (permalink / raw)
  To: Changli Gao
  Cc: Paweł Staszewski, Eric Dumazet, David S. Miller,
	Linux Network Development list
In-Reply-To: <AANLkTinfMrktz2K99bvSf=VTkEw_V8iXOG1LEG+qWMWG@mail.gmail.com>

On Mon, Dec 20, 2010 at 08:30:39PM +0800, Changli Gao wrote:
> Sigh. We have to revert my patch first. :(

Yes, please, send the patch. And don't worry: I hope you'll find the
way to add it again ;-)

Cheers,
Jarek P.

^ permalink raw reply

* Re: [PATCH v4 net-next-2.6] netfilter: x_tables: dont block BH while reading counters
From: Jesper Dangaard Brouer @ 2010-12-20 13:42 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Patrick McHardy, netfilter-devel, netdev, Stephen Hemminger
In-Reply-To: <1292646579.7894.42.camel@edumazet-laptop>


I have tested the patch on 2.6.35.  Which implies I also needed to
cherry-pick 870f67dcf7ef, which implements the vzalloc() call. (Latest
net-next has a problem with my HP CCISS driver/controller or the PCI
layout, and will not boot)

According to the function_graph trace, the execution time of
get_counters() has increased (approx) from 109 ms to 120 ms, which is
the expected result.

The results are not all positive, but I think its related to the
debugging options I have enabled.

Because I now see packet drops if my 1Gbit/s pktgen script are sending
packet with a packet size below 512 bytes, which is "only" approx 230
kpps (this is 1Gbit/s on my 10G labsetup where I have seen 5 Mpps).

There is no packet overruns/drops, iif I run "iptables -vnL >
/dev/null" without tracing enabled and only 1Gbit/s pktgen at 512
bytes packets.  If I enable tracing while calling iptables I see
packet drops/overruns.  So I guess this is caused by the tracing
overhead.

I'll try to rerun my test without all the lock debugging options
enabled.

-- 
Med venlig hilsen / Best regards
  Jesper Brouer
  ComX Networks A/S
  Linux Network Kernel Developer
  Cand. Scient Datalog / MSc.CS
  Author of http://adsl-optimizer.dk
  LinkedIn: http://www.linkedin.com/in/brouer


On Sat, 2010-12-18 at 05:29 +0100, Eric Dumazet wrote:
> Using "iptables -L" with a lot of rules have a too big BH latency.
> Jesper mentioned ~6 ms and worried of frame drops.
> 
> Switch to a per_cpu seqlock scheme, so that taking a snapshot of
> counters doesnt need to block BH (for this cpu, but also other cpus).
> 
> This adds two increments on seqlock sequence per ipt_do_table() call,
> its a reasonable cost for allowing "iptables -L" not block BH
> processing.
> 
> Reported-by: Jesper Dangaard Brouer <hawk@comx.dk>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> Acked-by: Stephen Hemminger <shemminger@vyatta.com>
> ---



^ permalink raw reply

* Re: Kernel panic eth2 mirred redirect to ifb0
From: Changli Gao @ 2010-12-20 14:05 UTC (permalink / raw)
  To: Jarek Poplawski
  Cc: Eric Dumazet, Paweł Staszewski, David S. Miller,
	Linux Network Development list
In-Reply-To: <20101220130247.GB9325@ff.dom.local>

2010/12/20 Jarek Poplawski <jarkao2@gmail.com>:
>
> IMHO it should, (probably even more, like loopback) but we should
> consider mirred can xmit to other than ifb too.
>

I also think so. And when making ifb a multiqueue NIC, I tried to add
these dev features to ifb. :)

-- 
Regards,
Changli Gao(xiaosuo@gmail.com)

^ permalink raw reply

* [PATCH net-next-2.6] ifb: add performance flags to dev->features
From: Eric Dumazet @ 2010-12-20 14:25 UTC (permalink / raw)
  To: Changli Gao, David Miller
  Cc: Jarek Poplawski, Paweł Staszewski,
	Linux Network Development list
In-Reply-To: <AANLkTi=eqCWpFpHQ86_yO544p5G6J6P2os7rCR9FBtUd@mail.gmail.com>

Le lundi 20 décembre 2010 à 22:05 +0800, Changli Gao a écrit :
> 2010/12/20 Jarek Poplawski <jarkao2@gmail.com>:
> >
> > IMHO it should, (probably even more, like loopback) but we should
> > consider mirred can xmit to other than ifb too.
> >
> 
> I also think so. And when making ifb a multiqueue NIC, I tried to add
> these dev features to ifb. :)
> 

This has litle to do with your multiqueue work,
its more an effect of GRO being more and more deployed.

I dont see dev->features being changed in one of your previous patches.
I did dummy case in commit 6d81f41c58c6

[PATCH net-next-2.6] ifb: add performance flags to dev->features

IFB can use the full set of features flags (NETIF_F_SG |
NETIF_F_FRAGLIST | NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_HIGHDMA) to
avoid unecessary split of some packets (GRO for example)

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Changli Gao <xiaosuo@gmail.com>
Cc: Jarek Poplawski <jarkao2@gmail.com>
Cc: Pawel Staszewski <pstaszewski@itcare.pl>
---
 drivers/net/ifb.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index 124dac4..c761551 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -136,6 +136,9 @@ static void ifb_setup(struct net_device *dev)
 	ether_setup(dev);
 	dev->tx_queue_len = TX_Q_LIMIT;
 
+	dev->features |= NETIF_F_NO_CSUM | NETIF_F_SG |
+			 NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
+			 NETIF_F_TSO;
 	dev->flags |= IFF_NOARP;
 	dev->flags &= ~IFF_MULTICAST;
 	dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;



^ permalink raw reply related

* [PATCH net-2.6] net_sched: always clone skbs
From: Changli Gao @ 2010-12-20 14:35 UTC (permalink / raw)
  To: David S. Miller
  Cc: Jarek Poplawski, Eric Dumazet, netdev, Jamal Hadi Salim,
	Pawel Staszewski, Changli Gao

Pawel reported a panic related to handling shared skbs in ixgbe
incorrectly. So we need to revert my previous patch to work around
this bug. Instead of reverting the patch completely, I just revert
the essential lines, so we can add the previous optimization
back more easily in future.

    commit 3511c9132f8b1e1b5634e41a3331c44b0c13be70
    Author: Changli Gao <xiaosuo@gmail.com>
    Date:   Sat Oct 16 13:04:08 2010 +0000
    
        net_sched: remove the unused parameter of qdisc_create_dflt()

Reported-by: Pawel Staszewski <pstaszewski@itcare.pl>
Signed-off-by: Changli Gao <xiaosuo@gmail.com>
---
 include/net/sch_generic.h |    6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 786cc39..0af57eb 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -611,11 +611,7 @@ static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask,
 {
 	struct sk_buff *n;
 
-	if ((action == TC_ACT_STOLEN || action == TC_ACT_QUEUED) &&
-	    !skb_shared(skb))
-		n = skb_get(skb);
-	else
-		n = skb_clone(skb, gfp_mask);
+	n = skb_clone(skb, gfp_mask);
 
 	if (n) {
 		n->tc_verd = SET_TC_VERD(n->tc_verd, 0);

^ permalink raw reply related

* Re: [PATCH 11/12] nfs: introduce mount option 'rpcmount'
From: J. Bruce Fields @ 2010-12-20 14:37 UTC (permalink / raw)
  To: Kirill A. Shutsemov
  Cc: Trond Myklebust, Neil Brown, Pavel Emelyanov,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA, David S. Miller,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1292846078-31793-12-git-send-email-kirill-oKw7cIdHH8eLwutG50LtGA@public.gmane.org>

On Mon, Dec 20, 2010 at 01:54:37PM +0200, Kirill A. Shutsemov wrote:
> From: Kirill A. Shutemov <kirill-oKw7cIdHH8eLwutG50LtGA@public.gmane.org>
> 
> It specifies rpc_pipefs to use. init_rpc_pipefs, by default.

You also need to export get_rpc_pipefs() for the nfs module to use.

--b.

> 
> Signed-off-by: Kirill A. Shutemov <kirill-oKw7cIdHH8eLwutG50LtGA@public.gmane.org>
> ---
>  fs/nfs/callback.c         |    6 ++--
>  fs/nfs/callback.h         |    3 +-
>  fs/nfs/client.c           |   46 ++++++++++++++++++++++++++++++++++++--------
>  fs/nfs/internal.h         |   10 +++++++-
>  fs/nfs/mount_clnt.c       |    3 +-
>  fs/nfs/namespace.c        |    3 +-
>  fs/nfs/nfs4namespace.c    |   22 +++++++++++---------
>  fs/nfs/super.c            |   20 +++++++++++++++++++
>  include/linux/nfs_fs_sb.h |    1 +
>  9 files changed, 86 insertions(+), 28 deletions(-)
> 
> diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
> index bef6abd..ef6d206 100644
> --- a/fs/nfs/callback.c
> +++ b/fs/nfs/callback.c
> @@ -16,7 +16,6 @@
>  #include <linux/freezer.h>
>  #include <linux/kthread.h>
>  #include <linux/sunrpc/svcauth_gss.h>
> -#include <linux/sunrpc/rpc_pipe_fs.h>
>  #if defined(CONFIG_NFS_V4_1)
>  #include <linux/sunrpc/bc_xprt.h>
>  #endif
> @@ -239,7 +238,8 @@ static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt,
>  /*
>   * Bring up the callback thread if it is not already up.
>   */
> -int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
> +int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt,
> +		struct vfsmount *rpcmount)
>  {
>  	struct svc_serv *serv = NULL;
>  	struct svc_rqst *rqstp;
> @@ -254,7 +254,7 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
>  		nfs_callback_bc_serv(minorversion, xprt, cb_info);
>  		goto out;
>  	}
> -	serv = svc_create(&nfs4_callback_program, init_rpc_pipefs,
> +	serv = svc_create(&nfs4_callback_program, rpcmount,
>  			NFS4_CALLBACK_BUFSIZE, NULL);
>  	if (!serv) {
>  		ret = -ENOMEM;
> diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
> index 85a7cfd..ae27385 100644
> --- a/fs/nfs/callback.h
> +++ b/fs/nfs/callback.h
> @@ -133,7 +133,8 @@ extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getat
>  extern __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy);
>  
>  #ifdef CONFIG_NFS_V4
> -extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt);
> +extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt,
> +		struct vfsmount *rpcmount);
>  extern void nfs_callback_down(int minorversion);
>  extern int nfs4_validate_delegation_stateid(struct nfs_delegation *delegation,
>  					    const nfs4_stateid *stateid);
> diff --git a/fs/nfs/client.c b/fs/nfs/client.c
> index fbc013d..ccc400a 100644
> --- a/fs/nfs/client.c
> +++ b/fs/nfs/client.c
> @@ -107,6 +107,7 @@ struct nfs_client_initdata {
>  	const struct nfs_rpc_ops *rpc_ops;
>  	int proto;
>  	u32 minorversion;
> +	struct vfsmount *rpcmount;
>  };
>  
>  /*
> @@ -143,6 +144,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
>  	clp->cl_rpcclient = ERR_PTR(-EINVAL);
>  
>  	clp->cl_proto = cl_init->proto;
> +	clp->cl_rpcmount = mntget(cl_init->rpcmount);
>  
>  #ifdef CONFIG_NFS_V4
>  	INIT_LIST_HEAD(&clp->cl_delegations);
> @@ -231,6 +233,7 @@ static void nfs_free_client(struct nfs_client *clp)
>  	if (clp->cl_machine_cred != NULL)
>  		put_rpccred(clp->cl_machine_cred);
>  
> +	mntput(clp->cl_rpcmount);
>  	kfree(clp->cl_hostname);
>  	kfree(clp);
>  
> @@ -457,6 +460,9 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
>  		/* Match the full socket address */
>  		if (!nfs_sockaddr_cmp(sap, clap))
>  			continue;
> +		/* Match rpc_pipefs mount point */
> +		if (clp->cl_rpcmount->mnt_sb != data->rpcmount->mnt_sb)
> +			continue;
>  
>  		atomic_inc(&clp->cl_count);
>  		return clp;
> @@ -615,7 +621,7 @@ static int nfs_create_rpc_client(struct nfs_client *clp,
>  		.program	= &nfs_program,
>  		.version	= clp->rpc_ops->version,
>  		.authflavor	= flavor,
> -		.rpcmount	= init_rpc_pipefs,
> +		.rpcmount	= clp->cl_rpcmount,
>  	};
>  
>  	if (discrtry)
> @@ -650,7 +656,7 @@ static void nfs_destroy_server(struct nfs_server *server)
>  /*
>   * Version 2 or 3 lockd setup
>   */
> -static int nfs_start_lockd(struct nfs_server *server)
> +static int nfs_start_lockd(struct nfs_server *server, struct vfsmount *rpcmount)
>  {
>  	struct nlm_host *host;
>  	struct nfs_client *clp = server->nfs_client;
> @@ -661,7 +667,7 @@ static int nfs_start_lockd(struct nfs_server *server)
>  		.nfs_version	= clp->rpc_ops->version,
>  		.noresvport	= server->flags & NFS_MOUNT_NORESVPORT ?
>  					1 : 0,
> -		.rpcmount	= init_rpc_pipefs,
> +		.rpcmount	= rpcmount,
>  	};
>  
>  	if (nlm_init.nfs_version > 3)
> @@ -809,8 +815,16 @@ static int nfs_init_server(struct nfs_server *server,
>  		cl_init.rpc_ops = &nfs_v3_clientops;
>  #endif
>  
> +	cl_init.rpcmount = get_rpc_pipefs(data->rpcmount);
> +	if (IS_ERR(cl_init.rpcmount)) {
> +		dprintk("<-- nfs_init_server() = error %ld\n",
> +				PTR_ERR(cl_init.rpcmount));
> +		return PTR_ERR(cl_init.rpcmount);
> +	}
> +
>  	/* Allocate or find a client reference we can use */
>  	clp = nfs_get_client(&cl_init);
> +	mntput(cl_init.rpcmount);
>  	if (IS_ERR(clp)) {
>  		dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp));
>  		return PTR_ERR(clp);
> @@ -842,7 +856,7 @@ static int nfs_init_server(struct nfs_server *server,
>  	server->acdirmax = data->acdirmax * HZ;
>  
>  	/* Start lockd here, before we might error out */
> -	error = nfs_start_lockd(server);
> +	error = nfs_start_lockd(server, clp->cl_rpcmount);
>  	if (error < 0)
>  		goto error;
>  
> @@ -1144,7 +1158,8 @@ static int nfs4_init_callback(struct nfs_client *clp)
>  		}
>  
>  		error = nfs_callback_up(clp->cl_mvops->minor_version,
> -					clp->cl_rpcclient->cl_xprt);
> +					clp->cl_rpcclient->cl_xprt,
> +					clp->cl_rpcmount);
>  		if (error < 0) {
>  			dprintk("%s: failed to start callback. Error = %d\n",
>  				__func__, error);
> @@ -1244,7 +1259,8 @@ static int nfs4_set_client(struct nfs_server *server,
>  		const char *ip_addr,
>  		rpc_authflavor_t authflavour,
>  		int proto, const struct rpc_timeout *timeparms,
> -		u32 minorversion)
> +		u32 minorversion,
> +		struct vfsmount *rpcmount)
>  {
>  	struct nfs_client_initdata cl_init = {
>  		.hostname = hostname,
> @@ -1253,6 +1269,7 @@ static int nfs4_set_client(struct nfs_server *server,
>  		.rpc_ops = &nfs_v4_clientops,
>  		.proto = proto,
>  		.minorversion = minorversion,
> +		.rpcmount = rpcmount,
>  	};
>  	struct nfs_client *clp;
>  	int error;
> @@ -1363,6 +1380,7 @@ static int nfs4_init_server(struct nfs_server *server,
>  		const struct nfs_parsed_mount_data *data)
>  {
>  	struct rpc_timeout timeparms;
> +	struct vfsmount *rpcmount;
>  	int error;
>  
>  	dprintk("--> nfs4_init_server()\n");
> @@ -1377,6 +1395,11 @@ static int nfs4_init_server(struct nfs_server *server,
>  			server->caps |= NFS_CAP_READDIRPLUS;
>  	server->options = data->options;
>  
> +	rpcmount = get_rpc_pipefs(data->rpcmount);
> +	if (IS_ERR(rpcmount)) {
> +		error = PTR_ERR(rpcmount);
> +		goto error;
> +	}
>  	/* Get a client record */
>  	error = nfs4_set_client(server,
>  			data->nfs_server.hostname,
> @@ -1386,7 +1409,9 @@ static int nfs4_init_server(struct nfs_server *server,
>  			data->auth_flavors[0],
>  			data->nfs_server.protocol,
>  			&timeparms,
> -			data->minorversion);
> +			data->minorversion,
> +			rpcmount);
> +	mntput(rpcmount);
>  	if (error < 0)
>  		goto error;
>  
> @@ -1476,7 +1501,10 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
>  				data->authflavor,
>  				parent_server->client->cl_xprt->prot,
>  				parent_server->client->cl_timeout,
> -				parent_client->cl_mvops->minor_version);
> +				parent_client->cl_mvops->minor_version,
> +				parent_client->cl_rpcmount);
> +
> +
>  	if (error < 0)
>  		goto error;
>  
> @@ -1550,7 +1578,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
>  		(unsigned long long) server->fsid.major,
>  		(unsigned long long) server->fsid.minor);
>  
> -	error = nfs_start_lockd(server);
> +	error = nfs_start_lockd(server, server->nfs_client->cl_rpcmount);
>  	if (error < 0)
>  		goto out_free_server;
>  
> diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
> index e6356b7..cb31fd9 100644
> --- a/fs/nfs/internal.h
> +++ b/fs/nfs/internal.h
> @@ -86,6 +86,7 @@ struct nfs_parsed_mount_data {
>  	unsigned int		version;
>  	unsigned int		minorversion;
>  	char			*fscache_uniq;
> +	char			*rpcmount;
>  
>  	struct {
>  		struct sockaddr_storage	address;
> @@ -120,6 +121,7 @@ struct nfs_mount_request {
>  	int			noresvport;
>  	unsigned int		*auth_flav_len;
>  	rpc_authflavor_t	*auth_flavs;
> +	struct vfsmount		*rpcmount;
>  };
>  
>  extern int nfs_mount(struct nfs_mount_request *info);
> @@ -160,10 +162,14 @@ static inline void nfs_fs_proc_exit(void)
>  
>  /* nfs4namespace.c */
>  #ifdef CONFIG_NFS_V4
> -extern struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry);
> +extern struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent,
> +		struct dentry *dentry,
> +		struct vfsmount *rpcmount);
>  #else
>  static inline
> -struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry)
> +struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent,
> +		struct dentry *dentry,
> +		struct vfsmount *rpcmount)
>  {
>  	return ERR_PTR(-ENOENT);
>  }
> diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
> index 67b4b8d..9fd4157 100644
> --- a/fs/nfs/mount_clnt.c
> +++ b/fs/nfs/mount_clnt.c
> @@ -13,7 +13,6 @@
>  #include <linux/in.h>
>  #include <linux/sunrpc/clnt.h>
>  #include <linux/sunrpc/sched.h>
> -#include <linux/sunrpc/rpc_pipe_fs.h>
>  #include <linux/nfs_fs.h>
>  #include "internal.h"
>  
> @@ -162,7 +161,7 @@ int nfs_mount(struct nfs_mount_request *info)
>  		.program	= &mnt_program,
>  		.version	= info->version,
>  		.authflavor	= RPC_AUTH_UNIX,
> -		.rpcmount	= init_rpc_pipefs,
> +		.rpcmount	= info->rpcmount,
>  	};
>  	struct rpc_clnt		*mnt_clnt;
>  	int			status;
> diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
> index db6aa36..d47f6f5 100644
> --- a/fs/nfs/namespace.c
> +++ b/fs/nfs/namespace.c
> @@ -135,7 +135,8 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
>  		goto out_err;
>  
>  	if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL)
> -		mnt = nfs_do_refmount(nd->path.mnt, nd->path.dentry);
> +		mnt = nfs_do_refmount(nd->path.mnt, nd->path.dentry,
> +				server->nfs_client->cl_rpcmount);
>  	else
>  		mnt = nfs_do_submount(nd->path.mnt, nd->path.dentry, fh,
>  				      fattr);
> diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
> index 7a61fdb..92d5d63 100644
> --- a/fs/nfs/nfs4namespace.c
> +++ b/fs/nfs/nfs4namespace.c
> @@ -14,7 +14,6 @@
>  #include <linux/slab.h>
>  #include <linux/string.h>
>  #include <linux/sunrpc/clnt.h>
> -#include <linux/sunrpc/rpc_pipe_fs.h>
>  #include <linux/vfs.h>
>  #include <linux/inet.h>
>  #include "internal.h"
> @@ -99,14 +98,13 @@ static int nfs4_validate_fspath(const struct vfsmount *mnt_parent,
>  }
>  
>  static size_t nfs_parse_server_name(char *string, size_t len,
> -		struct sockaddr *sa, size_t salen)
> +		struct sockaddr *sa, size_t salen, struct vfsmount *rpcmount)
>  {
>  	ssize_t ret;
>  
>  	ret = rpc_pton(string, len, sa, salen);
>  	if (ret == 0) {
> -		ret = nfs_dns_resolve_name(string, len, sa, salen,
> -				init_rpc_pipefs);
> +		ret = nfs_dns_resolve_name(string, len, sa, salen, rpcmount);
>  		if (ret < 0)
>  			ret = 0;
>  	}
> @@ -115,7 +113,8 @@ static size_t nfs_parse_server_name(char *string, size_t len,
>  
>  static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
>  				     char *page, char *page2,
> -				     const struct nfs4_fs_location *location)
> +				     const struct nfs4_fs_location *location,
> +				     struct vfsmount *rpcmount)
>  {
>  	const size_t addr_bufsize = sizeof(struct sockaddr_storage);
>  	struct vfsmount *mnt = ERR_PTR(-ENOENT);
> @@ -143,7 +142,7 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
>  			continue;
>  
>  		mountdata->addrlen = nfs_parse_server_name(buf->data, buf->len,
> -				mountdata->addr, addr_bufsize);
> +				mountdata->addr, addr_bufsize, rpcmount);
>  		if (mountdata->addrlen == 0)
>  			continue;
>  
> @@ -174,7 +173,8 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
>   */
>  static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
>  					    const struct dentry *dentry,
> -					    const struct nfs4_fs_locations *locations)
> +					    const struct nfs4_fs_locations *locations,
> +					    struct vfsmount *rpcmount)
>  {
>  	struct vfsmount *mnt = ERR_PTR(-ENOENT);
>  	struct nfs_clone_mount mountdata = {
> @@ -213,7 +213,7 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
>  		    location->rootpath.ncomponents == 0)
>  			continue;
>  
> -		mnt = try_location(&mountdata, page, page2, location);
> +		mnt = try_location(&mountdata, page, page2, location, rpcmount);
>  		if (!IS_ERR(mnt))
>  			break;
>  	}
> @@ -231,7 +231,9 @@ out:
>   * @dentry - dentry of referral
>   *
>   */
> -struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry)
> +struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent,
> +		struct dentry *dentry,
> +		struct vfsmount *rpcmount)
>  {
>  	struct vfsmount *mnt = ERR_PTR(-ENOMEM);
>  	struct dentry *parent;
> @@ -264,7 +266,7 @@ struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentr
>  	    fs_locations->fs_path.ncomponents <= 0)
>  		goto out_free;
>  
> -	mnt = nfs_follow_referral(mnt_parent, dentry, fs_locations);
> +	mnt = nfs_follow_referral(mnt_parent, dentry, fs_locations, rpcmount);
>  out_free:
>  	__free_page(page);
>  	kfree(fs_locations);
> diff --git a/fs/nfs/super.c b/fs/nfs/super.c
> index 4100630..32b7e35 100644
> --- a/fs/nfs/super.c
> +++ b/fs/nfs/super.c
> @@ -35,6 +35,7 @@
>  #include <linux/sunrpc/metrics.h>
>  #include <linux/sunrpc/xprtsock.h>
>  #include <linux/sunrpc/xprtrdma.h>
> +#include <linux/sunrpc/rpc_pipe_fs.h>
>  #include <linux/nfs_fs.h>
>  #include <linux/nfs_mount.h>
>  #include <linux/nfs4_mount.h>
> @@ -106,6 +107,7 @@ enum {
>  	Opt_lookupcache,
>  	Opt_fscache_uniq,
>  	Opt_local_lock,
> +	Opt_rpcmount,
>  
>  	/* Special mount options */
>  	Opt_userspace, Opt_deprecated, Opt_sloppy,
> @@ -178,6 +180,7 @@ static const match_table_t nfs_mount_option_tokens = {
>  	{ Opt_lookupcache, "lookupcache=%s" },
>  	{ Opt_fscache_uniq, "fsc=%s" },
>  	{ Opt_local_lock, "local_lock=%s" },
> +	{ Opt_rpcmount, "rpcmount=%s" },
>  
>  	{ Opt_err, NULL }
>  };
> @@ -1484,6 +1487,13 @@ static int nfs_parse_mount_options(char *raw,
>  				return 0;
>  			};
>  			break;
> +		case Opt_rpcmount:
> +			string = match_strdup(args);
> +			if (string == NULL)
> +				goto out_nomem;
> +			kfree(mnt->rpcmount);
> +			mnt->rpcmount = string;
> +			break;
>  
>  		/*
>  		 * Special options
> @@ -1644,11 +1654,19 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
>  	request.salen = args->mount_server.addrlen;
>  	nfs_set_port(request.sap, &args->mount_server.port, 0);
>  
> +	request.rpcmount = get_rpc_pipefs(args->rpcmount);
> +	if (IS_ERR(request.rpcmount)) {
> +		dfprintk(MOUNT,	"NFS: unable get rpc_pipefs mount point, "
> +				"error %ld\n", PTR_ERR(request.rpcmount));
> +		return PTR_ERR(request.rpcmount);
> +	}
> +
>  	/*
>  	 * Now ask the mount server to map our export path
>  	 * to a file handle.
>  	 */
>  	status = nfs_mount(&request);
> +	mntput(request.rpcmount);
>  	if (status != 0) {
>  		dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n",
>  				request.hostname, status);
> @@ -2352,6 +2370,7 @@ out:
>  	kfree(data->nfs_server.hostname);
>  	kfree(data->mount_server.hostname);
>  	kfree(data->fscache_uniq);
> +	kfree(data->rpcmount);
>  	security_free_mnt_opts(&data->lsm_opts);
>  out_free_fh:
>  	nfs_free_fhandle(mntfh);
> @@ -2947,6 +2966,7 @@ out:
>  	kfree(data->nfs_server.export_path);
>  	kfree(data->nfs_server.hostname);
>  	kfree(data->fscache_uniq);
> +	kfree(data->rpcmount);
>  out_free_data:
>  	kfree(data);
>  	dprintk("<-- nfs4_get_sb() = %d%s\n", error,
> diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
> index 452d964..ee417c9 100644
> --- a/include/linux/nfs_fs_sb.h
> +++ b/include/linux/nfs_fs_sb.h
> @@ -36,6 +36,7 @@ struct nfs_client {
>  	struct list_head	cl_share_link;	/* link in global client list */
>  	struct list_head	cl_superblocks;	/* List of nfs_server structs */
>  
> +	struct vfsmount		*cl_rpcmount;	/* rpc_pipefs mount point */
>  	struct rpc_clnt *	cl_rpcclient;
>  	const struct nfs_rpc_ops *rpc_ops;	/* NFS protocol vector */
>  	int			cl_proto;	/* Network transport protocol */
> -- 
> 1.7.3.4
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH net-2.6] net_sched: always clone skbs
From: Eric Dumazet @ 2010-12-20 14:37 UTC (permalink / raw)
  To: Changli Gao
  Cc: David S. Miller, Jarek Poplawski, netdev, Jamal Hadi Salim,
	Pawel Staszewski
In-Reply-To: <1292855730-19265-1-git-send-email-xiaosuo@gmail.com>

Le lundi 20 décembre 2010 à 22:35 +0800, Changli Gao a écrit :
> Pawel reported a panic related to handling shared skbs in ixgbe
> incorrectly. So we need to revert my previous patch to work around
> this bug. Instead of reverting the patch completely, I just revert
> the essential lines, so we can add the previous optimization
> back more easily in future.
> 
>     commit 3511c9132f8b1e1b5634e41a3331c44b0c13be70
>     Author: Changli Gao <xiaosuo@gmail.com>
>     Date:   Sat Oct 16 13:04:08 2010 +0000
>     
>         net_sched: remove the unused parameter of qdisc_create_dflt()
> 
> Reported-by: Pawel Staszewski <pstaszewski@itcare.pl>
> Signed-off-by: Changli Gao <xiaosuo@gmail.com>

Acked-by: Eric Dumazet <eric.dumazet@gmail.com>




^ permalink raw reply

* Re: [PATCH 11/12] nfs: introduce mount option 'rpcmount'
From: Kirill A. Shutemov @ 2010-12-20 14:38 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: Trond Myklebust, Neil Brown, Pavel Emelyanov, linux-nfs,
	David S. Miller, netdev, linux-kernel
In-Reply-To: <20101220143703.GB20643@fieldses.org>

On Mon, Dec 20, 2010 at 09:37:03AM -0500, J. Bruce Fields wrote:
> On Mon, Dec 20, 2010 at 01:54:37PM +0200, Kirill A. Shutsemov wrote:
> > From: Kirill A. Shutemov <kirill@shutemov.name>
> > 
> > It specifies rpc_pipefs to use. init_rpc_pipefs, by default.
> 
> You also need to export get_rpc_pipefs() for the nfs module to use.

Oh, sure. Thanks.

> 
> --b.
> 
> > 
> > Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
> > ---
> >  fs/nfs/callback.c         |    6 ++--
> >  fs/nfs/callback.h         |    3 +-
> >  fs/nfs/client.c           |   46 ++++++++++++++++++++++++++++++++++++--------
> >  fs/nfs/internal.h         |   10 +++++++-
> >  fs/nfs/mount_clnt.c       |    3 +-
> >  fs/nfs/namespace.c        |    3 +-
> >  fs/nfs/nfs4namespace.c    |   22 +++++++++++---------
> >  fs/nfs/super.c            |   20 +++++++++++++++++++
> >  include/linux/nfs_fs_sb.h |    1 +
> >  9 files changed, 86 insertions(+), 28 deletions(-)
> > 
> > diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
> > index bef6abd..ef6d206 100644
> > --- a/fs/nfs/callback.c
> > +++ b/fs/nfs/callback.c
> > @@ -16,7 +16,6 @@
> >  #include <linux/freezer.h>
> >  #include <linux/kthread.h>
> >  #include <linux/sunrpc/svcauth_gss.h>
> > -#include <linux/sunrpc/rpc_pipe_fs.h>
> >  #if defined(CONFIG_NFS_V4_1)
> >  #include <linux/sunrpc/bc_xprt.h>
> >  #endif
> > @@ -239,7 +238,8 @@ static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt,
> >  /*
> >   * Bring up the callback thread if it is not already up.
> >   */
> > -int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
> > +int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt,
> > +		struct vfsmount *rpcmount)
> >  {
> >  	struct svc_serv *serv = NULL;
> >  	struct svc_rqst *rqstp;
> > @@ -254,7 +254,7 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
> >  		nfs_callback_bc_serv(minorversion, xprt, cb_info);
> >  		goto out;
> >  	}
> > -	serv = svc_create(&nfs4_callback_program, init_rpc_pipefs,
> > +	serv = svc_create(&nfs4_callback_program, rpcmount,
> >  			NFS4_CALLBACK_BUFSIZE, NULL);
> >  	if (!serv) {
> >  		ret = -ENOMEM;
> > diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
> > index 85a7cfd..ae27385 100644
> > --- a/fs/nfs/callback.h
> > +++ b/fs/nfs/callback.h
> > @@ -133,7 +133,8 @@ extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getat
> >  extern __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy);
> >  
> >  #ifdef CONFIG_NFS_V4
> > -extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt);
> > +extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt,
> > +		struct vfsmount *rpcmount);
> >  extern void nfs_callback_down(int minorversion);
> >  extern int nfs4_validate_delegation_stateid(struct nfs_delegation *delegation,
> >  					    const nfs4_stateid *stateid);
> > diff --git a/fs/nfs/client.c b/fs/nfs/client.c
> > index fbc013d..ccc400a 100644
> > --- a/fs/nfs/client.c
> > +++ b/fs/nfs/client.c
> > @@ -107,6 +107,7 @@ struct nfs_client_initdata {
> >  	const struct nfs_rpc_ops *rpc_ops;
> >  	int proto;
> >  	u32 minorversion;
> > +	struct vfsmount *rpcmount;
> >  };
> >  
> >  /*
> > @@ -143,6 +144,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
> >  	clp->cl_rpcclient = ERR_PTR(-EINVAL);
> >  
> >  	clp->cl_proto = cl_init->proto;
> > +	clp->cl_rpcmount = mntget(cl_init->rpcmount);
> >  
> >  #ifdef CONFIG_NFS_V4
> >  	INIT_LIST_HEAD(&clp->cl_delegations);
> > @@ -231,6 +233,7 @@ static void nfs_free_client(struct nfs_client *clp)
> >  	if (clp->cl_machine_cred != NULL)
> >  		put_rpccred(clp->cl_machine_cred);
> >  
> > +	mntput(clp->cl_rpcmount);
> >  	kfree(clp->cl_hostname);
> >  	kfree(clp);
> >  
> > @@ -457,6 +460,9 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
> >  		/* Match the full socket address */
> >  		if (!nfs_sockaddr_cmp(sap, clap))
> >  			continue;
> > +		/* Match rpc_pipefs mount point */
> > +		if (clp->cl_rpcmount->mnt_sb != data->rpcmount->mnt_sb)
> > +			continue;
> >  
> >  		atomic_inc(&clp->cl_count);
> >  		return clp;
> > @@ -615,7 +621,7 @@ static int nfs_create_rpc_client(struct nfs_client *clp,
> >  		.program	= &nfs_program,
> >  		.version	= clp->rpc_ops->version,
> >  		.authflavor	= flavor,
> > -		.rpcmount	= init_rpc_pipefs,
> > +		.rpcmount	= clp->cl_rpcmount,
> >  	};
> >  
> >  	if (discrtry)
> > @@ -650,7 +656,7 @@ static void nfs_destroy_server(struct nfs_server *server)
> >  /*
> >   * Version 2 or 3 lockd setup
> >   */
> > -static int nfs_start_lockd(struct nfs_server *server)
> > +static int nfs_start_lockd(struct nfs_server *server, struct vfsmount *rpcmount)
> >  {
> >  	struct nlm_host *host;
> >  	struct nfs_client *clp = server->nfs_client;
> > @@ -661,7 +667,7 @@ static int nfs_start_lockd(struct nfs_server *server)
> >  		.nfs_version	= clp->rpc_ops->version,
> >  		.noresvport	= server->flags & NFS_MOUNT_NORESVPORT ?
> >  					1 : 0,
> > -		.rpcmount	= init_rpc_pipefs,
> > +		.rpcmount	= rpcmount,
> >  	};
> >  
> >  	if (nlm_init.nfs_version > 3)
> > @@ -809,8 +815,16 @@ static int nfs_init_server(struct nfs_server *server,
> >  		cl_init.rpc_ops = &nfs_v3_clientops;
> >  #endif
> >  
> > +	cl_init.rpcmount = get_rpc_pipefs(data->rpcmount);
> > +	if (IS_ERR(cl_init.rpcmount)) {
> > +		dprintk("<-- nfs_init_server() = error %ld\n",
> > +				PTR_ERR(cl_init.rpcmount));
> > +		return PTR_ERR(cl_init.rpcmount);
> > +	}
> > +
> >  	/* Allocate or find a client reference we can use */
> >  	clp = nfs_get_client(&cl_init);
> > +	mntput(cl_init.rpcmount);
> >  	if (IS_ERR(clp)) {
> >  		dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp));
> >  		return PTR_ERR(clp);
> > @@ -842,7 +856,7 @@ static int nfs_init_server(struct nfs_server *server,
> >  	server->acdirmax = data->acdirmax * HZ;
> >  
> >  	/* Start lockd here, before we might error out */
> > -	error = nfs_start_lockd(server);
> > +	error = nfs_start_lockd(server, clp->cl_rpcmount);
> >  	if (error < 0)
> >  		goto error;
> >  
> > @@ -1144,7 +1158,8 @@ static int nfs4_init_callback(struct nfs_client *clp)
> >  		}
> >  
> >  		error = nfs_callback_up(clp->cl_mvops->minor_version,
> > -					clp->cl_rpcclient->cl_xprt);
> > +					clp->cl_rpcclient->cl_xprt,
> > +					clp->cl_rpcmount);
> >  		if (error < 0) {
> >  			dprintk("%s: failed to start callback. Error = %d\n",
> >  				__func__, error);
> > @@ -1244,7 +1259,8 @@ static int nfs4_set_client(struct nfs_server *server,
> >  		const char *ip_addr,
> >  		rpc_authflavor_t authflavour,
> >  		int proto, const struct rpc_timeout *timeparms,
> > -		u32 minorversion)
> > +		u32 minorversion,
> > +		struct vfsmount *rpcmount)
> >  {
> >  	struct nfs_client_initdata cl_init = {
> >  		.hostname = hostname,
> > @@ -1253,6 +1269,7 @@ static int nfs4_set_client(struct nfs_server *server,
> >  		.rpc_ops = &nfs_v4_clientops,
> >  		.proto = proto,
> >  		.minorversion = minorversion,
> > +		.rpcmount = rpcmount,
> >  	};
> >  	struct nfs_client *clp;
> >  	int error;
> > @@ -1363,6 +1380,7 @@ static int nfs4_init_server(struct nfs_server *server,
> >  		const struct nfs_parsed_mount_data *data)
> >  {
> >  	struct rpc_timeout timeparms;
> > +	struct vfsmount *rpcmount;
> >  	int error;
> >  
> >  	dprintk("--> nfs4_init_server()\n");
> > @@ -1377,6 +1395,11 @@ static int nfs4_init_server(struct nfs_server *server,
> >  			server->caps |= NFS_CAP_READDIRPLUS;
> >  	server->options = data->options;
> >  
> > +	rpcmount = get_rpc_pipefs(data->rpcmount);
> > +	if (IS_ERR(rpcmount)) {
> > +		error = PTR_ERR(rpcmount);
> > +		goto error;
> > +	}
> >  	/* Get a client record */
> >  	error = nfs4_set_client(server,
> >  			data->nfs_server.hostname,
> > @@ -1386,7 +1409,9 @@ static int nfs4_init_server(struct nfs_server *server,
> >  			data->auth_flavors[0],
> >  			data->nfs_server.protocol,
> >  			&timeparms,
> > -			data->minorversion);
> > +			data->minorversion,
> > +			rpcmount);
> > +	mntput(rpcmount);
> >  	if (error < 0)
> >  		goto error;
> >  
> > @@ -1476,7 +1501,10 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
> >  				data->authflavor,
> >  				parent_server->client->cl_xprt->prot,
> >  				parent_server->client->cl_timeout,
> > -				parent_client->cl_mvops->minor_version);
> > +				parent_client->cl_mvops->minor_version,
> > +				parent_client->cl_rpcmount);
> > +
> > +
> >  	if (error < 0)
> >  		goto error;
> >  
> > @@ -1550,7 +1578,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
> >  		(unsigned long long) server->fsid.major,
> >  		(unsigned long long) server->fsid.minor);
> >  
> > -	error = nfs_start_lockd(server);
> > +	error = nfs_start_lockd(server, server->nfs_client->cl_rpcmount);
> >  	if (error < 0)
> >  		goto out_free_server;
> >  
> > diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
> > index e6356b7..cb31fd9 100644
> > --- a/fs/nfs/internal.h
> > +++ b/fs/nfs/internal.h
> > @@ -86,6 +86,7 @@ struct nfs_parsed_mount_data {
> >  	unsigned int		version;
> >  	unsigned int		minorversion;
> >  	char			*fscache_uniq;
> > +	char			*rpcmount;
> >  
> >  	struct {
> >  		struct sockaddr_storage	address;
> > @@ -120,6 +121,7 @@ struct nfs_mount_request {
> >  	int			noresvport;
> >  	unsigned int		*auth_flav_len;
> >  	rpc_authflavor_t	*auth_flavs;
> > +	struct vfsmount		*rpcmount;
> >  };
> >  
> >  extern int nfs_mount(struct nfs_mount_request *info);
> > @@ -160,10 +162,14 @@ static inline void nfs_fs_proc_exit(void)
> >  
> >  /* nfs4namespace.c */
> >  #ifdef CONFIG_NFS_V4
> > -extern struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry);
> > +extern struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent,
> > +		struct dentry *dentry,
> > +		struct vfsmount *rpcmount);
> >  #else
> >  static inline
> > -struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry)
> > +struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent,
> > +		struct dentry *dentry,
> > +		struct vfsmount *rpcmount)
> >  {
> >  	return ERR_PTR(-ENOENT);
> >  }
> > diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
> > index 67b4b8d..9fd4157 100644
> > --- a/fs/nfs/mount_clnt.c
> > +++ b/fs/nfs/mount_clnt.c
> > @@ -13,7 +13,6 @@
> >  #include <linux/in.h>
> >  #include <linux/sunrpc/clnt.h>
> >  #include <linux/sunrpc/sched.h>
> > -#include <linux/sunrpc/rpc_pipe_fs.h>
> >  #include <linux/nfs_fs.h>
> >  #include "internal.h"
> >  
> > @@ -162,7 +161,7 @@ int nfs_mount(struct nfs_mount_request *info)
> >  		.program	= &mnt_program,
> >  		.version	= info->version,
> >  		.authflavor	= RPC_AUTH_UNIX,
> > -		.rpcmount	= init_rpc_pipefs,
> > +		.rpcmount	= info->rpcmount,
> >  	};
> >  	struct rpc_clnt		*mnt_clnt;
> >  	int			status;
> > diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
> > index db6aa36..d47f6f5 100644
> > --- a/fs/nfs/namespace.c
> > +++ b/fs/nfs/namespace.c
> > @@ -135,7 +135,8 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
> >  		goto out_err;
> >  
> >  	if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL)
> > -		mnt = nfs_do_refmount(nd->path.mnt, nd->path.dentry);
> > +		mnt = nfs_do_refmount(nd->path.mnt, nd->path.dentry,
> > +				server->nfs_client->cl_rpcmount);
> >  	else
> >  		mnt = nfs_do_submount(nd->path.mnt, nd->path.dentry, fh,
> >  				      fattr);
> > diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
> > index 7a61fdb..92d5d63 100644
> > --- a/fs/nfs/nfs4namespace.c
> > +++ b/fs/nfs/nfs4namespace.c
> > @@ -14,7 +14,6 @@
> >  #include <linux/slab.h>
> >  #include <linux/string.h>
> >  #include <linux/sunrpc/clnt.h>
> > -#include <linux/sunrpc/rpc_pipe_fs.h>
> >  #include <linux/vfs.h>
> >  #include <linux/inet.h>
> >  #include "internal.h"
> > @@ -99,14 +98,13 @@ static int nfs4_validate_fspath(const struct vfsmount *mnt_parent,
> >  }
> >  
> >  static size_t nfs_parse_server_name(char *string, size_t len,
> > -		struct sockaddr *sa, size_t salen)
> > +		struct sockaddr *sa, size_t salen, struct vfsmount *rpcmount)
> >  {
> >  	ssize_t ret;
> >  
> >  	ret = rpc_pton(string, len, sa, salen);
> >  	if (ret == 0) {
> > -		ret = nfs_dns_resolve_name(string, len, sa, salen,
> > -				init_rpc_pipefs);
> > +		ret = nfs_dns_resolve_name(string, len, sa, salen, rpcmount);
> >  		if (ret < 0)
> >  			ret = 0;
> >  	}
> > @@ -115,7 +113,8 @@ static size_t nfs_parse_server_name(char *string, size_t len,
> >  
> >  static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
> >  				     char *page, char *page2,
> > -				     const struct nfs4_fs_location *location)
> > +				     const struct nfs4_fs_location *location,
> > +				     struct vfsmount *rpcmount)
> >  {
> >  	const size_t addr_bufsize = sizeof(struct sockaddr_storage);
> >  	struct vfsmount *mnt = ERR_PTR(-ENOENT);
> > @@ -143,7 +142,7 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
> >  			continue;
> >  
> >  		mountdata->addrlen = nfs_parse_server_name(buf->data, buf->len,
> > -				mountdata->addr, addr_bufsize);
> > +				mountdata->addr, addr_bufsize, rpcmount);
> >  		if (mountdata->addrlen == 0)
> >  			continue;
> >  
> > @@ -174,7 +173,8 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
> >   */
> >  static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
> >  					    const struct dentry *dentry,
> > -					    const struct nfs4_fs_locations *locations)
> > +					    const struct nfs4_fs_locations *locations,
> > +					    struct vfsmount *rpcmount)
> >  {
> >  	struct vfsmount *mnt = ERR_PTR(-ENOENT);
> >  	struct nfs_clone_mount mountdata = {
> > @@ -213,7 +213,7 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
> >  		    location->rootpath.ncomponents == 0)
> >  			continue;
> >  
> > -		mnt = try_location(&mountdata, page, page2, location);
> > +		mnt = try_location(&mountdata, page, page2, location, rpcmount);
> >  		if (!IS_ERR(mnt))
> >  			break;
> >  	}
> > @@ -231,7 +231,9 @@ out:
> >   * @dentry - dentry of referral
> >   *
> >   */
> > -struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry)
> > +struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent,
> > +		struct dentry *dentry,
> > +		struct vfsmount *rpcmount)
> >  {
> >  	struct vfsmount *mnt = ERR_PTR(-ENOMEM);
> >  	struct dentry *parent;
> > @@ -264,7 +266,7 @@ struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentr
> >  	    fs_locations->fs_path.ncomponents <= 0)
> >  		goto out_free;
> >  
> > -	mnt = nfs_follow_referral(mnt_parent, dentry, fs_locations);
> > +	mnt = nfs_follow_referral(mnt_parent, dentry, fs_locations, rpcmount);
> >  out_free:
> >  	__free_page(page);
> >  	kfree(fs_locations);
> > diff --git a/fs/nfs/super.c b/fs/nfs/super.c
> > index 4100630..32b7e35 100644
> > --- a/fs/nfs/super.c
> > +++ b/fs/nfs/super.c
> > @@ -35,6 +35,7 @@
> >  #include <linux/sunrpc/metrics.h>
> >  #include <linux/sunrpc/xprtsock.h>
> >  #include <linux/sunrpc/xprtrdma.h>
> > +#include <linux/sunrpc/rpc_pipe_fs.h>
> >  #include <linux/nfs_fs.h>
> >  #include <linux/nfs_mount.h>
> >  #include <linux/nfs4_mount.h>
> > @@ -106,6 +107,7 @@ enum {
> >  	Opt_lookupcache,
> >  	Opt_fscache_uniq,
> >  	Opt_local_lock,
> > +	Opt_rpcmount,
> >  
> >  	/* Special mount options */
> >  	Opt_userspace, Opt_deprecated, Opt_sloppy,
> > @@ -178,6 +180,7 @@ static const match_table_t nfs_mount_option_tokens = {
> >  	{ Opt_lookupcache, "lookupcache=%s" },
> >  	{ Opt_fscache_uniq, "fsc=%s" },
> >  	{ Opt_local_lock, "local_lock=%s" },
> > +	{ Opt_rpcmount, "rpcmount=%s" },
> >  
> >  	{ Opt_err, NULL }
> >  };
> > @@ -1484,6 +1487,13 @@ static int nfs_parse_mount_options(char *raw,
> >  				return 0;
> >  			};
> >  			break;
> > +		case Opt_rpcmount:
> > +			string = match_strdup(args);
> > +			if (string == NULL)
> > +				goto out_nomem;
> > +			kfree(mnt->rpcmount);
> > +			mnt->rpcmount = string;
> > +			break;
> >  
> >  		/*
> >  		 * Special options
> > @@ -1644,11 +1654,19 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
> >  	request.salen = args->mount_server.addrlen;
> >  	nfs_set_port(request.sap, &args->mount_server.port, 0);
> >  
> > +	request.rpcmount = get_rpc_pipefs(args->rpcmount);
> > +	if (IS_ERR(request.rpcmount)) {
> > +		dfprintk(MOUNT,	"NFS: unable get rpc_pipefs mount point, "
> > +				"error %ld\n", PTR_ERR(request.rpcmount));
> > +		return PTR_ERR(request.rpcmount);
> > +	}
> > +
> >  	/*
> >  	 * Now ask the mount server to map our export path
> >  	 * to a file handle.
> >  	 */
> >  	status = nfs_mount(&request);
> > +	mntput(request.rpcmount);
> >  	if (status != 0) {
> >  		dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n",
> >  				request.hostname, status);
> > @@ -2352,6 +2370,7 @@ out:
> >  	kfree(data->nfs_server.hostname);
> >  	kfree(data->mount_server.hostname);
> >  	kfree(data->fscache_uniq);
> > +	kfree(data->rpcmount);
> >  	security_free_mnt_opts(&data->lsm_opts);
> >  out_free_fh:
> >  	nfs_free_fhandle(mntfh);
> > @@ -2947,6 +2966,7 @@ out:
> >  	kfree(data->nfs_server.export_path);
> >  	kfree(data->nfs_server.hostname);
> >  	kfree(data->fscache_uniq);
> > +	kfree(data->rpcmount);
> >  out_free_data:
> >  	kfree(data);
> >  	dprintk("<-- nfs4_get_sb() = %d%s\n", error,
> > diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
> > index 452d964..ee417c9 100644
> > --- a/include/linux/nfs_fs_sb.h
> > +++ b/include/linux/nfs_fs_sb.h
> > @@ -36,6 +36,7 @@ struct nfs_client {
> >  	struct list_head	cl_share_link;	/* link in global client list */
> >  	struct list_head	cl_superblocks;	/* List of nfs_server structs */
> >  
> > +	struct vfsmount		*cl_rpcmount;	/* rpc_pipefs mount point */
> >  	struct rpc_clnt *	cl_rpcclient;
> >  	const struct nfs_rpc_ops *rpc_ops;	/* NFS protocol vector */
> >  	int			cl_proto;	/* Network transport protocol */
> > -- 
> > 1.7.3.4
> > 

-- 
 Kirill A. Shutemov

^ permalink raw reply

* Re: [PATCH v4 net-next-2.6] netfilter: x_tables: dont block BH while reading counters
From: Eric Dumazet @ 2010-12-20 14:45 UTC (permalink / raw)
  To: Jesper Dangaard Brouer
  Cc: Patrick McHardy, netfilter-devel, netdev, Stephen Hemminger
In-Reply-To: <1292852541.31289.75.camel@firesoul.comx.local>

Le lundi 20 décembre 2010 à 14:42 +0100, Jesper Dangaard Brouer a
écrit :
> I have tested the patch on 2.6.35.  Which implies I also needed to
> cherry-pick 870f67dcf7ef, which implements the vzalloc() call. (Latest
> net-next has a problem with my HP CCISS driver/controller or the PCI
> layout, and will not boot)
> 

Ah wait, you need to switch from cciss to hpsa driver, I hit same
problem some weeks ago ;) (and eventually rename your partitions
to /dev/sdaX instead of /dev/cciss/c0d0pX)


> According to the function_graph trace, the execution time of
> get_counters() has increased (approx) from 109 ms to 120 ms, which is
> the expected result.
> 
> The results are not all positive, but I think its related to the
> debugging options I have enabled.
> 
> Because I now see packet drops if my 1Gbit/s pktgen script are sending
> packet with a packet size below 512 bytes, which is "only" approx 230
> kpps (this is 1Gbit/s on my 10G labsetup where I have seen 5 Mpps).
> 



> There is no packet overruns/drops, iif I run "iptables -vnL >
> /dev/null" without tracing enabled and only 1Gbit/s pktgen at 512
> bytes packets.  If I enable tracing while calling iptables I see
> packet drops/overruns.  So I guess this is caused by the tracing
> overhead.

yes, probably :)

> 
> I'll try to rerun my test without all the lock debugging options
> enabled.
> 

Thanks !


--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 00/12] make rpc_pipefs be mountable multiple times
From: J. Bruce Fields @ 2010-12-20 14:46 UTC (permalink / raw)
  To: Kirill A. Shutsemov
  Cc: Trond Myklebust, Neil Brown, Pavel Emelyanov, linux-nfs,
	David S. Miller, netdev, linux-kernel
In-Reply-To: <1292846078-31793-1-git-send-email-kirill@shutemov.name>

On Mon, Dec 20, 2010 at 01:54:26PM +0200, Kirill A. Shutsemov wrote:
> From: Kirill A. Shutemov <kirill@shutemov.name>
> 
> Prepare nfs/sunrpc stack to use multiple instances of rpc_pipefs.
> Only for client for now.
> 
> Only quick sanity check was made. BTW, is there any check list for NFS
> contributors?

Nothing formal.

Chuck may have some nlm patches that conflict; I'm not sure what their
status is.

For testing rpc_pipefs, maybe a few mounts (simultaneous mounts might be
good), possibly over different security flavors, and with some of them
nfsv4, might be a good idea.

By the way, was there ever a resolution to Trond's question?:

	http://marc.info/?l=linux-nfs&m=128655758712817&w=2

	"The keyring upcalls are currently initiated through the same
	mechanism as module_request and therefore get started with the
	init_nsproxy namespace. We'd really like them to run inside the
	same container as the process.  As part of the same problem,
	there is the issue of what to do with the dns resolver and
	Bryan's new keyring based idmapper code."

--b.

> 
> Kirill A. Shutemov (12):
>   sunrpc: mount rpc_pipefs on initialization
>   sunrpc: introduce init_rpc_pipefs
>   sunrpc: push init_rpc_pipefs up to rpc_create() callers
>   sunrpc: tag svc_serv with rpc_pipefs mount point
>   sunrpc: get rpc_pipefs mount point for svc_serv from callers
>   lockd: get rpc_pipefs mount point from callers
>   sunrpc: get rpc_pipefs mount point for rpcb_create_local from callers
>   sunrpc: tag pipefs field of cache_detail with rpc_pipefs mount point
>   nfs: per-rpc_pipefs dns cache
>   sunrpc: introduce get_rpc_pipefs()
>   nfs: introduce mount option 'rpcmount'
>   sunrpc: make rpc_pipefs be mountable multiple times
> 
>  fs/lockd/clntlock.c                |    8 +-
>  fs/lockd/host.c                    |   12 +++-
>  fs/lockd/mon.c                     |   13 ++-
>  fs/lockd/svc.c                     |    4 +-
>  fs/nfs/cache_lib.c                 |   18 +----
>  fs/nfs/cache_lib.h                 |    3 +-
>  fs/nfs/callback.c                  |    6 +-
>  fs/nfs/callback.h                  |    3 +-
>  fs/nfs/client.c                    |   45 ++++++++++--
>  fs/nfs/dns_resolve.c               |  128 ++++++++++++++++++++++++++-------
>  fs/nfs/dns_resolve.h               |    8 +--
>  fs/nfs/inode.c                     |    8 +--
>  fs/nfs/internal.h                  |   10 ++-
>  fs/nfs/mount_clnt.c                |    1 +
>  fs/nfs/namespace.c                 |    3 +-
>  fs/nfs/nfs4namespace.c             |   20 +++--
>  fs/nfs/super.c                     |   20 +++++
>  fs/nfsd/nfs4callback.c             |    2 +
>  fs/nfsd/nfssvc.c                   |    8 +-
>  include/linux/lockd/bind.h         |    3 +-
>  include/linux/lockd/lockd.h        |    4 +-
>  include/linux/nfs_fs_sb.h          |    1 +
>  include/linux/sunrpc/cache.h       |    9 +--
>  include/linux/sunrpc/clnt.h        |    5 +-
>  include/linux/sunrpc/rpc_pipe_fs.h |    6 +-
>  include/linux/sunrpc/svc.h         |    9 +-
>  net/sunrpc/cache.c                 |   16 +++--
>  net/sunrpc/clnt.c                  |   19 +++--
>  net/sunrpc/rpc_pipe.c              |  142 ++++++++++++++++++++++++++++++------
>  net/sunrpc/rpcb_clnt.c             |   13 ++-
>  net/sunrpc/svc.c                   |   52 ++++++++-----
>  31 files changed, 430 insertions(+), 169 deletions(-)
> 
> -- 
> 1.7.3.4
> 

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox