All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/2] Two xattrs-related fixes for ceph
@ 2022-06-13 11:31 Luís Henriques
  2022-06-13 11:31 ` [PATCH v3 1/2] generic/020: adjust max_attrval_size " Luís Henriques
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Luís Henriques @ 2022-06-13 11:31 UTC (permalink / raw)
  To: fstests
  Cc: David Disseldorp, Zorro Lang, Dave Chinner, Darrick J. Wong,
	Jeff Layton, Xiubo Li, ceph-devel, Luís Henriques

Hi!

A bug fix in ceph has made some changes in the way xattr limits are
enforced on the client side.  This requires some fixes on tests
generic/020 and generic/486.

* Changes since v2:

  - patch 0001:
    Add logic to compute the *real* maximum.  Kudos to David Disseldorp
    for providing the right incantation to do the maths.  Also split
    _attr_get_max() in two, so that they can be invoked from different
    places in the test script.

  - patch 002:
    attr_replace_test now has an extra param as suggested by Dave Chinner,
    and added fs-specific logic to the script.  No need to have an exact
    maximum in this test, a big-enough value suffices.

* Changes since v1:

  - patch 0001:
    Set the max size for xattrs values to a 65000, so that it is close to
    the maximum, but still able to accommodate any pre-existing xattr

  - patch 0002:
    Same thing as patch 0001, but in a more precise way: actually take
    into account the exact sizes for name+value of a pre-existing xattr.

Luís Henriques (2):
  generic/020: adjust max_attrval_size for ceph
  generic/486: adjust the max xattr size

 src/attr_replace_test.c | 30 ++++++++++++++++++++++++++----
 tests/generic/020       | 33 +++++++++++++++++++++++++--------
 tests/generic/486       | 11 ++++++++++-
 3 files changed, 61 insertions(+), 13 deletions(-)


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v3 1/2] generic/020: adjust max_attrval_size for ceph
  2022-06-13 11:31 [PATCH v3 0/2] Two xattrs-related fixes for ceph Luís Henriques
@ 2022-06-13 11:31 ` Luís Henriques
  2022-06-13 12:21   ` David Disseldorp
  2022-06-13 11:31 ` [PATCH v3 2/2] generic/486: adjust the max xattr size Luís Henriques
  2022-06-14  9:22 ` [PATCH v3 0/2] Two xattrs-related fixes for ceph Xiubo Li
  2 siblings, 1 reply; 6+ messages in thread
From: Luís Henriques @ 2022-06-13 11:31 UTC (permalink / raw)
  To: fstests
  Cc: David Disseldorp, Zorro Lang, Dave Chinner, Darrick J. Wong,
	Jeff Layton, Xiubo Li, ceph-devel, Luís Henriques

CephFS doesn't have a maximum xattr size.  Instead, it imposes a maximum
size for the full set of xattrs names+values, which by default is 64K.

This patch fixes the max_attrval_size for ceph so that it is takes into
account any already existing attrs in the file.

Signed-off-by: Luís Henriques <lhenriques@suse.de>
---
 tests/generic/020 | 33 +++++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/tests/generic/020 b/tests/generic/020
index d8648e96286e..b91bca34dcd4 100755
--- a/tests/generic/020
+++ b/tests/generic/020
@@ -51,13 +51,9 @@ _attr_list()
     fi
 }
 
-# set fs-specific max_attrs and max_attrval_size values. The parameter
-# @max_attrval_namelen is required for filesystems which take into account attr
-# name lengths (including namespace prefix) when determining limits.
+# set fs-specific max_attrs
 _attr_get_max()
 {
-	local max_attrval_namelen="$1"
-
 	# set maximum total attr space based on fs type
 	case "$FSTYP" in
 	xfs|udf|pvfs2|9p|ceph|nfs)
@@ -112,6 +108,16 @@ _attr_get_max()
 		# overhead
 		let max_attrs=$BLOCK_SIZE/40
 	esac
+}
+
+# set fs-specific max_attrval_size values. The parameter @max_attrval_namelen is
+# required for filesystems which take into account attr name lengths (including
+# namespace prefix) when determining limits; parameter @filename is required for
+# filesystems that need to take into account already existing attrs.
+_attr_get_maxval_size()
+{
+	local max_attrval_namelen="$1"
+	local filename="$2"
 
 	# Set max attr value size in bytes based on fs type
 	case "$FSTYP" in
@@ -128,7 +134,7 @@ _attr_get_max()
 	pvfs2)
 		max_attrval_size=8192
 		;;
-	xfs|udf|9p|ceph)
+	xfs|udf|9p)
 		max_attrval_size=65536
 		;;
 	bcachefs)
@@ -139,6 +145,15 @@ _attr_get_max()
 		# the underlying filesystem, so just use the lowest value above.
 		max_attrval_size=1024
 		;;
+	ceph)
+		# CephFS does not have a maximum value for attributes.  Instead,
+		# it imposes a maximum size for the full set of xattrs
+		# names+values, which by default is 64K.  Compute the maximum
+		# taking into account the already existing attributes
+		max_attrval_size=$(getfattr --dump -e hex $filename 2>/dev/null | \
+			awk -F "=0x" '/^user/ {len += length($1) + length($2) / 2} END {print len}')
+		max_attrval_size=$((65536 - $max_attrval_size - $max_attrval_namelen))
+		;;
 	*)
 		# Assume max ~1 block of attrs
 		BLOCK_SIZE=`_get_block_size $TEST_DIR`
@@ -181,8 +196,7 @@ echo "*** remove attribute"
 _attr -r fish $testfile
 _attr_list $testfile
 
-max_attrval_name="long_attr"	# add 5 for "user." prefix
-_attr_get_max "$(( 5 + ${#max_attrval_name} ))"
+_attr_get_max
 
 echo "*** add lots of attributes"
 v=0
@@ -226,6 +240,9 @@ done
 _attr_list $testfile
 
 echo "*** really long value"
+max_attrval_name="long_attr"	# add 5 for "user." prefix
+_attr_get_maxval_size "$(( 5 + ${#max_attrval_name} ))" "$testfile"
+
 dd if=/dev/zero bs=1 count=$max_attrval_size 2>/dev/null \
     | _attr -s "$max_attrval_name" $testfile >/dev/null
 

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 2/2] generic/486: adjust the max xattr size
  2022-06-13 11:31 [PATCH v3 0/2] Two xattrs-related fixes for ceph Luís Henriques
  2022-06-13 11:31 ` [PATCH v3 1/2] generic/020: adjust max_attrval_size " Luís Henriques
@ 2022-06-13 11:31 ` Luís Henriques
  2022-06-13 12:24   ` David Disseldorp
  2022-06-14  9:22 ` [PATCH v3 0/2] Two xattrs-related fixes for ceph Xiubo Li
  2 siblings, 1 reply; 6+ messages in thread
From: Luís Henriques @ 2022-06-13 11:31 UTC (permalink / raw)
  To: fstests
  Cc: David Disseldorp, Zorro Lang, Dave Chinner, Darrick J. Wong,
	Jeff Layton, Xiubo Li, ceph-devel, Luís Henriques

CephFS doesn't have a maximum xattr size.  Instead, it imposes a maximum
size for the full set of xattrs names+values, which by default is 64K.  And
since it reports 4M as the blocksize (the default ceph object size),
generic/486 will fail in ceph because the XATTR_SIZE_MAX value can't be used
in attr_replace_test.

The fix is to add a new argument to the test so that the max size can be
passed in instead of trying to auto-probe a value for it.

Signed-off-by: Luís Henriques <lhenriques@suse.de>
---
 src/attr_replace_test.c | 30 ++++++++++++++++++++++++++----
 tests/generic/486       | 11 ++++++++++-
 2 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/src/attr_replace_test.c b/src/attr_replace_test.c
index cca8dcf8ff60..1218e7264c8f 100644
--- a/src/attr_replace_test.c
+++ b/src/attr_replace_test.c
@@ -20,19 +20,41 @@ exit(1); } while (0)
 fprintf(stderr, __VA_ARGS__); exit (1); \
 } while (0)
 
+void usage(char *progname)
+{
+	fail("usage: %s [-m max_attr_size] <file>\n", progname);
+}
+
 int main(int argc, char *argv[])
 {
 	int ret;
 	int fd;
+	int c;
 	char *path;
 	char *name = "user.world";
 	char *value;
 	struct stat sbuf;
 	size_t size = sizeof(value);
+	size_t maxsize = XATTR_SIZE_MAX;
+
+	while ((c = getopt(argc, argv, "m:")) != -1) {
+		char *endp;
+
+		switch (c) {
+		case 'm':
+			maxsize = strtoul(optarg, &endp, 0);
+			if (*endp || (maxsize > XATTR_SIZE_MAX))
+				fail("Invalid 'max_attr_size' value\n");
+			break;
+		default:
+			usage(argv[0]);
+		}
+	}
 
-	if (argc != 2)
-		fail("Usage: %s <file>\n", argv[0]);
-	path = argv[1];
+	if (optind == argc - 1)
+		path = argv[optind];
+	else
+		usage(argv[0]);
 
 	fd = open(path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
 	if (fd < 0) die();
@@ -46,7 +68,7 @@ int main(int argc, char *argv[])
 	size = sbuf.st_blksize * 3 / 4;
 	if (!size)
 		fail("Invalid st_blksize(%ld)\n", sbuf.st_blksize);
-	size = MIN(size, XATTR_SIZE_MAX);
+	size = MIN(size, maxsize);
 	value = malloc(size);
 	if (!value)
 		fail("Failed to allocate memory\n");
diff --git a/tests/generic/486 b/tests/generic/486
index 7de198f93a71..7dbfcb9835d9 100755
--- a/tests/generic/486
+++ b/tests/generic/486
@@ -41,7 +41,16 @@ filter_attr_output() {
 		sed -e 's/has a [0-9]* byte value/has a NNNN byte value/g'
 }
 
-$here/src/attr_replace_test $SCRATCH_MNT/hello
+max_attr_size=65536
+
+# attr_replace_test can't easily auto-probe the attr size for ceph because:
+# - ceph imposes a maximum value for the total xattr names+values, and
+# - ceph reports the 'object size' in the block size, which is, by default, much
+#   larger than XATTR_SIZE_MAX (4M > 64k)
+# Hence, we need to provide it with a maximum size.
+[ "$FSTYP" = "ceph" ] && max_attr_size=65000
+
+$here/src/attr_replace_test -m $max_attr_size $SCRATCH_MNT/hello
 $ATTR_PROG -l $SCRATCH_MNT/hello >>$seqres.full 2>&1
 $ATTR_PROG -l $SCRATCH_MNT/hello | filter_attr_output
 

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v3 1/2] generic/020: adjust max_attrval_size for ceph
  2022-06-13 11:31 ` [PATCH v3 1/2] generic/020: adjust max_attrval_size " Luís Henriques
@ 2022-06-13 12:21   ` David Disseldorp
  0 siblings, 0 replies; 6+ messages in thread
From: David Disseldorp @ 2022-06-13 12:21 UTC (permalink / raw)
  To: Luís Henriques
  Cc: fstests, Zorro Lang, Dave Chinner, Darrick J. Wong, Jeff Layton,
	Xiubo Li, ceph-devel

On Mon, 13 Jun 2022 12:31:41 +0100, Luís Henriques wrote:

> CephFS doesn't have a maximum xattr size.  Instead, it imposes a maximum
> size for the full set of xattrs names+values, which by default is 64K.
> 
> This patch fixes the max_attrval_size for ceph so that it is takes into
> account any already existing attrs in the file.
> 
> Signed-off-by: Luís Henriques <lhenriques@suse.de>
> ---
>  tests/generic/020 | 33 +++++++++++++++++++++++++--------
>  1 file changed, 25 insertions(+), 8 deletions(-)
> 
> diff --git a/tests/generic/020 b/tests/generic/020
> index d8648e96286e..b91bca34dcd4 100755
> --- a/tests/generic/020
> +++ b/tests/generic/020
> @@ -51,13 +51,9 @@ _attr_list()
>      fi
>  }
>  
> -# set fs-specific max_attrs and max_attrval_size values. The parameter
> -# @max_attrval_namelen is required for filesystems which take into account attr
> -# name lengths (including namespace prefix) when determining limits.
> +# set fs-specific max_attrs
>  _attr_get_max()
>  {
> -	local max_attrval_namelen="$1"
> -
>  	# set maximum total attr space based on fs type
>  	case "$FSTYP" in
>  	xfs|udf|pvfs2|9p|ceph|nfs)
> @@ -112,6 +108,16 @@ _attr_get_max()
>  		# overhead
>  		let max_attrs=$BLOCK_SIZE/40
>  	esac
> +}
> +
> +# set fs-specific max_attrval_size values. The parameter @max_attrval_namelen is
> +# required for filesystems which take into account attr name lengths (including
> +# namespace prefix) when determining limits; parameter @filename is required for
> +# filesystems that need to take into account already existing attrs.
> +_attr_get_maxval_size()
> +{
> +	local max_attrval_namelen="$1"
> +	local filename="$2"
>  
>  	# Set max attr value size in bytes based on fs type
>  	case "$FSTYP" in
> @@ -128,7 +134,7 @@ _attr_get_max()
>  	pvfs2)
>  		max_attrval_size=8192
>  		;;
> -	xfs|udf|9p|ceph)
> +	xfs|udf|9p)
>  		max_attrval_size=65536
>  		;;
>  	bcachefs)
> @@ -139,6 +145,15 @@ _attr_get_max()
>  		# the underlying filesystem, so just use the lowest value above.
>  		max_attrval_size=1024
>  		;;
> +	ceph)
> +		# CephFS does not have a maximum value for attributes.  Instead,
> +		# it imposes a maximum size for the full set of xattrs
> +		# names+values, which by default is 64K.  Compute the maximum
> +		# taking into account the already existing attributes
> +		max_attrval_size=$(getfattr --dump -e hex $filename 2>/dev/null | \
> +			awk -F "=0x" '/^user/ {len += length($1) + length($2) / 2} END {print len}')
> +		max_attrval_size=$((65536 - $max_attrval_size - $max_attrval_namelen))
> +		;;
>  	*)
>  		# Assume max ~1 block of attrs
>  		BLOCK_SIZE=`_get_block_size $TEST_DIR`
> @@ -181,8 +196,7 @@ echo "*** remove attribute"
>  _attr -r fish $testfile
>  _attr_list $testfile
>  
> -max_attrval_name="long_attr"	# add 5 for "user." prefix
> -_attr_get_max "$(( 5 + ${#max_attrval_name} ))"
> +_attr_get_max
>  
>  echo "*** add lots of attributes"
>  v=0
> @@ -226,6 +240,9 @@ done
>  _attr_list $testfile
>  
>  echo "*** really long value"
> +max_attrval_name="long_attr"	# add 5 for "user." prefix
> +_attr_get_maxval_size "$(( 5 + ${#max_attrval_name} ))" "$testfile"
> +
>  dd if=/dev/zero bs=1 count=$max_attrval_size 2>/dev/null \
>      | _attr -s "$max_attrval_name" $testfile >/dev/null
>  

Looks good.
Reviewed-by: David Disseldorp <ddiss@suse.de>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3 2/2] generic/486: adjust the max xattr size
  2022-06-13 11:31 ` [PATCH v3 2/2] generic/486: adjust the max xattr size Luís Henriques
@ 2022-06-13 12:24   ` David Disseldorp
  0 siblings, 0 replies; 6+ messages in thread
From: David Disseldorp @ 2022-06-13 12:24 UTC (permalink / raw)
  To: Luís Henriques
  Cc: fstests, Zorro Lang, Dave Chinner, Darrick J. Wong, Jeff Layton,
	Xiubo Li, ceph-devel

On Mon, 13 Jun 2022 12:31:42 +0100, Luís Henriques wrote:

> CephFS doesn't have a maximum xattr size.  Instead, it imposes a maximum
> size for the full set of xattrs names+values, which by default is 64K.  And
> since it reports 4M as the blocksize (the default ceph object size),
> generic/486 will fail in ceph because the XATTR_SIZE_MAX value can't be used
> in attr_replace_test.
> 
> The fix is to add a new argument to the test so that the max size can be
> passed in instead of trying to auto-probe a value for it.
> 
> Signed-off-by: Luís Henriques <lhenriques@suse.de>
> ---
>  src/attr_replace_test.c | 30 ++++++++++++++++++++++++++----
>  tests/generic/486       | 11 ++++++++++-
>  2 files changed, 36 insertions(+), 5 deletions(-)
> 
> diff --git a/src/attr_replace_test.c b/src/attr_replace_test.c
> index cca8dcf8ff60..1218e7264c8f 100644
> --- a/src/attr_replace_test.c
> +++ b/src/attr_replace_test.c
> @@ -20,19 +20,41 @@ exit(1); } while (0)
>  fprintf(stderr, __VA_ARGS__); exit (1); \
>  } while (0)
>  
> +void usage(char *progname)
> +{
> +	fail("usage: %s [-m max_attr_size] <file>\n", progname);
> +}
> +
>  int main(int argc, char *argv[])
>  {
>  	int ret;
>  	int fd;
> +	int c;
>  	char *path;
>  	char *name = "user.world";
>  	char *value;
>  	struct stat sbuf;
>  	size_t size = sizeof(value);
> +	size_t maxsize = XATTR_SIZE_MAX;
> +
> +	while ((c = getopt(argc, argv, "m:")) != -1) {
> +		char *endp;
> +
> +		switch (c) {
> +		case 'm':
> +			maxsize = strtoul(optarg, &endp, 0);
> +			if (*endp || (maxsize > XATTR_SIZE_MAX))
> +				fail("Invalid 'max_attr_size' value\n");
> +			break;
> +		default:
> +			usage(argv[0]);
> +		}
> +	}
>  
> -	if (argc != 2)
> -		fail("Usage: %s <file>\n", argv[0]);
> -	path = argv[1];
> +	if (optind == argc - 1)
> +		path = argv[optind];
> +	else
> +		usage(argv[0]);
>  
>  	fd = open(path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
>  	if (fd < 0) die();
> @@ -46,7 +68,7 @@ int main(int argc, char *argv[])
>  	size = sbuf.st_blksize * 3 / 4;
>  	if (!size)
>  		fail("Invalid st_blksize(%ld)\n", sbuf.st_blksize);
> -	size = MIN(size, XATTR_SIZE_MAX);
> +	size = MIN(size, maxsize);
>  	value = malloc(size);
>  	if (!value)
>  		fail("Failed to allocate memory\n");
> diff --git a/tests/generic/486 b/tests/generic/486
> index 7de198f93a71..7dbfcb9835d9 100755
> --- a/tests/generic/486
> +++ b/tests/generic/486
> @@ -41,7 +41,16 @@ filter_attr_output() {
>  		sed -e 's/has a [0-9]* byte value/has a NNNN byte value/g'
>  }
>  
> -$here/src/attr_replace_test $SCRATCH_MNT/hello
> +max_attr_size=65536
> +
> +# attr_replace_test can't easily auto-probe the attr size for ceph because:
> +# - ceph imposes a maximum value for the total xattr names+values, and
> +# - ceph reports the 'object size' in the block size, which is, by default, much
> +#   larger than XATTR_SIZE_MAX (4M > 64k)
> +# Hence, we need to provide it with a maximum size.
> +[ "$FSTYP" = "ceph" ] && max_attr_size=65000
> +
> +$here/src/attr_replace_test -m $max_attr_size $SCRATCH_MNT/hello
>  $ATTR_PROG -l $SCRATCH_MNT/hello >>$seqres.full 2>&1
>  $ATTR_PROG -l $SCRATCH_MNT/hello | filter_attr_output

Looks okay as an alternative to going through a 73aa648c
("generic/020: move MAX_ATTRS and MAX_ATTRVAL_SIZE logic") revert.

Reviewed-by: David Disseldorp <ddiss@suse.de>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3 0/2] Two xattrs-related fixes for ceph
  2022-06-13 11:31 [PATCH v3 0/2] Two xattrs-related fixes for ceph Luís Henriques
  2022-06-13 11:31 ` [PATCH v3 1/2] generic/020: adjust max_attrval_size " Luís Henriques
  2022-06-13 11:31 ` [PATCH v3 2/2] generic/486: adjust the max xattr size Luís Henriques
@ 2022-06-14  9:22 ` Xiubo Li
  2 siblings, 0 replies; 6+ messages in thread
From: Xiubo Li @ 2022-06-14  9:22 UTC (permalink / raw)
  To: Luís Henriques, fstests
  Cc: David Disseldorp, Zorro Lang, Dave Chinner, Darrick J. Wong,
	Jeff Layton, ceph-devel


On 6/13/22 7:31 PM, Luís Henriques wrote:
> Hi!
>
> A bug fix in ceph has made some changes in the way xattr limits are
> enforced on the client side.  This requires some fixes on tests
> generic/020 and generic/486.
>
> * Changes since v2:
>
>    - patch 0001:
>      Add logic to compute the *real* maximum.  Kudos to David Disseldorp
>      for providing the right incantation to do the maths.  Also split
>      _attr_get_max() in two, so that they can be invoked from different
>      places in the test script.
>
>    - patch 002:
>      attr_replace_test now has an extra param as suggested by Dave Chinner,
>      and added fs-specific logic to the script.  No need to have an exact
>      maximum in this test, a big-enough value suffices.
>
> * Changes since v1:
>
>    - patch 0001:
>      Set the max size for xattrs values to a 65000, so that it is close to
>      the maximum, but still able to accommodate any pre-existing xattr
>
>    - patch 0002:
>      Same thing as patch 0001, but in a more precise way: actually take
>      into account the exact sizes for name+value of a pre-existing xattr.
>
> Luís Henriques (2):
>    generic/020: adjust max_attrval_size for ceph
>    generic/486: adjust the max xattr size
>
>   src/attr_replace_test.c | 30 ++++++++++++++++++++++++++----
>   tests/generic/020       | 33 +++++++++++++++++++++++++--------
>   tests/generic/486       | 11 ++++++++++-
>   3 files changed, 61 insertions(+), 13 deletions(-)
>
This series looks good to me.

Reviewed-by: Xiubo Li <xiubli@redhat.com>



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-06-14  9:24 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-06-13 11:31 [PATCH v3 0/2] Two xattrs-related fixes for ceph Luís Henriques
2022-06-13 11:31 ` [PATCH v3 1/2] generic/020: adjust max_attrval_size " Luís Henriques
2022-06-13 12:21   ` David Disseldorp
2022-06-13 11:31 ` [PATCH v3 2/2] generic/486: adjust the max xattr size Luís Henriques
2022-06-13 12:24   ` David Disseldorp
2022-06-14  9:22 ` [PATCH v3 0/2] Two xattrs-related fixes for ceph Xiubo Li

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.