From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.sourceforge.net (lists.sourceforge.net [216.105.38.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 712B6CD3427 for ; Thu, 7 May 2026 08:55:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type:Cc: Reply-To:From:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:Subject:To:In-Reply-To:References:Message-Id: MIME-Version:Date:Sender:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=bV0vC4k+dDgvW9BpewnPpib5wKtTgMSRQJGUajPj2co=; b=N/u+3gduTLh9RDimjZwhH2UZLs K67tcd4j8V2keWS/GFSRWP/ksbZHCVz3aT5wv2SVdS3Y9A8Qn1ZEtpRXPz/25BO8EMYeNntF8uC62 8tm8oZJvWmMjch26yeD1oQicUItOSkKXs7eFeBaZdIkn42IBLc7zte0d5DcMYlyh3KDI=; Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1wKuVl-0005oa-52; Thu, 07 May 2026 08:55:13 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1wKuVj-0005oP-59 for linux-f2fs-devel@lists.sourceforge.net; Thu, 07 May 2026 08:55:11 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Cc:To:In-Reply-To:References:Message-Id: Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date:From:Sender: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=HJGau91+wm3B0Hu4oOfxHELfpc0sGg4AqJj1ap+HOhU=; b=lxQ8Wn2yFY9qBpSgFBpMNpamvK oqnCG6a770TopkLIpxdLnCPCXTxLxjWG6EmUGzfPklSXYPKYnoCj5aOw4KeoYFH/mugqGrvTRJ+cw 6tTi8liXrkYM1lg8B+B5+P1DTSvnsr/Lrv8hTY2t40zQu6XcarN/OR/A0KBJXrmZSXt0=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Cc:To:In-Reply-To:References:Message-Id:Content-Transfer-Encoding: Content-Type:MIME-Version:Subject:Date:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=HJGau91+wm3B0Hu4oOfxHELfpc0sGg4AqJj1ap+HOhU=; b=IyGoGwCGGHSwL/jc/vk2dRwtoj whxmxKDyktMeEU3xiTTz8kPk4o71bA3OBHBElNibg0vQs9jVOAFT6J+c1D47TAuF2rUtyurQ+F3Ot OVQiOMQcZtTVIJpmZcxWU0QL2CK+hgHOx5kSAXJii0LoiYrvHvHVljaDlV45W0Jkw6wE=; Received: from sea.source.kernel.org ([172.234.252.31]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1wKuVh-0002Fe-HN for linux-f2fs-devel@lists.sourceforge.net; Thu, 07 May 2026 08:55:11 +0000 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sea.source.kernel.org (Postfix) with ESMTP id 424E743A4F; Thu, 7 May 2026 08:54:59 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 578EEC2BCB8; Thu, 7 May 2026 08:54:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1778144099; bh=2NSf4+7qlZ+vT9eKp/7+cdSDZGq8xAtKJ25Ppiig/ZA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Rz21vbS1Dzn21SPmuV2qO235tZA708gsw+xwkomBOle62yk0tt7cYzAApb3F/Mqp+ 7srcgcnavL7JG/QHhtKrg2Byu0i21OoPcYmkeqt+GTXSNVpT/5+ChKlsi6YaB0I12B 9kexGMxMU1G3r+u9mB6znKU5SsZSvK1IUjxN2ooilV+PSdGda1T1ZEG4Fywgc0qu1Z QLGwv4qYSN5W5QbQXb3PefB3Df+J57P2jUFIF4kyPnxluYFcnUzYddGAeqQS97Cvyl T8YKeHh3//3cfaU4HB9zqao9b4Hk0508UiyGGtWjHzYIBCYo57mEKBM9sb/kJw4Ofr K0a81VLKrw+8g== Date: Thu, 07 May 2026 04:53:06 -0400 MIME-Version: 1.0 Message-Id: <20260507-case-sensitivity-v14-13-e62cc8200435@oracle.com> References: <20260507-case-sensitivity-v14-0-e62cc8200435@oracle.com> In-Reply-To: <20260507-case-sensitivity-v14-0-e62cc8200435@oracle.com> To: Al Viro , Christian Brauner , Jan Kara X-Mailer: b4 0.16-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=8373; i=chuck.lever@oracle.com; h=from:subject:message-id; bh=2cQdKL/iRcH0yK5lMh63TGELmX0w6vyxoFnTaE/H7eE=; b=owEBbQKS/ZANAwAKATNqszNvZn+XAcsmYgBp/FL2cglHZ34suSkVQ1UwIwIr+9Gx/j2X5+9dY WpTJ8buvAyJAjMEAAEKAB0WIQQosuWwEobfJDzyPv4zarMzb2Z/lwUCafxS9gAKCRAzarMzb2Z/ lw+PEACafZrSIhJkaCK6hyJDlTikfWz0YTeSmzU35RhiI/FyHYWjw2VR9z5yy6+wyISbKHzK7rm nW60h1vWMoA7e09pIfjhSjVZlAXEj5ojeXWWwhkTkNyB1A0WRii5pBjsbueS9SnukPC7fnDBtjA GbU4MUbgAutvhTTTaJ4R6Vy3sq2r7mjM3CdLHgSJy5V7LF0iCr3XHxnEgyu3x8QA/4ZrieOMvke +4cvoIdm4dVE+Yi/C+gNFv7CM60gqm4W0Tj1TyQTAvDMC7+MgBRZ9g7YVssLKjKPl2o57/IUg94 /nu4mIBrm5sRRKWGnHZdlMovTxwI14wy3kGQEWeuIppYdZ7ce8b/grXgK/qvU3dyVmBNxKDIYQ/ q0Lfr/j6laKFwo/ADYBNZetCYapj59vx+EgpY3Ht+1+W3cwp704XzJxcq2whsbnf2ii1sgpvvNn 2AUHmgOp6TnW+2MC7TYbDQvPM4LyRplNLorCdqhBIxVOFSTay5fBuaSNlVmvIfN5Ytt5RRCdT4m BRJhuCA/mdtOqqEtMYMhpEMFK3wqyLJg9ZrO4njJAgGFwbYmyvENapJwvLZpGAkWnlTttAG6jV6 31sFZuA6CiK1CQYFgshTi9UxOOMRxUAvd0X1dAIpszpwPPufzKy2Ot8MshKKOr0o9oLtKwviymU VwYYPvJQgbra0Rg== X-Developer-Key: i=chuck.lever@oracle.com; a=openpgp; fpr=28B2E5B01286DF243CF23EFE336AB3336F667F97 X-Headers-End: 1wKuVh-0002Fe-HN Subject: [f2fs-dev] [PATCH v14 13/15] nfsd: Report export case-folding via NFSv3 PATHCONF X-BeenThere: linux-f2fs-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Chuck Lever via Linux-f2fs-devel Reply-To: Chuck Lever Cc: pc@manguebit.org, yuezhang.mo@sony.com, cem@kernel.org, Roland Mainz , almaz.alexandrovich@paragon-software.com, adilger.kernel@dilger.ca, linux-cifs@vger.kernel.org, sfrench@samba.org, slava@dubeyko.com, linux-ext4@vger.kernel.org, linkinjeon@kernel.org, sprasad@microsoft.com, frank.li@vivo.com, ronniesahlberg@gmail.com, glaubitz@physik.fu-berlin.de, jaegeuk@kernel.org, hirofumi@mail.parknet.co.jp, linux-nfs@vger.kernel.org, tytso@mit.edu, linux-api@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-xfs@vger.kernel.org, senozhatsky@chromium.org, Chuck Lever , hansg@kernel.org, anna@kernel.org, linux-fsdevel@vger.kernel.org, sj1557.seo@samsung.com, trondmy@kernel.org Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: linux-f2fs-devel-bounces@lists.sourceforge.net From: Chuck Lever The hard-coded MSDOS_SUPER_MAGIC check in nfsd3_proc_pathconf() only recognizes FAT filesystems as case-insensitive. Modern filesystems like F2FS, exFAT, and CIFS support case-insensitive directories, but NFSv3 clients cannot discover this capability. Query the export's actual case behavior through ->fileattr_get instead. This allows NFSv3 clients to correctly handle case sensitivity for any filesystem that implements the fileattr interface. Filesystems without ->fileattr_get continue to report the default POSIX behavior (case-sensitive, case-preserving). This change depends on the earlier "fat: Implement fileattr_get for case sensitivity" patch in this series, which ensures FAT filesystems report their case behavior correctly via the fileattr interface. Case-folding is a per-directory property, so nfsd_get_case_info() queries the parent dentry for non-directory filehandles. Three inherent corner cases follow: a single-file export's parent lies outside the exported subtree, so the LSM hook evaluates against an unexported directory; a disconnected dentry from fh_verify() has d_parent == itself, so the file's own attributes are reported until the dentry connects; and a hardlinked file resolves through the alias the dcache currently holds, so when the inode is linked into both case-folded and case-sensitive directories the reported value tracks whichever parent is active. These limitations are not addressable without redefining the protocol attribute as per-parent rather than per-object. RFC 1813 restricts PATHCONF errors to NFS3ERR_STALE, NFS3ERR_BADHANDLE, and NFS3ERR_SERVERFAULT. When an LSM hook denies the case-folding query on the parent, NFS3ERR_STALE is the only correct mapping: NFS3ERR_SERVERFAULT misrepresents a working server as broken, and NFS3ERR_BADHANDLE implies a decoding failure that did not occur. A client purging the filehandle on receipt is the desired outcome, since the server has refused to read attributes through it. Substituting POSIX defaults instead would let the same handle report casefold=false now and casefold=true once policy permits, opening a silent name-collision window on case-insensitive exports. Reviewed-by: Roland Mainz Signed-off-by: Chuck Lever --- fs/nfsd/nfs3proc.c | 36 +++++++++++++++++----- fs/nfsd/vfs.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/nfsd/vfs.h | 3 ++ fs/nfsd/xdr3.h | 4 +-- 4 files changed, 121 insertions(+), 10 deletions(-) diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index 42adc5461db0..12b9172c6be1 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -710,23 +710,43 @@ nfsd3_proc_pathconf(struct svc_rqst *rqstp) resp->p_name_max = 255; /* at least */ resp->p_no_trunc = 0; resp->p_chown_restricted = 1; - resp->p_case_insensitive = 0; - resp->p_case_preserving = 1; + resp->p_case_insensitive = false; + resp->p_case_preserving = true; resp->status = fh_verify(rqstp, &argp->fh, 0, NFSD_MAY_NOP); if (resp->status == nfs_ok) { struct super_block *sb = argp->fh.fh_dentry->d_sb; + int err; - /* Note that we don't care for remote fs's here */ - switch (sb->s_magic) { - case EXT2_SUPER_MAGIC: + if (sb->s_magic == EXT2_SUPER_MAGIC) { resp->p_link_max = EXT2_LINK_MAX; resp->p_name_max = EXT2_NAME_LEN; + } + + err = nfsd_get_case_info(argp->fh.fh_dentry, + &resp->p_case_insensitive, + &resp->p_case_preserving); + /* + * RFC 1813 lists NFS3ERR_STALE, NFS3ERR_BADHANDLE, and + * NFS3ERR_SERVERFAULT as the only PATHCONF errors. + */ + switch (err) { + case 0: + case -EOPNOTSUPP: + /* Both arms leave the output booleans valid. */ break; - case MSDOS_SUPER_MAGIC: - resp->p_case_insensitive = 1; - resp->p_case_preserving = 0; + case -EACCES: + case -EPERM: + /* + * Policy denied the query. Report STALE so the + * handle is unusable without implying a server + * malfunction. + */ + resp->status = nfserr_stale; + break; + default: + resp->status = nfserr_serverfault; break; } } diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index eafdf7b7890f..85ff418127c7 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "xdr3.h" @@ -2891,3 +2892,90 @@ nfsd_permission(struct svc_cred *cred, struct svc_export *exp, return err? nfserrno(err) : 0; } + +/** + * nfsd_get_case_info - get case sensitivity info for a dentry + * @dentry: dentry to query + * @case_insensitive: set to true if name comparison ignores case + * @case_preserving: set to true if case is preserved on disk + * + * On casefold-capable filesystems the flag lives on the directory, + * not on its entries, so for a non-directory @dentry the parent is + * queried instead. A directory (including an export root, whose + * parent lies outside the export) is queried as-is so its own + * contents' lookup behavior is reported. NFSD advertises + * fattr4_homogeneous as FALSE, so per-directory answers may differ + * within an export. + * + * The probe runs with kernel credentials. case_insensitive and + * case_preserving describe the directory's structural lookup + * behavior, not the caller's identity; running under the calling + * client's mapped credentials would let per-client MAC policy on + * the parent directory turn this query into NFS4ERR_ACCESS even + * though the underlying property is the same for every client. + * + * When the filesystem does not expose case-folding state (no + * ->fileattr_get, or the callback returns -EOPNOTSUPP / + * -ENOIOCTLCMD / -ENOTTY / -EINVAL), the outputs are filled with + * POSIX defaults (case-sensitive, case-preserving) on the premise + * that a filesystem with case-folding support wires up + * fileattr_get. + * + * Return: 0 with outputs filled, -EOPNOTSUPP with outputs filled + * to POSIX defaults, or a negative errno (e.g., -EIO, + * -ESTALE, -ENOMEM) with outputs unmodified. + */ +int +nfsd_get_case_info(struct dentry *dentry, bool *case_insensitive, + bool *case_preserving) +{ + struct file_kattr fa = {}; + const struct cred *saved; + struct cred *probe; + struct dentry *cd; + bool put = false; + int err; + + if (d_is_dir(dentry)) { + cd = dentry; + } else { + cd = dget_parent(dentry); + put = true; + } + + probe = prepare_creds(); + if (!probe) { + err = -ENOMEM; + goto out; + } + probe->fsuid = GLOBAL_ROOT_UID; + probe->fsgid = GLOBAL_ROOT_GID; + saved = override_creds(probe); + + err = vfs_fileattr_get(cd, &fa); + + put_cred(revert_creds(saved)); +out: + if (put) + dput(cd); + switch (err) { + case 0: + *case_insensitive = fa.fsx_xflags & FS_XFLAG_CASEFOLD; + *case_preserving = + !(fa.fsx_xflags & FS_XFLAG_CASENONPRESERVING); + return 0; + case -EINVAL: + case -ENOTTY: + case -ENOIOCTLCMD: + case -EOPNOTSUPP: + /* + * Filesystem does not expose case state. + * Report POSIX defaults. + */ + *case_insensitive = false; + *case_preserving = true; + return -EOPNOTSUPP; + default: + return err; + } +} diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index 702a844f2106..e09ea04a51b9 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -156,6 +156,9 @@ __be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *, loff_t *, struct readdir_cd *, nfsd_filldir_t); __be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *, struct kstatfs *, int access); +int nfsd_get_case_info(struct dentry *dentry, + bool *case_insensitive, + bool *case_preserving); __be32 nfsd_permission(struct svc_cred *cred, struct svc_export *exp, struct dentry *dentry, int acc); diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h index 522067b7fd75..a7c9714b0b0e 100644 --- a/fs/nfsd/xdr3.h +++ b/fs/nfsd/xdr3.h @@ -209,8 +209,8 @@ struct nfsd3_pathconfres { __u32 p_name_max; __u32 p_no_trunc; __u32 p_chown_restricted; - __u32 p_case_insensitive; - __u32 p_case_preserving; + bool p_case_insensitive; + bool p_case_preserving; }; struct nfsd3_commitres { -- 2.53.0 _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel