summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/Kconfig9
-rw-r--r--fs/nfs/Makefile3
-rw-r--r--fs/nfs/fs_context.c3
-rw-r--r--fs/nfs/nfs4_fs.h6
-rw-r--r--fs/nfs/nfs4client.c3
-rw-r--r--fs/nfs/nfs4proc.c2
-rw-r--r--fs/nfs/nfs4state.c2
-rw-r--r--fs/nfs/nfs4xdr.c24
8 files changed, 47 insertions, 5 deletions
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index 07932ce9246c..058ed67b98cc 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -96,6 +96,15 @@ config NFS_SWAP
help
This option enables swapon to work on files located on NFS mounts.
+config NFS_V4_0
+ bool "NFS client support for NFSv4.0"
+ depends on NFS_V4
+ help
+ This option enables support for minor version 0 of the NFSv4 protocol
+ (RFC 3530) in the kernel's NFS client.
+
+ If unsure, say N.
+
config NFS_V4_1
bool "NFS client support for NFSv4.1"
depends on NFS_V4
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index d05e69c00fe1..6a9aaf2f913b 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -27,9 +27,10 @@ CFLAGS_nfs4trace.o += -I$(src)
nfsv4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o \
delegation.o nfs4idmap.o callback.o callback_xdr.o callback_proc.o \
nfs4namespace.o nfs4getroot.o nfs4client.o nfs4session.o \
- dns_resolve.o nfs4trace.o nfs40proc.o nfs40client.o
+ dns_resolve.o nfs4trace.o
nfsv4-$(CONFIG_NFS_USE_LEGACY_DNS) += cache_lib.o
nfsv4-$(CONFIG_SYSCTL) += nfs4sysctl.o
+nfsv4-$(CONFIG_NFS_V4_0) += nfs40client.o nfs40proc.o
nfsv4-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o pnfs_nfs.o
nfsv4-$(CONFIG_NFS_V4_2) += nfs42proc.o nfs42xattr.o
diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c
index b4679b7161b0..86750f110053 100644
--- a/fs/nfs/fs_context.c
+++ b/fs/nfs/fs_context.c
@@ -806,7 +806,8 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
ctx->mount_server.version = result.uint_32;
break;
case Opt_minorversion:
- if (result.uint_32 > NFS4_MAX_MINOR_VERSION)
+ if (result.uint_32 < NFS4_MIN_MINOR_VERSION ||
+ result.uint_32 > NFS4_MAX_MINOR_VERSION)
goto out_of_bounds;
ctx->minorversion = result.uint_32;
break;
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index a5dd4a837769..5a6728acb589 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -10,6 +10,12 @@
#ifndef __LINUX_FS_NFS_NFS4_FS_H
#define __LINUX_FS_NFS_NFS4_FS_H
+#if defined(CONFIG_NFS_V4_0)
+#define NFS4_MIN_MINOR_VERSION 0
+#else
+#define NFS4_MIN_MINOR_VERSION 1
+#endif
+
#if defined(CONFIG_NFS_V4_2)
#define NFS4_MAX_MINOR_VERSION 2
#elif defined(CONFIG_NFS_V4_1)
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index c376b2420b6c..00b57e55aba8 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -203,7 +203,8 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init)
if (err)
goto error;
- if (cl_init->minorversion > NFS4_MAX_MINOR_VERSION) {
+ if (cl_init->minorversion < NFS4_MIN_MINOR_VERSION ||
+ cl_init->minorversion > NFS4_MAX_MINOR_VERSION) {
err = -EINVAL;
goto error;
}
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index c621294e3f0f..3ee5394aca72 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -10591,7 +10591,9 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
#endif
const struct nfs4_minor_version_ops *nfs_v4_minor_ops[] = {
+#if defined(CONFIG_NFS_V4_0)
[0] = &nfs_v4_0_minor_ops,
+#endif /* CONFIG_NFS_V4_0 */
#if defined(CONFIG_NFS_V4_1)
[1] = &nfs_v4_1_minor_ops,
#endif
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index f3d441bb28af..3330a188e1a5 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1804,9 +1804,11 @@ static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
switch (error) {
case 0:
break;
+#if IS_ENABLED(CONFIG_NFS_V4_0)
case -NFS4ERR_CB_PATH_DOWN:
nfs40_handle_cb_pathdown(clp);
break;
+#endif /* CONFIG_NFS_V4_0 */
case -NFS4ERR_NO_GRACE:
nfs4_state_end_reclaim_reboot(clp);
break;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index b6fe30577fab..85ddcee51162 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1399,11 +1399,13 @@ static void encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *ar
xdr_encode_hyper(p, nfs4_lock_length(args->fl));
}
+#if defined(CONFIG_NFS_V4_0)
static void encode_release_lockowner(struct xdr_stream *xdr, const struct nfs_lowner *lowner, struct compound_hdr *hdr)
{
encode_op_hdr(xdr, OP_RELEASE_LOCKOWNER, decode_release_lockowner_maxsz, hdr);
encode_lockowner(xdr, lowner);
}
+#endif /* CONFIG_NFS_V4_0 */
static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
{
@@ -2583,6 +2585,7 @@ static void nfs4_xdr_enc_locku(struct rpc_rqst *req, struct xdr_stream *xdr,
encode_nops(&hdr);
}
+#if defined(CONFIG_NFS_V4_0)
static void nfs4_xdr_enc_release_lockowner(struct rpc_rqst *req,
struct xdr_stream *xdr,
const void *data)
@@ -2596,6 +2599,7 @@ static void nfs4_xdr_enc_release_lockowner(struct rpc_rqst *req,
encode_release_lockowner(xdr, &args->lock_owner, &hdr);
encode_nops(&hdr);
}
+#endif /* CONFIG_NFS_V4_0 */
/*
* Encode a READLINK request
@@ -2825,6 +2829,7 @@ static void nfs4_xdr_enc_server_caps(struct rpc_rqst *req,
/*
* a RENEW request
*/
+#if defined(CONFIG_NFS_V4_0)
static void nfs4_xdr_enc_renew(struct rpc_rqst *req, struct xdr_stream *xdr,
const void *data)
@@ -2838,6 +2843,7 @@ static void nfs4_xdr_enc_renew(struct rpc_rqst *req, struct xdr_stream *xdr,
encode_renew(xdr, clp->cl_clientid, &hdr);
encode_nops(&hdr);
}
+#endif /* CONFIG_NFS_V4_0 */
/*
* a SETCLIENTID request
@@ -5224,10 +5230,12 @@ static int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res)
return status;
}
+#if defined(CONFIG_NFS_V4_0)
static int decode_release_lockowner(struct xdr_stream *xdr)
{
return decode_op_hdr(xdr, OP_RELEASE_LOCKOWNER);
}
+#endif /* CONFIG_NFS_V4_0 */
static int decode_lookup(struct xdr_stream *xdr)
{
@@ -6930,6 +6938,7 @@ out:
return status;
}
+#if defined(CONFIG_NFS_V4_0)
static int nfs4_xdr_dec_release_lockowner(struct rpc_rqst *rqstp,
struct xdr_stream *xdr, void *dummy)
{
@@ -6941,6 +6950,7 @@ static int nfs4_xdr_dec_release_lockowner(struct rpc_rqst *rqstp,
status = decode_release_lockowner(xdr);
return status;
}
+#endif /* CONFIG_NFS_V4_0 */
/*
* Decode READLINK response
@@ -7162,6 +7172,7 @@ out:
/*
* Decode RENEW response
*/
+#if defined(CONFIG_NFS_V4_0)
static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
void *__unused)
{
@@ -7173,6 +7184,7 @@ static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
status = decode_renew(xdr);
return status;
}
+#endif /* CONFIG_NFS_V4_0 */
/*
* Decode SETCLIENTID response
@@ -7754,6 +7766,14 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
.p_name = #proc, \
}
+#if defined(CONFIG_NFS_V4_0)
+#define PROC40(proc, argtype, restype) \
+ PROC(proc, argtype, restype)
+#else
+#define PROC40(proc, argtype, restype) \
+ STUB(proc)
+#endif /* CONFIG_NFS_V4_0 */
+
#if defined(CONFIG_NFS_V4_1)
#define PROC41(proc, argtype, restype) \
PROC(proc, argtype, restype)
@@ -7781,7 +7801,7 @@ const struct rpc_procinfo nfs4_procedures[] = {
PROC(CLOSE, enc_close, dec_close),
PROC(SETATTR, enc_setattr, dec_setattr),
PROC(FSINFO, enc_fsinfo, dec_fsinfo),
- PROC(RENEW, enc_renew, dec_renew),
+ PROC40(RENEW, enc_renew, dec_renew),
PROC(SETCLIENTID, enc_setclientid, dec_setclientid),
PROC(SETCLIENTID_CONFIRM, enc_setclientid_confirm, dec_setclientid_confirm),
PROC(LOCK, enc_lock, dec_lock),
@@ -7805,7 +7825,7 @@ const struct rpc_procinfo nfs4_procedures[] = {
PROC(GETACL, enc_getacl, dec_getacl),
PROC(SETACL, enc_setacl, dec_setacl),
PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations),
- PROC(RELEASE_LOCKOWNER, enc_release_lockowner, dec_release_lockowner),
+ PROC40(RELEASE_LOCKOWNER, enc_release_lockowner, dec_release_lockowner),
PROC(SECINFO, enc_secinfo, dec_secinfo),
PROC(FSID_PRESENT, enc_fsid_present, dec_fsid_present),
PROC41(EXCHANGE_ID, enc_exchange_id, dec_exchange_id),