* [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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.