Commit 1ab5be4a authored by Trond Myklebust's avatar Trond Myklebust Committed by Anna Schumaker
Browse files

NFSv4: Add some support for case insensitive filesystems



Add capabilities to allow the NFS client to recognise when it is dealing
with case insensitive and case preserving filesystems.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent b05bf5c6
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -3840,7 +3840,9 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
		     FATTR4_WORD0_FH_EXPIRE_TYPE |
		     FATTR4_WORD0_LINK_SUPPORT |
		     FATTR4_WORD0_SYMLINK_SUPPORT |
		     FATTR4_WORD0_ACLSUPPORT;
		     FATTR4_WORD0_ACLSUPPORT |
		     FATTR4_WORD0_CASE_INSENSITIVE |
		     FATTR4_WORD0_CASE_PRESERVING;
	if (minorversion)
		bitmask[2] = FATTR4_WORD2_SUPPATTR_EXCLCREAT;

@@ -3869,6 +3871,10 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
			server->caps |= NFS_CAP_HARDLINKS;
		if (res.has_symlinks != 0)
			server->caps |= NFS_CAP_SYMLINKS;
		if (res.case_insensitive)
			server->caps |= NFS_CAP_CASE_INSENSITIVE;
		if (res.case_preserving)
			server->caps |= NFS_CAP_CASE_PRESERVING;
#ifdef CONFIG_NFS_V4_SECURITY_LABEL
		if (res.attr_bitmask[2] & FATTR4_WORD2_SECURITY_LABEL)
			server->caps |= NFS_CAP_SECURITY_LABEL;
+40 −0
Original line number Diff line number Diff line
@@ -3533,6 +3533,42 @@ static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint
	return 0;
}

static int decode_attr_case_insensitive(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
{
	__be32 *p;

	*res = 0;
	if (unlikely(bitmap[0] & (FATTR4_WORD0_CASE_INSENSITIVE - 1U)))
		return -EIO;
	if (likely(bitmap[0] & FATTR4_WORD0_CASE_INSENSITIVE)) {
		p = xdr_inline_decode(xdr, 4);
		if (unlikely(!p))
			return -EIO;
		*res = be32_to_cpup(p);
		bitmap[0] &= ~FATTR4_WORD0_CASE_INSENSITIVE;
	}
	dprintk("%s: case_insensitive=%s\n", __func__, *res == 0 ? "false" : "true");
	return 0;
}

static int decode_attr_case_preserving(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
{
	__be32 *p;

	*res = 0;
	if (unlikely(bitmap[0] & (FATTR4_WORD0_CASE_PRESERVING - 1U)))
		return -EIO;
	if (likely(bitmap[0] & FATTR4_WORD0_CASE_PRESERVING)) {
		p = xdr_inline_decode(xdr, 4);
		if (unlikely(!p))
			return -EIO;
		*res = be32_to_cpup(p);
		bitmap[0] &= ~FATTR4_WORD0_CASE_PRESERVING;
	}
	dprintk("%s: case_preserving=%s\n", __func__, *res == 0 ? "false" : "true");
	return 0;
}

static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid)
{
	__be32 *p;
@@ -4413,6 +4449,10 @@ static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_re
		goto xdr_error;
	if ((status = decode_attr_aclsupport(xdr, bitmap, &res->acl_bitmask)) != 0)
		goto xdr_error;
	if ((status = decode_attr_case_insensitive(xdr, bitmap, &res->case_insensitive)) != 0)
		goto xdr_error;
	if ((status = decode_attr_case_preserving(xdr, bitmap, &res->case_preserving)) != 0)
		goto xdr_error;
	if ((status = decode_attr_exclcreat_supported(xdr, bitmap,
				res->exclcreat_bitmask)) != 0)
		goto xdr_error;
+2 −0
Original line number Diff line number Diff line
@@ -271,6 +271,8 @@ struct nfs_server {
#define NFS_CAP_ACLS		(1U << 3)
#define NFS_CAP_ATOMIC_OPEN	(1U << 4)
#define NFS_CAP_LGOPEN		(1U << 5)
#define NFS_CAP_CASE_INSENSITIVE	(1U << 6)
#define NFS_CAP_CASE_PRESERVING	(1U << 7)
#define NFS_CAP_POSIX_LOCK	(1U << 14)
#define NFS_CAP_UIDGID_NOMAP	(1U << 15)
#define NFS_CAP_STATEID_NFSV41	(1U << 16)
+2 −0
Original line number Diff line number Diff line
@@ -1194,6 +1194,8 @@ struct nfs4_server_caps_res {
	u32				has_links;
	u32				has_symlinks;
	u32				fh_expire_type;
	u32				case_insensitive;
	u32				case_preserving;
};

#define NFS4_PATHNAME_MAXCOMPONENTS 512