]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
nfs: Skip pathconf probe when neither field is consumed
authorChuck Lever <chuck.lever@oracle.com>
Fri, 15 May 2026 15:35:11 +0000 (11:35 -0400)
committerChristian Brauner <brauner@kernel.org>
Fri, 15 May 2026 15:49:22 +0000 (17:49 +0200)
The PATHCONF RPC issued from nfs_probe_fsinfo() supplies two pieces of
information: max_namelen, used only when server->namelen has not been
pinned by mount options, and the case_insensitive / case_preserving
fields, used only by the NFSv2/NFSv3 path. NFSv4 receives its case
sensitivity caps from the FATTR4_CASE_* attributes during the
set_capabilities probe, and a non-zero server->namelen short-circuits
the only other field of interest.

When both conditions hold (NFSv4 with namelen pinned), the pathconf
reply is discarded in full but the round-trip is still on the mount
critical path. Gate the call on version < 4 || namelen == 0 so that
mounts which cannot benefit from the reply do not pay for it.

Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260507-case-sensitivity-v14-0-e62cc8200435@oracle.com?part=10
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Link: https://patch.msgid.link/20260515153515.362266-4-cel@kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/nfs/client.c

index 28b66bb0dd33744079772f61752cee09a4af3e95..73b95318ba48b27c05975dc6150e8514f432b78e 100644 (file)
@@ -937,23 +937,25 @@ static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, str
        pathinfo.fattr = fattr;
        nfs_fattr_init(fattr);
 
-       if (clp->rpc_ops->pathconf(server, mntfh, &pathinfo) >= 0) {
-               if (server->namelen == 0)
-                       server->namelen = pathinfo.max_namelen;
-               if (clp->rpc_ops->version < 4) {
-                       unsigned int caps = server->caps;
-
-                       caps &= ~(NFS_CAP_CASE_INSENSITIVE |
-                                 NFS_CAP_CASE_NONPRESERVING);
-                       if (pathinfo.case_insensitive)
-                               caps |= NFS_CAP_CASE_INSENSITIVE;
-                       if (!pathinfo.case_preserving)
-                               caps |= NFS_CAP_CASE_NONPRESERVING;
-                       server->caps = caps;
+       if (clp->rpc_ops->version < 4 || server->namelen == 0) {
+               if (clp->rpc_ops->pathconf(server, mntfh, &pathinfo) >= 0) {
+                       if (server->namelen == 0)
+                               server->namelen = pathinfo.max_namelen;
+                       if (clp->rpc_ops->version < 4) {
+                               unsigned int caps = server->caps;
+
+                               caps &= ~(NFS_CAP_CASE_INSENSITIVE |
+                                         NFS_CAP_CASE_NONPRESERVING);
+                               if (pathinfo.case_insensitive)
+                                       caps |= NFS_CAP_CASE_INSENSITIVE;
+                               if (!pathinfo.case_preserving)
+                                       caps |= NFS_CAP_CASE_NONPRESERVING;
+                               server->caps = caps;
+                       }
+               } else if (clp->rpc_ops->version < 4) {
+                       server->caps &= ~(NFS_CAP_CASE_INSENSITIVE |
+                                         NFS_CAP_CASE_NONPRESERVING);
                }
-       } else if (clp->rpc_ops->version < 4) {
-               server->caps &= ~(NFS_CAP_CASE_INSENSITIVE |
-                                 NFS_CAP_CASE_NONPRESERVING);
        }
 
        if (clp->rpc_ops->discover_trunking != NULL &&