* [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