Browse Source

xfs: avoid dependency on Linux XATTR_SIZE_MAX

Currently, we depends on Linux XATTR value for on disk
definition. Which causes trouble on other platforms and
maybe also if this value was to change.

Fix it by creating a custom definition independent from
those in Linux (although with the same values), so it is OK
with the be16 fields used for holding these attributes.

This patch reflects a change in xfsprogs.

Signed-off-by: Jan Tulak <jtulak@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Jan Tulak 9 years ago
parent
commit
51fcbfe709
3 changed files with 12 additions and 4 deletions
  1. 1 1
      fs/xfs/libxfs/xfs_attr_remote.c
  2. 9 1
      fs/xfs/libxfs/xfs_format.h
  3. 2 2
      fs/xfs/xfs_ioctl.c

+ 1 - 1
fs/xfs/libxfs/xfs_attr_remote.c

@@ -107,7 +107,7 @@ xfs_attr3_rmt_verify(
 	if (be32_to_cpu(rmt->rm_bytes) > fsbsize - sizeof(*rmt))
 	if (be32_to_cpu(rmt->rm_bytes) > fsbsize - sizeof(*rmt))
 		return false;
 		return false;
 	if (be32_to_cpu(rmt->rm_offset) +
 	if (be32_to_cpu(rmt->rm_offset) +
-				be32_to_cpu(rmt->rm_bytes) > XATTR_SIZE_MAX)
+				be32_to_cpu(rmt->rm_bytes) > XFS_XATTR_SIZE_MAX)
 		return false;
 		return false;
 	if (rmt->rm_owner == 0)
 	if (rmt->rm_owner == 0)
 		return false;
 		return false;

+ 9 - 1
fs/xfs/libxfs/xfs_format.h

@@ -59,6 +59,14 @@ struct xfs_ifork;
 #define	XFS_SB_VERSION_BORGBIT		0x4000	/* ASCII only case-insens. */
 #define	XFS_SB_VERSION_BORGBIT		0x4000	/* ASCII only case-insens. */
 #define	XFS_SB_VERSION_MOREBITSBIT	0x8000
 #define	XFS_SB_VERSION_MOREBITSBIT	0x8000
 
 
+/*
+ * The size of a single extended attribute on disk is limited by
+ * the size of index values within the attribute entries themselves.
+ * These are be16 fields, so we can only support attribute data
+ * sizes up to 2^16 bytes in length.
+ */
+#define XFS_XATTR_SIZE_MAX (1 << 16)
+
 /*
 /*
  * Supported feature bit list is just all bits in the versionnum field because
  * Supported feature bit list is just all bits in the versionnum field because
  * we've used them all up and understand them all. Except, of course, for the
  * we've used them all up and understand them all. Except, of course, for the
@@ -1483,7 +1491,7 @@ struct xfs_acl {
  */
  */
 #define XFS_ACL_MAX_ENTRIES(mp)	\
 #define XFS_ACL_MAX_ENTRIES(mp)	\
 	(xfs_sb_version_hascrc(&mp->m_sb) \
 	(xfs_sb_version_hascrc(&mp->m_sb) \
-		?  (XATTR_SIZE_MAX - sizeof(struct xfs_acl)) / \
+		?  (XFS_XATTR_SIZE_MAX - sizeof(struct xfs_acl)) / \
 						sizeof(struct xfs_acl_entry) \
 						sizeof(struct xfs_acl_entry) \
 		: 25)
 		: 25)
 
 

+ 2 - 2
fs/xfs/xfs_ioctl.c

@@ -455,7 +455,7 @@ xfs_attrmulti_attr_get(
 	unsigned char		*kbuf;
 	unsigned char		*kbuf;
 	int			error = -EFAULT;
 	int			error = -EFAULT;
 
 
-	if (*len > XATTR_SIZE_MAX)
+	if (*len > XFS_XATTR_SIZE_MAX)
 		return -EINVAL;
 		return -EINVAL;
 	kbuf = kmem_zalloc_large(*len, KM_SLEEP);
 	kbuf = kmem_zalloc_large(*len, KM_SLEEP);
 	if (!kbuf)
 	if (!kbuf)
@@ -485,7 +485,7 @@ xfs_attrmulti_attr_set(
 
 
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 		return -EPERM;
 		return -EPERM;
-	if (len > XATTR_SIZE_MAX)
+	if (len > XFS_XATTR_SIZE_MAX)
 		return -EINVAL;
 		return -EINVAL;
 
 
 	kbuf = memdup_user(ubuf, len);
 	kbuf = memdup_user(ubuf, len);