]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
NFS: Add a way to disable NFS v4.0 via KConfig
authorAnna Schumaker <anna.schumaker@oracle.com>
Fri, 21 Nov 2025 19:53:50 +0000 (14:53 -0500)
committerAnna Schumaker <anna.schumaker@oracle.com>
Fri, 30 Jan 2026 16:42:20 +0000 (11:42 -0500)
I introduce NFS4_MIN_MINOR_VERSION as a parallel to
NFS4_MAX_MINOR_VERSION to check if NFS v4.0 has been compiled in and
return an appropriate error if not.

Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
fs/nfs/Kconfig
fs/nfs/Makefile
fs/nfs/fs_context.c
fs/nfs/nfs4_fs.h
fs/nfs/nfs4client.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4state.c
fs/nfs/nfs4xdr.c

index 07932ce9246c177a57ffe510d2b6920ad5925d31..058ed67b98cc6b8636612f7f6ac359974038e4ca 100644 (file)
@@ -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
index d05e69c00fe1e3ef8feaa5a77047c76fcc0aec00..6a9aaf2f913bddaac2c7be1586c10241e1087b62 100644 (file)
@@ -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
 
index b4679b7161b0968810e13f57c889052ea015bf56..86750f1100533e26ba315b3a5fabc5025cd7df96 100644 (file)
@@ -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;
index a5dd4a837769541cb73d4fc828240c04e55451d0..5a6728acb58971389a4571959281201b3a5f1d73 100644 (file)
 #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)
index c376b2420b6cf205bbd28ff98d7fac7c4682aab5..00b57e55aba800b1abda03c89724b49ae1653fe9 100644 (file)
@@ -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;
        }
index c621294e3f0f42072fb00a105630aede10daef31..3ee5394aca724893fd2a1df7375f7ad2a6c26a22 100644 (file)
@@ -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
index f3d441bb28af8b1cfb90446886119f5be1154c1e..3330a188e1a57542dcfd69370497628003b26279 100644 (file)
@@ -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;
index b6fe30577fab5781db120f2c544e7fe8d1ce5713..85ddcee51162ff9f4f9f5986945a840b433b70cd 100644 (file)
@@ -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),