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 CCA2BD3EE86 for ; Thu, 22 Jan 2026 16:03:53 +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:MIME-Version:References:In-Reply-To: Message-ID:Date:To:Sender:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=UAK/Zur7CHTkyjNphJJWUtf2kkxF3ezM/M/S6gRozV8=; b=CEk40Wqofp2gFirlqBcMnGe2Mh lXG01Mb8F1Kbook/6hMjMjOBz+Y2AUO1NahRY+TDVryH0hJoRT5gQLUlVju6pdE8p+u31Khyija4k W5FxVBAIqFqQFkEYbCkzt2z4NxuxF84JDTCycQ4mUdHE2W1VdMV0DCDRtuiJuidU0Ov0=; Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1vixA0-0004Y4-Ms; Thu, 22 Jan 2026 16:03:53 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1vix9z-0004Xn-Ab for linux-f2fs-devel@lists.sourceforge.net; Thu, 22 Jan 2026 16:03:52 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: 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=pNyyDxVl0CQPZfpkWS62q/QEQSVwIdM0eK7RcDzbudY=; b=klfcaXROAlSng8Pewx263fBEKh CDMLYKQZH2ejo4zsIzoO0iqTYaOx7BGeMBnadzdxWlvInWWsygqPyVzxrjn4TqC0uOwS8HtG5MK9c +fhzogQA/A9VtGIgqVmrfknG2rBaWACGMRl4nQR7qrXSPUaIAElwxSu2bwn0kcXIKwKU=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: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=pNyyDxVl0CQPZfpkWS62q/QEQSVwIdM0eK7RcDzbudY=; b=f1uE6EfTw+NwL/rAy4ni0hGNAc tRJuC3RRQKl7G3zmjBgGqKB55PPwsTeIxUjWtwjeJiHyGX3cy2StdNXOkRQwWgwXt2XaIRdAklUUA ePafMg21LtQ6VBnkzpO80GpjJ9n+4pZ8P9Qy7GhG50IXSdWIZWNZUR1oLekGXO0VkjW8=; 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 1vix9z-0000WO-Do for linux-f2fs-devel@lists.sourceforge.net; Thu, 22 Jan 2026 16:03:52 +0000 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sea.source.kernel.org (Postfix) with ESMTP id 26B8244388; Thu, 22 Jan 2026 16:03:41 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id AA1CFC19422; Thu, 22 Jan 2026 16:03:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1769097821; bh=qLtSl/hzug0iezWDJ52LTln03Jl9ZBIsucwCCdyP8wA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XrCkvb+70GVLgMaGG2OPpiPrCEtB1ljxpVnh45IsgcYOMESU5mfooF0aufdqzLrRV 4v/2O/Wy+cWos+307a7w3moHtllQFNGA3TH5ysy39JHww3H7zhD2TyI1K9utoyv0iL oxxg4gRF2XjMN3GNv3YJryjKPFx8bv3NY4Cic5LrcmunBFw6mLbJc+TRVLvu4RzBq2 xuc3T5MZvB2CisAJrgCaXqFjPG+hg9dmSeZ4TrRua2jW+bIFayY9ZMBPX53eGWKJHt cfXCBWiuzS7llsmQrwoTfEpnC9ZhevLncFUxhQ/CdKzEQmFPZcvW3W0i3KQ+qmUFIA z9XgPP1kgifMA== To: Al Viro , Christian Brauner , Jan Kara Date: Thu, 22 Jan 2026 11:03:05 -0500 Message-ID: <20260122160311.1117669-11-cel@kernel.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260122160311.1117669-1-cel@kernel.org> References: <20260122160311.1117669-1-cel@kernel.org> MIME-Version: 1.0 X-Headers-End: 1vix9z-0000WO-Do Subject: [f2fs-dev] [PATCH v7 10/16] nfs: Implement fileattr_get for case sensitivity 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, 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 An NFS server re-exporting an NFS mount point needs to report the case sensitivity behavior of the underlying filesystem to its clients. Without this, re-export servers cannot accurately convey case handling semantics, potentially causing client applications to make incorrect assumptions about filename collisions and lookups. The NFS client already retrieves case sensitivity information from servers during mount via PATHCONF (NFSv3) or the FATTR4_CASE_INSENSITIVE/FATTR4_CASE_PRESERVING attributes (NFSv4). Expose this information through fileattr_get by reporting the FS_XFLAG_CASEFOLD and FS_XFLAG_CASENONPRESERVING flags. NFSv2 lacks PATHCONF support, so mounts using that protocol version default to standard POSIX behavior: case-sensitive and case-preserving. Signed-off-by: Chuck Lever --- fs/nfs/client.c | 9 +++++++-- fs/nfs/inode.c | 20 ++++++++++++++++++++ fs/nfs/internal.h | 3 +++ fs/nfs/nfs3proc.c | 2 ++ fs/nfs/nfs3xdr.c | 7 +++++-- fs/nfs/nfs4proc.c | 2 ++ fs/nfs/proc.c | 3 +++ fs/nfs/symlink.c | 3 +++ include/linux/nfs_xdr.h | 2 ++ 9 files changed, 47 insertions(+), 4 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 2aaea9c98c2c..da437d89e14a 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -935,13 +935,18 @@ static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, str /* Get some general file system info */ if (server->namelen == 0) { - struct nfs_pathconf pathinfo; + struct nfs_pathconf pathinfo = { }; pathinfo.fattr = fattr; nfs_fattr_init(fattr); - if (clp->rpc_ops->pathconf(server, mntfh, &pathinfo) >= 0) + if (clp->rpc_ops->pathconf(server, mntfh, &pathinfo) >= 0) { server->namelen = pathinfo.max_namelen; + if (pathinfo.case_insensitive) + server->caps |= NFS_CAP_CASE_INSENSITIVE; + if (pathinfo.case_preserving) + server->caps |= NFS_CAP_CASE_PRESERVING; + } } if (clp->rpc_ops->discover_trunking != NULL && diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index de2cce1d08f4..77b4de8a1050 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "nfs4_fs.h" #include "callback.h" @@ -1102,6 +1103,25 @@ int nfs_getattr(struct mnt_idmap *idmap, const struct path *path, } EXPORT_SYMBOL_GPL(nfs_getattr); +/** + * nfs_fileattr_get - Retrieve file attributes + * @dentry: object to query + * @fa: file attributes to fill in + * + * Return: 0 on success + */ +int nfs_fileattr_get(struct dentry *dentry, struct file_kattr *fa) +{ + struct inode *inode = d_inode(dentry); + + if (nfs_server_capable(inode, NFS_CAP_CASE_INSENSITIVE)) + fa->fsx_xflags |= FS_XFLAG_CASEFOLD; + if (!nfs_server_capable(inode, NFS_CAP_CASE_PRESERVING)) + fa->fsx_xflags |= FS_XFLAG_CASENONPRESERVING; + return 0; +} +EXPORT_SYMBOL_GPL(nfs_fileattr_get); + static void nfs_init_lock_context(struct nfs_lock_context *l_ctx) { refcount_set(&l_ctx->count, 1); diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 2e596244799f..a843e076aad7 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -453,6 +453,9 @@ extern void nfs_set_cache_invalid(struct inode *inode, unsigned long flags); extern bool nfs_check_cache_invalid(struct inode *, unsigned long); extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode); +struct file_kattr; +int nfs_fileattr_get(struct dentry *dentry, struct file_kattr *fa); + #if IS_ENABLED(CONFIG_NFS_LOCALIO) /* localio.c */ struct nfs_local_dio { diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 1181f9cc6dbd..60344a83f400 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -1048,6 +1048,7 @@ static const struct inode_operations nfs3_dir_inode_operations = { .permission = nfs_permission, .getattr = nfs_getattr, .setattr = nfs_setattr, + .fileattr_get = nfs_fileattr_get, #ifdef CONFIG_NFS_V3_ACL .listxattr = nfs3_listxattr, .get_inode_acl = nfs3_get_acl, @@ -1059,6 +1060,7 @@ static const struct inode_operations nfs3_file_inode_operations = { .permission = nfs_permission, .getattr = nfs_getattr, .setattr = nfs_setattr, + .fileattr_get = nfs_fileattr_get, #ifdef CONFIG_NFS_V3_ACL .listxattr = nfs3_listxattr, .get_inode_acl = nfs3_get_acl, diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index e17d72908412..e745e78faab0 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -2276,8 +2276,11 @@ static int decode_pathconf3resok(struct xdr_stream *xdr, if (unlikely(!p)) return -EIO; result->max_link = be32_to_cpup(p++); - result->max_namelen = be32_to_cpup(p); - /* ignore remaining fields */ + result->max_namelen = be32_to_cpup(p++); + p++; /* ignore no_trunc */ + p++; /* ignore chown_restricted */ + result->case_insensitive = be32_to_cpup(p++) != 0; + result->case_preserving = be32_to_cpup(p) != 0; return 0; } diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index a0885ae55abc..7bb1ea77d20e 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -11072,6 +11072,7 @@ static const struct inode_operations nfs4_dir_inode_operations = { .getattr = nfs_getattr, .setattr = nfs_setattr, .listxattr = nfs4_listxattr, + .fileattr_get = nfs_fileattr_get, }; static const struct inode_operations nfs4_file_inode_operations = { @@ -11079,6 +11080,7 @@ static const struct inode_operations nfs4_file_inode_operations = { .getattr = nfs_getattr, .setattr = nfs_setattr, .listxattr = nfs4_listxattr, + .fileattr_get = nfs_fileattr_get, }; static struct nfs_server *nfs4_clone_server(struct nfs_server *source, diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index 39df80e4ae6f..48f02a80b800 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c @@ -597,6 +597,7 @@ nfs_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, { info->max_link = 0; info->max_namelen = NFS2_MAXNAMLEN; + info->case_preserving = true; return 0; } @@ -718,12 +719,14 @@ static const struct inode_operations nfs_dir_inode_operations = { .permission = nfs_permission, .getattr = nfs_getattr, .setattr = nfs_setattr, + .fileattr_get = nfs_fileattr_get, }; static const struct inode_operations nfs_file_inode_operations = { .permission = nfs_permission, .getattr = nfs_getattr, .setattr = nfs_setattr, + .fileattr_get = nfs_fileattr_get, }; const struct nfs_rpc_ops nfs_v2_clientops = { diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c index 58146e935402..74a072896f8d 100644 --- a/fs/nfs/symlink.c +++ b/fs/nfs/symlink.c @@ -22,6 +22,8 @@ #include #include +#include "internal.h" + /* Symlink caching in the page cache is even more simplistic * and straight-forward than readdir caching. */ @@ -74,4 +76,5 @@ const struct inode_operations nfs_symlink_inode_operations = { .get_link = nfs_get_link, .getattr = nfs_getattr, .setattr = nfs_setattr, + .fileattr_get = nfs_fileattr_get, }; diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 79fe2dfb470f..5f061a9db2c2 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -182,6 +182,8 @@ struct nfs_pathconf { struct nfs_fattr *fattr; /* Post-op attributes */ __u32 max_link; /* max # of hard links */ __u32 max_namelen; /* max name length */ + bool case_insensitive; + bool case_preserving; }; struct nfs4_change_info { -- 2.52.0 _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel