Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 764302cc authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust
Browse files

NFS: Allow the "nfs" file system type to support NFSv4



When mounting an "nfs" type file system, recognize "v4," "vers=4," or
"nfsvers=4" mount options, and convert the file system to "nfs4" under
the covers.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
[trondmy: fixed up binary mount code so it sets the 'version' field too]
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent a6fe23be
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -68,6 +68,7 @@ struct nfs_parsed_mount_data {
	unsigned int		auth_flavor_len;
	unsigned int		auth_flavor_len;
	rpc_authflavor_t	auth_flavors[1];
	rpc_authflavor_t	auth_flavors[1];
	char			*client_address;
	char			*client_address;
	unsigned int		version;
	unsigned int		minorversion;
	unsigned int		minorversion;
	char			*fscache_uniq;
	char			*fscache_uniq;


+46 −2
Original line number Original line Diff line number Diff line
@@ -73,7 +73,7 @@ enum {
	Opt_cto, Opt_nocto,
	Opt_cto, Opt_nocto,
	Opt_ac, Opt_noac,
	Opt_ac, Opt_noac,
	Opt_lock, Opt_nolock,
	Opt_lock, Opt_nolock,
	Opt_v2, Opt_v3,
	Opt_v2, Opt_v3, Opt_v4,
	Opt_udp, Opt_tcp, Opt_rdma,
	Opt_udp, Opt_tcp, Opt_rdma,
	Opt_acl, Opt_noacl,
	Opt_acl, Opt_noacl,
	Opt_rdirplus, Opt_nordirplus,
	Opt_rdirplus, Opt_nordirplus,
@@ -127,6 +127,7 @@ static const match_table_t nfs_mount_option_tokens = {
	{ Opt_nolock, "nolock" },
	{ Opt_nolock, "nolock" },
	{ Opt_v2, "v2" },
	{ Opt_v2, "v2" },
	{ Opt_v3, "v3" },
	{ Opt_v3, "v3" },
	{ Opt_v4, "v4" },
	{ Opt_udp, "udp" },
	{ Opt_udp, "udp" },
	{ Opt_tcp, "tcp" },
	{ Opt_tcp, "tcp" },
	{ Opt_rdma, "rdma" },
	{ Opt_rdma, "rdma" },
@@ -934,10 +935,18 @@ static int nfs_parse_mount_options(char *raw,
			break;
			break;
		case Opt_v2:
		case Opt_v2:
			mnt->flags &= ~NFS_MOUNT_VER3;
			mnt->flags &= ~NFS_MOUNT_VER3;
			mnt->version = 2;
			break;
			break;
		case Opt_v3:
		case Opt_v3:
			mnt->flags |= NFS_MOUNT_VER3;
			mnt->flags |= NFS_MOUNT_VER3;
			mnt->version = 3;
			break;
			break;
#ifdef CONFIG_NFS_V4
		case Opt_v4:
			mnt->flags &= ~NFS_MOUNT_VER3;
			mnt->version = 4;
			break;
#endif
		case Opt_udp:
		case Opt_udp:
			mnt->flags &= ~NFS_MOUNT_TCP;
			mnt->flags &= ~NFS_MOUNT_TCP;
			mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
			mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
@@ -1151,10 +1160,18 @@ static int nfs_parse_mount_options(char *raw,
			switch (option) {
			switch (option) {
			case NFS2_VERSION:
			case NFS2_VERSION:
				mnt->flags &= ~NFS_MOUNT_VER3;
				mnt->flags &= ~NFS_MOUNT_VER3;
				mnt->version = 2;
				break;
				break;
			case NFS3_VERSION:
			case NFS3_VERSION:
				mnt->flags |= NFS_MOUNT_VER3;
				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;
				break;
#endif
			default:
			default:
				goto out_invalid_value;
				goto out_invalid_value;
			}
			}
@@ -1629,6 +1646,7 @@ static int nfs_validate_mount_data(void *options,
	args->nfs_server.protocol = XPRT_TRANSPORT_TCP;
	args->nfs_server.protocol = XPRT_TRANSPORT_TCP;
	args->auth_flavors[0]	= RPC_AUTH_UNIX;
	args->auth_flavors[0]	= RPC_AUTH_UNIX;
	args->auth_flavor_len	= 1;
	args->auth_flavor_len	= 1;
	args->minorversion	= 0;


	switch (data->version) {
	switch (data->version) {
	case 1:
	case 1:
@@ -1650,8 +1668,11 @@ static int nfs_validate_mount_data(void *options,
			if (data->root.size > NFS3_FHSIZE || data->root.size == 0)
			if (data->root.size > NFS3_FHSIZE || data->root.size == 0)
				goto out_invalid_fh;
				goto out_invalid_fh;
			mntfh->size = data->root.size;
			mntfh->size = data->root.size;
		} else
			args->version = 3;
		} else {
			mntfh->size = NFS2_FHSIZE;
			mntfh->size = NFS2_FHSIZE;
			args->version = 2;
		}




		memcpy(mntfh->data, data->root.data, mntfh->size);
		memcpy(mntfh->data, data->root.data, mntfh->size);
@@ -1726,6 +1747,14 @@ static int nfs_validate_mount_data(void *options,
		if (!nfs_verify_server_address(sap))
		if (!nfs_verify_server_address(sap))
			goto out_no_address;
			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(sap, args->nfs_server.port, 0);
		nfs_set_default_port(sap, args->nfs_server.port, 0);


		nfs_set_mount_transport_protocol(args);
		nfs_set_mount_transport_protocol(args);
@@ -1774,6 +1803,12 @@ static int nfs_validate_mount_data(void *options,
	return -EPROTONOSUPPORT;
	return -EPROTONOSUPPORT;
#endif /* !CONFIG_NFS_V3 */
#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:
out_nomem:
	dfprintk(MOUNT, "NFS: not enough memory to handle mount options\n");
	dfprintk(MOUNT, "NFS: not enough memory to handle mount options\n");
	return -ENOMEM;
	return -ENOMEM;
@@ -2069,6 +2104,14 @@ static int nfs_get_sb(struct file_system_type *fs_type,
	if (error < 0)
	if (error < 0)
		goto out;
		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 */
	/* Get a volume representation */
	server = nfs_create_server(data, mntfh);
	server = nfs_create_server(data, mntfh);
	if (IS_ERR(server)) {
	if (IS_ERR(server)) {
@@ -2320,6 +2363,7 @@ static int nfs4_validate_mount_data(void *options,
	args->nfs_server.port	= NFS_UNSPEC_PORT;
	args->nfs_server.port	= NFS_UNSPEC_PORT;
	args->auth_flavors[0]	= RPC_AUTH_UNIX;
	args->auth_flavors[0]	= RPC_AUTH_UNIX;
	args->auth_flavor_len	= 1;
	args->auth_flavor_len	= 1;
	args->version		= 4;
	args->minorversion	= 0;
	args->minorversion	= 0;


	switch (data->version) {
	switch (data->version) {
+1 −0
Original line number Original line Diff line number Diff line
@@ -472,6 +472,7 @@ enum lock_type4 {


#define NFSPROC4_NULL 0
#define NFSPROC4_NULL 0
#define NFSPROC4_COMPOUND 1
#define NFSPROC4_COMPOUND 1
#define NFS4_VERSION 4
#define NFS4_MINOR_VERSION 0
#define NFS4_MINOR_VERSION 0


#if defined(CONFIG_NFS_V4_1)
#if defined(CONFIG_NFS_V4_1)