Linux NFS development
 help / color / mirror / Atom feed
* [PATCH 0/5] Support "-t nfs,vers=4" mounts in the kernel
@ 2009-08-30 16:34 Chuck Lever
       [not found] ` <20090830162211.3652.14638.stgit-RytpoXr2tKZ9HhUboXbp9zCvJB+x5qRC@public.gmane.org>
  0 siblings, 1 reply; 9+ messages in thread
From: Chuck Lever @ 2009-08-30 16:34 UTC (permalink / raw)
  To: trond.myklebust; +Cc: linux-nfs

Update to the patches that allow the "nfs" file system to handle
vers=4.  These patches are for discussion only.

Minor changes to mount.nfs and umount.nfs are required, and will be
posted in a separate thread.  With these changes, mount.nfs passes a
client_address option and skips rpcbind for vers=4 mounts, and
umount.nfs skips the UMNT call for vers=4 mounts.

This series adds proper handling of the default port (0 for v2/v3,
2049 for v4), teaches nfs_kill_super to handle both "nfs" and "nfs4"
file systems, and refactors NFSv4 routines so common code can be
invoked by "nfs" and "nfs4."

Simple mount test succeeds.  /proc/mounts lists the mount as "nfs4"
but /etc/mtab lists it as "nfs".  Thus combining nfs_kill_super and
nfs4_kill_super is probably not necessary.

I have not tried cross mounts or referrals.

---

Chuck Lever (5):
      NFS: Allow the "nfs" file system type to support NFSv4
      NFS: Move details of nfs4_get_sb() to a helper
      NFS: Refactor NFSv4 text-based mount option validation
      NFS: Mount option parser should detect unset port values
      NFS: combine nfs_kill_super() and nfs4_kill_super()


 fs/nfs/internal.h    |   23 ++++-
 fs/nfs/super.c       |  245 +++++++++++++++++++++++++++++++-------------------
 include/linux/nfs4.h |    1 
 3 files changed, 174 insertions(+), 95 deletions(-)

-- 
Chuck Lever <chuck.lever@oracle.com>

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

* [PATCH 1/5] NFS: combine nfs_kill_super() and nfs4_kill_super()
       [not found] ` <20090830162211.3652.14638.stgit-RytpoXr2tKZ9HhUboXbp9zCvJB+x5qRC@public.gmane.org>
@ 2009-08-30 16:34   ` Chuck Lever
       [not found]     ` <20090830163432.3652.437.stgit-RytpoXr2tKZ9HhUboXbp9zCvJB+x5qRC@public.gmane.org>
  2009-08-30 16:34   ` [PATCH 2/5] NFS: Mount option parser should detect unset port values Chuck Lever
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Chuck Lever @ 2009-08-30 16:34 UTC (permalink / raw)
  To: trond.myklebust; +Cc: linux-nfs

nfs_kill_super() and nfs4_kill_super() do almost the same thing, so combine
them.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/super.c |   45 +++++++++++++++++++++------------------------
 1 files changed, 21 insertions(+), 24 deletions(-)

diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index f3a95df..d215707 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -282,13 +282,12 @@ static int nfs4_referral_get_sb(struct file_system_type *fs_type,
 	int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
 static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type,
 	int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
-static void nfs4_kill_super(struct super_block *sb);
 
 static struct file_system_type nfs4_fs_type = {
 	.owner		= THIS_MODULE,
 	.name		= "nfs4",
 	.get_sb		= nfs4_get_sb,
-	.kill_sb	= nfs4_kill_super,
+	.kill_sb	= nfs_kill_super,
 	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
 };
 
@@ -296,7 +295,7 @@ static struct file_system_type nfs4_remote_fs_type = {
 	.owner		= THIS_MODULE,
 	.name		= "nfs4",
 	.get_sb		= nfs4_remote_get_sb,
-	.kill_sb	= nfs4_kill_super,
+	.kill_sb	= nfs_kill_super,
 	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
 };
 
@@ -304,7 +303,7 @@ struct file_system_type nfs4_xdev_fs_type = {
 	.owner		= THIS_MODULE,
 	.name		= "nfs4",
 	.get_sb		= nfs4_xdev_get_sb,
-	.kill_sb	= nfs4_kill_super,
+	.kill_sb	= nfs_kill_super,
 	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
 };
 
@@ -312,7 +311,7 @@ static struct file_system_type nfs4_remote_referral_fs_type = {
 	.owner		= THIS_MODULE,
 	.name		= "nfs4",
 	.get_sb		= nfs4_remote_referral_get_sb,
-	.kill_sb	= nfs4_kill_super,
+	.kill_sb	= nfs_kill_super,
 	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
 };
 
@@ -320,7 +319,7 @@ struct file_system_type nfs4_referral_fs_type = {
 	.owner		= THIS_MODULE,
 	.name		= "nfs4",
 	.get_sb		= nfs4_referral_get_sb,
-	.kill_sb	= nfs4_kill_super,
+	.kill_sb	= nfs_kill_super,
 	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
 };
 
@@ -2127,16 +2126,27 @@ error_splat_super:
 }
 
 /*
- * Destroy an NFS2/3 superblock
+ * Destroy an NFS superblock
  */
-static void nfs_kill_super(struct super_block *s)
+static void nfs_kill_super(struct super_block *sb)
 {
-	struct nfs_server *server = NFS_SB(s);
+	struct nfs_server *server = NFS_SB(sb);
+
+	dprintk("--> %s\n", __func__);
+
+#ifdef CONFIG_NFS_V4
+	if (server->nfs_client->rpc_ops->version == 4) {
+		nfs_super_return_all_delegations(sb);
+		nfs4_renewd_prepare_shutdown(server);
+	}
+#endif	/* CONFIG_NFS_V4 */
 
 	bdi_unregister(&server->backing_dev_info);
-	kill_anon_super(s);
-	nfs_fscache_release_super_cookie(s);
+	kill_anon_super(sb);
+	nfs_fscache_release_super_cookie(sb);
 	nfs_free_server(server);
+
+	dprintk("<-- %s\n", __func__);
 }
 
 /*
@@ -2599,19 +2609,6 @@ out_free_data:
 	return error;
 }
 
-static void nfs4_kill_super(struct super_block *sb)
-{
-	struct nfs_server *server = NFS_SB(sb);
-
-	dprintk("--> %s\n", __func__);
-	nfs_super_return_all_delegations(sb);
-	kill_anon_super(sb);
-	nfs4_renewd_prepare_shutdown(server);
-	nfs_fscache_release_super_cookie(sb);
-	nfs_free_server(server);
-	dprintk("<-- %s\n", __func__);
-}
-
 /*
  * Clone an NFS4 server record on xdev traversal (FSID-change)
  */


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

* [PATCH 2/5] NFS: Mount option parser should detect unset port values
       [not found] ` <20090830162211.3652.14638.stgit-RytpoXr2tKZ9HhUboXbp9zCvJB+x5qRC@public.gmane.org>
  2009-08-30 16:34   ` [PATCH 1/5] NFS: combine nfs_kill_super() and nfs4_kill_super() Chuck Lever
@ 2009-08-30 16:34   ` Chuck Lever
  2009-08-30 16:34   ` [PATCH 3/5] NFS: Refactor NFSv4 text-based mount option validation Chuck Lever
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Chuck Lever @ 2009-08-30 16:34 UTC (permalink / raw)
  To: trond.myklebust; +Cc: linux-nfs

The NFS mount option parser needs to distinguish between a user set
port value of zero, and the absence of a port setting (currently,
also zero).

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/internal.h |   22 ++++++++++++++++++++--
 fs/nfs/super.c    |   51 ++++++++++++++++++++++++++++-----------------------
 2 files changed, 48 insertions(+), 25 deletions(-)

diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index dabf345..d30b4fb 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -49,6 +49,11 @@ struct nfs_clone_mount {
 #define NFS_MAX_SECFLAVORS	(12)
 
 /*
+ * Value used if the user did not specify a port value.
+ */
+#define NFS_UNSPEC_PORT		(-1)
+
+/*
  * In-kernel mount arguments
  */
 struct nfs_parsed_mount_data {
@@ -71,7 +76,7 @@ struct nfs_parsed_mount_data {
 		size_t			addrlen;
 		char			*hostname;
 		u32			version;
-		unsigned short		port;
+		int			port;
 		unsigned short		protocol;
 	} mount_server;
 
@@ -80,13 +85,26 @@ struct nfs_parsed_mount_data {
 		size_t			addrlen;
 		char			*hostname;
 		char			*export_path;
-		unsigned short		port;
+		int			port;
 		unsigned short		protocol;
 	} nfs_server;
 
 	struct security_mnt_opts lsm_opts;
 };
 
+static inline struct sockaddr *
+nfs_server_address(struct nfs_parsed_mount_data *mnt)
+{
+	return (struct sockaddr *)&mnt->nfs_server.address;
+}
+
+static inline struct sockaddr *
+mnt_server_address(struct nfs_parsed_mount_data *mnt)
+{
+	return (struct sockaddr *)&mnt->mount_server.address;
+}
+
+
 /* mount_clnt.c */
 struct nfs_mount_request {
 	struct sockaddr		*sap;
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index d215707..ea7aedc 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -746,6 +746,21 @@ static int nfs_verify_server_address(struct sockaddr *addr)
 }
 
 /*
+ * Select between a default port value and a user-specified port value.
+ * If a zero value is set, then autobind will be used.
+ */
+static void nfs_set_default_port(struct sockaddr *sap, const int parsed_port,
+				 const unsigned short default_port)
+{
+	unsigned short port = default_port;
+
+	if (parsed_port != NFS_UNSPEC_PORT)
+		port = parsed_port;
+
+	rpc_set_port(sap, port);
+}
+
+/*
  * Sanity check the NFS transport protocol.
  *
  */
@@ -1226,8 +1241,7 @@ static int nfs_parse_mount_options(char *raw,
 				goto out_nomem;
 			mnt->nfs_server.addrlen =
 				rpc_pton(string, strlen(string),
-					(struct sockaddr *)
-					&mnt->nfs_server.address,
+					nfs_server_address(mnt),
 					sizeof(mnt->nfs_server.address));
 			kfree(string);
 			if (mnt->nfs_server.addrlen == 0)
@@ -1414,11 +1428,7 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
 		args->mount_server.addrlen = args->nfs_server.addrlen;
 	}
 	request.salen = args->mount_server.addrlen;
-
-	/*
-	 * autobind will be used if mount_server.port == 0
-	 */
-	rpc_set_port(request.sap, args->mount_server.port);
+	nfs_set_default_port(request.sap, args->mount_server.port, 0);
 
 	/*
 	 * Now ask the mount server to map our export path
@@ -1607,8 +1617,8 @@ static int nfs_validate_mount_data(void *options,
 	args->acregmax		= NFS_DEF_ACREGMAX;
 	args->acdirmin		= NFS_DEF_ACDIRMIN;
 	args->acdirmax		= NFS_DEF_ACDIRMAX;
-	args->mount_server.port	= 0;	/* autobind unless user sets port */
-	args->nfs_server.port	= 0;	/* autobind unless user sets port */
+	args->mount_server.port	= NFS_UNSPEC_PORT;
+	args->nfs_server.port	= NFS_UNSPEC_PORT;
 	args->nfs_server.protocol = XPRT_TRANSPORT_TCP;
 	args->auth_flavors[0]	= RPC_AUTH_UNIX;
 	args->auth_flavor_len	= 1;
@@ -1659,8 +1669,7 @@ static int nfs_validate_mount_data(void *options,
 		memcpy(&args->nfs_server.address, &data->addr,
 		       sizeof(data->addr));
 		args->nfs_server.addrlen = sizeof(data->addr);
-		if (!nfs_verify_server_address((struct sockaddr *)
-						&args->nfs_server.address))
+		if (!nfs_verify_server_address(nfs_server_address(args)))
 			goto out_no_address;
 
 		if (!(data->flags & NFS_MOUNT_TCP))
@@ -1708,12 +1717,11 @@ static int nfs_validate_mount_data(void *options,
 		if (nfs_parse_mount_options((char *)options, args) == 0)
 			return -EINVAL;
 
-		if (!nfs_verify_server_address((struct sockaddr *)
-						&args->nfs_server.address))
+		if (!nfs_verify_server_address(nfs_server_address(args)))
 			goto out_no_address;
 
-		rpc_set_port((struct sockaddr *)&args->nfs_server.address,
-				args->nfs_server.port);
+		nfs_set_default_port(nfs_server_address(args),
+					args->nfs_server.port, 0);
 
 		nfs_set_mount_transport_protocol(args);
 
@@ -2284,7 +2292,7 @@ static int nfs4_validate_mount_data(void *options,
 	args->acregmax		= NFS_DEF_ACREGMAX;
 	args->acdirmin		= NFS_DEF_ACDIRMIN;
 	args->acdirmax		= NFS_DEF_ACDIRMAX;
-	args->nfs_server.port	= NFS_PORT; /* 2049 unless user set port= */
+	args->nfs_server.port	= NFS_UNSPEC_PORT;
 	args->auth_flavors[0]	= RPC_AUTH_UNIX;
 	args->auth_flavor_len	= 1;
 	args->minorversion	= 0;
@@ -2299,8 +2307,7 @@ static int nfs4_validate_mount_data(void *options,
 		args->nfs_server.addrlen = data->host_addrlen;
 		if (copy_from_user(ap, data->host_addr, data->host_addrlen))
 			return -EFAULT;
-		if (!nfs_verify_server_address((struct sockaddr *)
-						&args->nfs_server.address))
+		if (!nfs_verify_server_address(nfs_server_address(args)))
 			goto out_no_address;
 
 		if (data->auth_flavourlen) {
@@ -2352,12 +2359,10 @@ static int nfs4_validate_mount_data(void *options,
 		if (nfs_parse_mount_options((char *)options, args) == 0)
 			return -EINVAL;
 
-		if (!nfs_verify_server_address((struct sockaddr *)
-						&args->nfs_server.address))
+		if (!nfs_verify_server_address(nfs_server_address(args)))
 			return -EINVAL;
-
-		rpc_set_port((struct sockaddr *)&args->nfs_server.address,
-				args->nfs_server.port);
+		nfs_set_default_port(nfs_server_address(args),
+					args->nfs_server.port, NFS_PORT);
 
 		nfs_validate_transport_protocol(args);
 


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

* [PATCH 3/5] NFS: Refactor NFSv4 text-based mount option validation
       [not found] ` <20090830162211.3652.14638.stgit-RytpoXr2tKZ9HhUboXbp9zCvJB+x5qRC@public.gmane.org>
  2009-08-30 16:34   ` [PATCH 1/5] NFS: combine nfs_kill_super() and nfs4_kill_super() Chuck Lever
  2009-08-30 16:34   ` [PATCH 2/5] NFS: Mount option parser should detect unset port values Chuck Lever
@ 2009-08-30 16:34   ` Chuck Lever
  2009-08-30 16:34   ` [PATCH 4/5] NFS: Move details of nfs4_get_sb() to a helper Chuck Lever
  2009-08-30 16:35   ` [PATCH 5/5] NFS: Allow the "nfs" file system type to support NFSv4 Chuck Lever
  4 siblings, 0 replies; 9+ messages in thread
From: Chuck Lever @ 2009-08-30 16:34 UTC (permalink / raw)
  To: trond.myklebust; +Cc: linux-nfs

Move the part of nfs4_validate_mount_options that handles text-based
options into a helper, so we can call it from other functions.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/super.c |   69 ++++++++++++++++++++++++++++----------------------------
 1 files changed, 34 insertions(+), 35 deletions(-)

diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index ea7aedc..9119f22 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -272,6 +272,8 @@ static const struct super_operations nfs_sops = {
 };
 
 #ifdef CONFIG_NFS_V4
+static int nfs4_validate_text_mount_data(void *options,
+	struct nfs_parsed_mount_data *args, const char *dev_name);
 static int nfs4_get_sb(struct file_system_type *fs_type,
 	int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
 static int nfs4_remote_get_sb(struct file_system_type *fs_type,
@@ -2272,6 +2274,36 @@ static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args)
 	args->flags &= ~(NFS_MOUNT_NONLM|NFS_MOUNT_NOACL|NFS_MOUNT_VER3);
 }
 
+static int nfs4_validate_text_mount_data(void *options,
+					 struct nfs_parsed_mount_data *args,
+					 const char *dev_name)
+{
+	if (nfs_parse_mount_options((char *)options, args) == 0)
+		return -EINVAL;
+
+	if (!nfs_verify_server_address(nfs_server_address(args)))
+		return -EINVAL;
+
+	nfs_set_default_port(nfs_server_address(args),
+				args->nfs_server.port, NFS_PORT);
+
+	nfs_validate_transport_protocol(args);
+
+	nfs4_validate_mount_flags(args);
+
+	if (args->auth_flavor_len > 1)
+		return -EINVAL;
+
+	if (args->client_address == NULL)
+		return -EINVAL;
+
+	return nfs_parse_devname(dev_name,
+				   &args->nfs_server.hostname,
+				   NFS4_MAXNAMLEN,
+				   &args->nfs_server.export_path,
+				   NFS4_MAXPATHLEN);
+}
+
 /*
  * Validate NFSv4 mount options
  */
@@ -2353,37 +2385,8 @@ static int nfs4_validate_mount_data(void *options,
 		nfs_validate_transport_protocol(args);
 
 		break;
-	default: {
-		int status;
-
-		if (nfs_parse_mount_options((char *)options, args) == 0)
-			return -EINVAL;
-
-		if (!nfs_verify_server_address(nfs_server_address(args)))
-			return -EINVAL;
-		nfs_set_default_port(nfs_server_address(args),
-					args->nfs_server.port, NFS_PORT);
-
-		nfs_validate_transport_protocol(args);
-
-		nfs4_validate_mount_flags(args);
-
-		if (args->auth_flavor_len > 1)
-			goto out_inval_auth;
-
-		if (args->client_address == NULL)
-			goto out_no_client_address;
-
-		status = nfs_parse_devname(dev_name,
-					   &args->nfs_server.hostname,
-					   NFS4_MAXNAMLEN,
-					   &args->nfs_server.export_path,
-					   NFS4_MAXPATHLEN);
-		if (status < 0)
-			return status;
-
-		break;
-		}
+	default:
+		return nfs4_validate_text_mount_data(options, args, dev_name);
 	}
 
 	return 0;
@@ -2400,10 +2403,6 @@ out_inval_auth:
 out_no_address:
 	dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n");
 	return -EINVAL;
-
-out_no_client_address:
-	dfprintk(MOUNT, "NFS4: mount program didn't pass callback address\n");
-	return -EINVAL;
 }
 
 /*


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

* [PATCH 4/5] NFS: Move details of nfs4_get_sb() to a helper
       [not found] ` <20090830162211.3652.14638.stgit-RytpoXr2tKZ9HhUboXbp9zCvJB+x5qRC@public.gmane.org>
                     ` (2 preceding siblings ...)
  2009-08-30 16:34   ` [PATCH 3/5] NFS: Refactor NFSv4 text-based mount option validation Chuck Lever
@ 2009-08-30 16:34   ` Chuck Lever
  2009-08-30 16:35   ` [PATCH 5/5] NFS: Allow the "nfs" file system type to support NFSv4 Chuck Lever
  4 siblings, 0 replies; 9+ messages in thread
From: Chuck Lever @ 2009-08-30 16:34 UTC (permalink / raw)
  To: trond.myklebust; +Cc: linux-nfs

Refactor nfs4_get_sb() to allow its guts to be invoked by other
functions.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/super.c |   44 +++++++++++++++++++++++++++++++-------------
 1 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 9119f22..4bcdfd4 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -274,6 +274,8 @@ static const struct super_operations nfs_sops = {
 #ifdef CONFIG_NFS_V4
 static int nfs4_validate_text_mount_data(void *options,
 	struct nfs_parsed_mount_data *args, const char *dev_name);
+static int nfs4_try_mount(int flags, const char *dev_name,
+	struct nfs_parsed_mount_data *data, struct vfsmount *mnt);
 static int nfs4_get_sb(struct file_system_type *fs_type,
 	int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
 static int nfs4_remote_get_sb(struct file_system_type *fs_type,
@@ -2569,6 +2571,34 @@ out_err:
 	return ret;
 }
 
+static int nfs4_try_mount(int flags, const char *dev_name,
+			 struct nfs_parsed_mount_data *data,
+			 struct vfsmount *mnt)
+{
+	char *export_path;
+	struct vfsmount *root_mnt;
+	int error;
+
+	dfprintk(MOUNT, "--> nfs4_try_mount()\n");
+
+	export_path = data->nfs_server.export_path;
+	data->nfs_server.export_path = "/";
+	root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, data,
+			data->nfs_server.hostname);
+	data->nfs_server.export_path = export_path;
+
+	error = PTR_ERR(root_mnt);
+	if (IS_ERR(root_mnt))
+		goto out;
+
+	error = nfs_follow_remote_path(root_mnt, export_path, mnt);
+
+out:
+	dfprintk(MOUNT, "<-- nfs4_try_mount() = %d%s\n", error,
+			error != 0 ? " [error]" : "");
+	return error;
+}
+
 /*
  * Get the superblock for an NFS4 mountpoint
  */
@@ -2576,8 +2606,6 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
 	int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
 {
 	struct nfs_parsed_mount_data *data;
-	char *export_path;
-	struct vfsmount *root_mnt;
 	int error = -ENOMEM;
 
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
@@ -2589,17 +2617,7 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
 	if (error < 0)
 		goto out;
 
-	export_path = data->nfs_server.export_path;
-	data->nfs_server.export_path = "/";
-	root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, data,
-			data->nfs_server.hostname);
-	data->nfs_server.export_path = export_path;
-
-	error = PTR_ERR(root_mnt);
-	if (IS_ERR(root_mnt))
-		goto out;
-
-	error = nfs_follow_remote_path(root_mnt, export_path, mnt);
+	error = nfs4_try_mount(flags, dev_name, data, mnt);
 
 out:
 	kfree(data->client_address);


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

* [PATCH 5/5] NFS: Allow the "nfs" file system type to support NFSv4
       [not found] ` <20090830162211.3652.14638.stgit-RytpoXr2tKZ9HhUboXbp9zCvJB+x5qRC@public.gmane.org>
                     ` (3 preceding siblings ...)
  2009-08-30 16:34   ` [PATCH 4/5] NFS: Move details of nfs4_get_sb() to a helper Chuck Lever
@ 2009-08-30 16:35   ` Chuck Lever
  4 siblings, 0 replies; 9+ messages in thread
From: Chuck Lever @ 2009-08-30 16:35 UTC (permalink / raw)
  To: trond.myklebust; +Cc: linux-nfs

When mounting an "nfs" type file system, recognize "v4," "vers=4," or
"nfsvers=4" mount options.  For nfsvers=4, cause the file system to
behave just like "nfs4," but remain "nfs".

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/internal.h    |    1 +
 fs/nfs/super.c       |   42 +++++++++++++++++++++++++++++++++++++++++-
 include/linux/nfs4.h |    1 +
 3 files changed, 43 insertions(+), 1 deletions(-)

diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index d30b4fb..da132dc 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -68,6 +68,7 @@ struct nfs_parsed_mount_data {
 	unsigned int		auth_flavor_len;
 	rpc_authflavor_t	auth_flavors[1];
 	char			*client_address;
+	unsigned int		version;
 	unsigned int		minorversion;
 	char			*fscache_uniq;
 
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 4bcdfd4..70da441 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -73,7 +73,7 @@ enum {
 	Opt_cto, Opt_nocto,
 	Opt_ac, Opt_noac,
 	Opt_lock, Opt_nolock,
-	Opt_v2, Opt_v3,
+	Opt_v2, Opt_v3, Opt_v4,
 	Opt_udp, Opt_tcp, Opt_rdma,
 	Opt_acl, Opt_noacl,
 	Opt_rdirplus, Opt_nordirplus,
@@ -127,6 +127,7 @@ static const match_table_t nfs_mount_option_tokens = {
 	{ Opt_nolock, "nolock" },
 	{ Opt_v2, "v2" },
 	{ Opt_v3, "v3" },
+	{ Opt_v4, "v4" },
 	{ Opt_udp, "udp" },
 	{ Opt_tcp, "tcp" },
 	{ Opt_rdma, "rdma" },
@@ -933,10 +934,18 @@ static int nfs_parse_mount_options(char *raw,
 			break;
 		case Opt_v2:
 			mnt->flags &= ~NFS_MOUNT_VER3;
+			mnt->version = 2;
 			break;
 		case Opt_v3:
 			mnt->flags |= NFS_MOUNT_VER3;
+			mnt->version = 3;
 			break;
+#ifdef CONFIG_NFS_V4
+		case Opt_v4:
+			mnt->flags &= ~NFS_MOUNT_VER3;
+			mnt->version = 4;
+			break;
+#endif
 		case Opt_udp:
 			mnt->flags &= ~NFS_MOUNT_TCP;
 			mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
@@ -1150,10 +1159,18 @@ static int nfs_parse_mount_options(char *raw,
 			switch (option) {
 			case NFS2_VERSION:
 				mnt->flags &= ~NFS_MOUNT_VER3;
+				mnt->version = 2;
 				break;
 			case NFS3_VERSION:
 				mnt->flags |= NFS_MOUNT_VER3;
+				mnt->version = 3;
+				break;
+#ifdef CONFIG_NFS_V4
+			case NFS4_VERSION:
+				mnt->flags &= ~NFS_MOUNT_VER3;
+				mnt->version = 4;
 				break;
+#endif
 			default:
 				goto out_invalid_value;
 			}
@@ -1626,6 +1643,7 @@ static int nfs_validate_mount_data(void *options,
 	args->nfs_server.protocol = XPRT_TRANSPORT_TCP;
 	args->auth_flavors[0]	= RPC_AUTH_UNIX;
 	args->auth_flavor_len	= 1;
+	args->minorversion	= 0;
 
 	switch (data->version) {
 	case 1:
@@ -1724,6 +1742,14 @@ static int nfs_validate_mount_data(void *options,
 		if (!nfs_verify_server_address(nfs_server_address(args)))
 			goto out_no_address;
 
+		if (args->version == 4)
+#ifdef CONFIG_NFS_V4
+			return nfs4_validate_text_mount_data(options,
+							     args, dev_name);
+#else
+			goto out_v4_not_compiled;
+#endif
+
 		nfs_set_default_port(nfs_server_address(args),
 					args->nfs_server.port, 0);
 
@@ -1773,6 +1799,12 @@ out_v3_not_compiled:
 	return -EPROTONOSUPPORT;
 #endif /* !CONFIG_NFS_V3 */
 
+#ifndef CONFIG_NFS_V4
+out_v4_not_compiled:
+	dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n");
+	return -EPROTONOSUPPORT;
+#endif /* !CONFIG_NFS_V4 */
+
 out_nomem:
 	dfprintk(MOUNT, "NFS: not enough memory to handle mount options\n");
 	return -ENOMEM;
@@ -2068,6 +2100,14 @@ static int nfs_get_sb(struct file_system_type *fs_type,
 	if (error < 0)
 		goto out;
 
+#ifdef CONFIG_NFS_V4
+	if (data->version == 4) {
+		error = nfs4_try_mount(flags, dev_name, data, mnt);
+		kfree(data->client_address);
+		goto out;
+	}
+#endif	/* CONFIG_NFS_V4 */
+
 	/* Get a volume representation */
 	server = nfs_create_server(data, mntfh);
 	if (IS_ERR(server)) {
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index bd2eba5..33b2836 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -472,6 +472,7 @@ enum lock_type4 {
 
 #define NFSPROC4_NULL 0
 #define NFSPROC4_COMPOUND 1
+#define NFS4_VERSION 4
 #define NFS4_MINOR_VERSION 0
 
 #if defined(CONFIG_NFS_V4_1)


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

* Re: [PATCH 1/5] NFS: combine nfs_kill_super() and nfs4_kill_super()
       [not found]     ` <20090830163432.3652.437.stgit-RytpoXr2tKZ9HhUboXbp9zCvJB+x5qRC@public.gmane.org>
@ 2009-08-30 16:42       ` Christoph Hellwig
  2009-08-30 16:59         ` Trond Myklebust
  0 siblings, 1 reply; 9+ messages in thread
From: Christoph Hellwig @ 2009-08-30 16:42 UTC (permalink / raw)
  To: Chuck Lever; +Cc: trond.myklebust, linux-nfs

On Sun, Aug 30, 2009 at 12:34:33PM -0400, Chuck Lever wrote:
> +static void nfs_kill_super(struct super_block *sb)
>  {
> +	struct nfs_server *server = NFS_SB(sb);
> +
> +	dprintk("--> %s\n", __func__);
> +
> +#ifdef CONFIG_NFS_V4
> +	if (server->nfs_client->rpc_ops->version == 4) {
> +		nfs_super_return_all_delegations(sb);
> +		nfs4_renewd_prepare_shutdown(server);
> +	}
> +#endif	/* CONFIG_NFS_V4 */
>  
>  	bdi_unregister(&server->backing_dev_info);

This was previously not done for nfs4.  If it is a bug-fixed that
should be documented in the patch description, and if not it needs
to be changed.


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

* Re: [PATCH 1/5] NFS: combine nfs_kill_super() and nfs4_kill_super()
  2009-08-30 16:42       ` Christoph Hellwig
@ 2009-08-30 16:59         ` Trond Myklebust
       [not found]           ` <1251651593.12486.14.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
  0 siblings, 1 reply; 9+ messages in thread
From: Trond Myklebust @ 2009-08-30 16:59 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Chuck Lever, linux-nfs

On Sun, 2009-08-30 at 12:42 -0400, Christoph Hellwig wrote:
> On Sun, Aug 30, 2009 at 12:34:33PM -0400, Chuck Lever wrote:
> > +static void nfs_kill_super(struct super_block *sb)
> >  {
> > +	struct nfs_server *server = NFS_SB(sb);
> > +
> > +	dprintk("--> %s\n", __func__);
> > +
> > +#ifdef CONFIG_NFS_V4
> > +	if (server->nfs_client->rpc_ops->version == 4) {
> > +		nfs_super_return_all_delegations(sb);
> > +		nfs4_renewd_prepare_shutdown(server);
> > +	}
> > +#endif	/* CONFIG_NFS_V4 */
> >  
> >  	bdi_unregister(&server->backing_dev_info);
> 
> This was previously not done for nfs4.  If it is a bug-fixed that
> should be documented in the patch description, and if not it needs
> to be changed.

It has always been done, but it was in a separate function
(nfs4_kill_super()). I don't really see what we gain by inlining it into
nfs_kill_super..

Also, I'm concerned about the growth of "if (version == X)" type
constructs. We shouldn't be looking at the version number in order to
figure out whether or not we're holding delegations, or whether or not a
particular daemon thread is running.
AFAICS, in this case it should in any case be safe to call
nfs_super_return_all_delegations() (as long as CONFIG_NFS_V4 is defined
- that we might want to fix). Ditto for nfs4_renewd_prepare_shutdown().

Cheers
  Trond


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

* Re: [PATCH 1/5] NFS: combine nfs_kill_super() and nfs4_kill_super()
       [not found]           ` <1251651593.12486.14.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
@ 2009-08-30 17:04             ` Chuck Lever
  0 siblings, 0 replies; 9+ messages in thread
From: Chuck Lever @ 2009-08-30 17:04 UTC (permalink / raw)
  To: Trond Myklebust; +Cc: Christoph Hellwig, linux-nfs


On Aug 30, 2009, at 12:59 PM, Trond Myklebust wrote:

> On Sun, 2009-08-30 at 12:42 -0400, Christoph Hellwig wrote:
>> On Sun, Aug 30, 2009 at 12:34:33PM -0400, Chuck Lever wrote:
>>> +static void nfs_kill_super(struct super_block *sb)
>>> {
>>> +	struct nfs_server *server = NFS_SB(sb);
>>> +
>>> +	dprintk("--> %s\n", __func__);
>>> +
>>> +#ifdef CONFIG_NFS_V4
>>> +	if (server->nfs_client->rpc_ops->version == 4) {
>>> +		nfs_super_return_all_delegations(sb);
>>> +		nfs4_renewd_prepare_shutdown(server);
>>> +	}
>>> +#endif	/* CONFIG_NFS_V4 */
>>>
>>> 	bdi_unregister(&server->backing_dev_info);
>>
>> This was previously not done for nfs4.  If it is a bug-fixed that
>> should be documented in the patch description, and if not it needs
>> to be changed.
>
> It has always been done, but it was in a separate function
> (nfs4_kill_super()). I don't really see what we gain by inlining it  
> into
> nfs_kill_super..

Actually nfs4_kill_super didn't unregister the bdi.

> Also, I'm concerned about the growth of "if (version == X)" type
> constructs. We shouldn't be looking at the version number in order to
> figure out whether or not we're holding delegations, or whether or  
> not a
> particular daemon thread is running.
> AFAICS, in this case it should in any case be safe to call
> nfs_super_return_all_delegations() (as long as CONFIG_NFS_V4 is  
> defined
> - that we might want to fix). Ditto for  
> nfs4_renewd_prepare_shutdown().

That's all fine, but as I said in the cover letter, this patch may be  
dropped since the file system is still nfs4 under the covers, so I  
think nfs4_kill_super would be invoked anyway for "-t nfs -o vers=4".

>
> Cheers
>  Trond
>

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




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

end of thread, other threads:[~2009-08-30 17:04 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-08-30 16:34 [PATCH 0/5] Support "-t nfs,vers=4" mounts in the kernel Chuck Lever
     [not found] ` <20090830162211.3652.14638.stgit-RytpoXr2tKZ9HhUboXbp9zCvJB+x5qRC@public.gmane.org>
2009-08-30 16:34   ` [PATCH 1/5] NFS: combine nfs_kill_super() and nfs4_kill_super() Chuck Lever
     [not found]     ` <20090830163432.3652.437.stgit-RytpoXr2tKZ9HhUboXbp9zCvJB+x5qRC@public.gmane.org>
2009-08-30 16:42       ` Christoph Hellwig
2009-08-30 16:59         ` Trond Myklebust
     [not found]           ` <1251651593.12486.14.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2009-08-30 17:04             ` Chuck Lever
2009-08-30 16:34   ` [PATCH 2/5] NFS: Mount option parser should detect unset port values Chuck Lever
2009-08-30 16:34   ` [PATCH 3/5] NFS: Refactor NFSv4 text-based mount option validation Chuck Lever
2009-08-30 16:34   ` [PATCH 4/5] NFS: Move details of nfs4_get_sb() to a helper Chuck Lever
2009-08-30 16:35   ` [PATCH 5/5] NFS: Allow the "nfs" file system type to support NFSv4 Chuck Lever

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