lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20210311042302.GA137676@embeddedor>
Date:   Wed, 10 Mar 2021 22:23:02 -0600
From:   "Gustavo A. R. Silva" <gustavoars@...nel.org>
To:     "Darrick J. Wong" <djwong@...nel.org>,
        Dave Chinner <david@...morbit.com>
Cc:     linux-xfs@...r.kernel.org, linux-kernel@...r.kernel.org,
        "Gustavo A. R. Silva" <gustavoars@...nel.org>,
        linux-hardening@...r.kernel.org
Subject: [PATCH v3][next] xfs: Replace one-element arrays with flexible-array
 members

There is a regular need in the kernel to provide a way to declare having
a dynamically sized set of trailing elements in a structure. Kernel code
should always use “flexible array members”[1] for these cases. The older
style of one-element or zero-length arrays should no longer be used[2].

Refactor the code according to the use of flexible-array members in
multiple structures, instead of one-element arrays. Also, make use of
the new struct_size() helper to properly calculate the size of multiple
structures that contain flexible-array members. Additionally, wrap
some calls to the struct_size() helper in multiple inline functions.

Below are the results of running xfstests for groups shutdown and log
with the following configuration in local.config:

export TEST_DEV=/dev/sda3
export TEST_DIR=/mnt/test
export SCRATCH_DEV=/dev/sda4
export SCRATCH_MNT=/mnt/scratch

The size for both partitions /dev/sda3 and /dev/sda4 is 25GB.

These are the results of running ./check -g shutdown and ./check -g
log, respectively, on 5.12.0-rc2-next-20210309 kernel WITHOUT this patch
applied:

gustavo@...fy:~/git/xfstests$ time sudo ./check -g shutdown 2>&1 | tee xfs-shutdown-no-patch.out
FSTYP         -- xfs (debug)
PLATFORM      -- Linux/x86_64 beefy 5.12.0-rc2-next-20210309 #21 SMP Tue Mar 9 17:48:24 CST 2021
MKFS_OPTIONS  -- -f -bsize=4096 /dev/sda4
MOUNT_OPTIONS -- /dev/sda4 /mnt/scratch

generic/042 2s ...  2s
generic/043 13s ...  13s
generic/044 14s ...  15s
generic/045 18s ...  17s
generic/046 14s ...  14s
generic/047 21s ...  20s
generic/048 50s ...  51s
generic/049 9s ...  9s
generic/050 1s ...  1s
generic/051 77s ...  76s
generic/052 1s ...  1s
generic/054 70s ...  31s
generic/055 15s ...  18s
generic/388 82s ...  80s
generic/392 5s ...  4s
generic/417 11s ...  12s
generic/461 22s ...  21s
generic/468 12s ...  3s
generic/474 2s ...  1s
generic/475 87s ...  97s
generic/505 1s ...  1s
generic/506 2s ...  2s
generic/507     [not run] file system doesn't support chattr +AsSu
generic/508 4s ...  5s
generic/530 14s ...  14s
generic/536 2s ...  2s
generic/599 2s ...  1s
generic/622 23s ...  24s
xfs/051 18s ...  18s
xfs/079 14s ...  14s
xfs/121 6s ...  32s
xfs/181 12s ...  12s
xfs/212 2s ...  2s
Ran: generic/042 generic/043 generic/044 generic/045 generic/046 generic/047 generic/048 generic/049 generic/050 generic/051 generic/052 generic/054 generic/055 generic/388 generic/392 generic/417 generic/461 generic/468 generic/474 generic/475 generic/505 generic/506 generic/507 generic/508 generic/530 generic/536 generic/599 generic/622 xfs/051 xfs/079 xfs/121 xfs/181 xfs/212
Not run: generic/507
Passed all 33 tests

gustavo@...fy:~/git/xfstests$ time sudo ./check -g log 2>&1 | tee xfs-log-no-patch.out
FSTYP         -- xfs (debug)
PLATFORM      -- Linux/x86_64 beefy 5.12.0-rc2-next-20210309 #21 SMP Tue Mar 9 17:48:24 CST 2021
MKFS_OPTIONS  -- -f -bsize=4096 /dev/sda4
MOUNT_OPTIONS -- /dev/sda4 /mnt/scratch

generic/034 0s ...  1s
generic/039 1s ...  1s
generic/040 5s ...  5s
generic/041 8s ...  7s
generic/043 13s ...  13s
generic/044 14s ...  15s
generic/045 18s ...  17s
generic/046 14s ...  15s
generic/051 75s ...  76s
generic/052 2s ...  1s
generic/054 32s ...  31s
generic/055 19s ...  23s
generic/056 1s ...  2s
generic/057 1s ...  1s
generic/059 2s ...  2s
generic/065 1s ...  1s
generic/066 1s ...  1s
generic/073 1s ...  1s
generic/090 1s ...  1s
generic/101 1s ...  1s
generic/104 1s ...  1s
generic/106 1s ...  1s
generic/107 1s ...  1s
generic/177 1s ...  1s
generic/311 68s ...  66s
generic/321 1s ...  2s
generic/322 2s ...  1s
generic/325 1s ...  1s
generic/335 1s ...  2s
generic/336 1s ...  1s
generic/341 1s ...  1s
generic/342 1s ...  1s
generic/343 1s ...  1s
generic/376 1s ...  1s
generic/388 93s ...  81s
generic/417 11s ...  12s
generic/455     [not run] This test requires a valid $LOGWRITES_DEV
generic/457     [not run] This test requires a valid $LOGWRITES_DEV
generic/475 98s ...  81s
generic/479 2s ...  2s
generic/480 1s ...  1s
generic/481 1s ...  1s
generic/483 7s ...  7s
generic/489 1s ...  1s
generic/498 1s ...  1s
generic/501 56s ...  57s
generic/502 1s ...  1s
generic/509 1s ...  1s
generic/510 1s ...  1s
generic/512 1s ...  1s
generic/520 16s ...  16s
generic/526 2s ...  1s
generic/527 1s ...  1s
generic/534 1s ...  1s
generic/535 1s ...  1s
generic/546 3s ...  3s
generic/547 2s ...  2s
generic/552 1s ...  1s
generic/557 2s ...  2s
generic/588 1s ...  1s
shared/002 9s ...  9s
xfs/011 18s ...  18s
xfs/029 1s ...  1s
xfs/051 17s ...  18s
xfs/057 24s ...  24s
xfs/079 14s ...  13s
xfs/095 2s ...  2s
xfs/119 2s ...  2s
xfs/121 6s ...  7s
xfs/141 16s ...  10s
xfs/181 40s ...  12s
xfs/216 2s ...  3s
xfs/217 2s ...  2s
xfs/439 [not run] test requires XFS bug_on_assert to be off, turn it off to run the test
Ran: generic/034 generic/039 generic/040 generic/041 generic/043 generic/044 generic/045 generic/046 generic/051 generic/052 generic/054 generic/055 generic/056 generic/057 generic/059 generic/065 generic/066 generic/073 generic/090 generic/101 generic/104 generic/106 generic/107 generic/177 generic/311 generic/321 generic/322 generic/325 generic/335 generic/336 generic/341 generic/342 generic/343 generic/376 generic/388 generic/417 generic/455 generic/457 generic/475 generic/479 generic/480 generic/481 generic/483 generic/489 generic/498 generic/501 generic/502 generic/509 generic/510 generic/512 generic/520 generic/526 generic/527 generic/534 generic/535 generic/546 generic/547 generic/552 generic/557 generic/588 shared/002 xfs/011 xfs/029 xfs/051 xfs/057 xfs/079 xfs/095 xfs/119 xfs/121 xfs/141 xfs/181 xfs/216 xfs/217 xfs/439
Not run: generic/455 generic/457 xfs/439
Passed all 74 tests

These are the results of running ./check -g shutdown and ./check -g
log, respectively, on 5.12.0-rc2-xfstests-patched-next-20210309+ kernel
WITH this patch applied on top:

gustavo@...fy:~/git/xfstests$ time sudo ./check -g shutdown 2>&1 | tee xfs-shutdown-patched.out
FSTYP         -- xfs (debug)
PLATFORM      -- Linux/x86_64 beefy 5.12.0-rc2-xfstests-patched-next-20210309+ #20 SMP Tue Mar 9 17:02:09 CST 2021
MKFS_OPTIONS  -- -f -bsize=4096 /dev/sda4
MOUNT_OPTIONS -- /dev/sda4 /mnt/scratch

generic/042 2s ...  3s
generic/043 13s ...  12s
generic/044 14s ...  15s
generic/045 18s ...  18s
generic/046 14s ...  14s
generic/047 21s ...  21s
generic/048 51s ...  51s
generic/049 8s ...  8s
generic/050 1s ...  2s
generic/051 76s ...  75s
generic/052 1s ...  2s
generic/054 35s ...  70s
generic/055 16s ...  21s
generic/388 77s ...  76s
generic/392 29s ...  6s
generic/417 12s ...  11s
generic/461 21s ...  22s
generic/468 3s ...  3s
generic/474 1s ...  1s
generic/475 99s ...  91s
generic/505 2s ...  2s
generic/506 1s ...  1s
generic/507     [not run] file system doesn't support chattr +AsSu
generic/508 2s ...  4s
generic/530 12s ...  9s
generic/536 2s ...  3s
generic/599 1s ...  1s
generic/622 24s ...  24s
xfs/051 18s ...  19s
xfs/079 16s ...  13s
xfs/121 7s ...  7s
xfs/181 11s ...  11s
xfs/212 2s ...  2s
Ran: generic/042 generic/043 generic/044 generic/045 generic/046 generic/047 generic/048 generic/049 generic/050 generic/051 generic/052 generic/054 generic/055 generic/388 generic/392 generic/417 generic/461 generic/468 generic/474 generic/475 generic/505 generic/506 generic/507 generic/508 generic/530 generic/536 generic/599 generic/622 xfs/051 xfs/079 xfs/121 xfs/181 xfs/212
Not run: generic/507
Passed all 33 tests

gustavo@...fy:~/git/xfstests$ time sudo ./check -g log 2>&1 | tee xfs-log-patched.out
FSTYP         -- xfs (debug)
PLATFORM      -- Linux/x86_64 beefy 5.12.0-rc2-xfstests-patched-next-20210309+ #20 SMP Tue Mar 9 17:02:09 CST 2021
MKFS_OPTIONS  -- -f -bsize=4096 /dev/sda4
MOUNT_OPTIONS -- /dev/sda4 /mnt/scratch

generic/034 1s ...  0s
generic/039 1s ...  1s
generic/040 5s ...  5s
generic/041 7s ...  8s
generic/043 12s ...  12s
generic/044 15s ...  15s
generic/045 18s ...  18s
generic/046 14s ...  14s
generic/051 75s ...  76s
generic/052 2s ...  5s
generic/054 70s ...  32s
generic/055 21s ...  15s
generic/056 1s ...  1s
generic/057 1s ...  1s
generic/059 2s ...  2s
generic/065 1s ...  1s
generic/066 2s ...  1s
generic/073 1s ...  1s
generic/090 1s ...  1s
generic/101 1s ...  1s
generic/104 1s ...  1s
generic/106 1s ...  1s
generic/107 1s ...  1s
generic/177 1s ...  1s
generic/311 67s ...  68s
generic/321 2s ...  1s
generic/322 2s ...  2s
generic/325 1s ...  1s
generic/335 1s ...  1s
generic/336 1s ...  1s
generic/341 1s ...  1s
generic/342 1s ...  1s
generic/343 1s ...  1s
generic/376 1s ...  1s
generic/388 76s ...  79s
generic/417 11s ...  12s
generic/455     [not run] This test requires a valid $LOGWRITES_DEV
generic/457     [not run] This test requires a valid $LOGWRITES_DEV
generic/475 91s ...  98s
generic/479 2s ...  2s
generic/480 1s ...  1s
generic/481 1s ...  1s
generic/483 6s ...  7s
generic/489 1s ...  1s
generic/498 1s ...  1s
generic/501 63s ...  56s
generic/502 1s ...  1s
generic/509 1s ...  1s
generic/510 1s ...  1s
generic/512 1s ...  1s
generic/520 17s ...  16s
generic/526 1s ...  2s
generic/527 1s ...  1s
generic/534 1s ...  1s
generic/535 1s ...  1s
generic/546 3s ...  3s
generic/547 2s ...  2s
generic/552 1s ...  1s
generic/557 2s ...  2s
generic/588 1s ...  1s
shared/002 9s ...  9s
xfs/011 18s ...  18s
xfs/029 1s ...  1s
xfs/051 19s ...  18s
xfs/057 23s ...  24s
xfs/079 13s ...  14s
xfs/095 1s ...  2s
xfs/119 3s ...  2s
xfs/121 7s ...  10s
xfs/141 26s ...  16s
xfs/181 11s ...  11s
xfs/216 2s ...  2s
xfs/217 2s ...  2s
xfs/439 [not run] test requires XFS bug_on_assert to be off, turn it off to run the test
Ran: generic/034 generic/039 generic/040 generic/041 generic/043 generic/044 generic/045 generic/046 generic/051 generic/052 generic/054 generic/055 generic/056 generic/057 generic/059 generic/065 generic/066 generic/073 generic/090 generic/101 generic/104 generic/106 generic/107 generic/177 generic/311 generic/321 generic/322 generic/325 generic/335 generic/336 generic/341 generic/342 generic/343 generic/376 generic/388 generic/417 generic/455 generic/457 generic/475 generic/479 generic/480 generic/481 generic/483 generic/489 generic/498 generic/501 generic/502 generic/509 generic/510 generic/512 generic/520 generic/526 generic/527 generic/534 generic/535 generic/546 generic/547 generic/552 generic/557 generic/588 shared/002 xfs/011 xfs/029 xfs/051 xfs/057 xfs/079 xfs/095 xfs/119 xfs/121 xfs/141 xfs/181 xfs/216 xfs/217 xfs/439
Not run: generic/455 generic/457 xfs/439
Passed all 74 tests

Notice that the test results before and after this patch is applied are
identical and successful. Other tests might need to be run in order to
verify everything is working as expected. For such tests, the intervention
of the maintainers might be needed.

[1] https://en.wikipedia.org/wiki/Flexible_array_member
[2] https://www.kernel.org/doc/html/v5.9/process/deprecated.html#zero-length-and-one-element-arrays

Link: https://github.com/KSPP/linux/issues/79
Signed-off-by: Gustavo A. R. Silva <gustavoars@...nel.org>
---
Changes in v3:
 - Add multiple inline functions as wrappers for struct_size(), as
   per Darrick's request.
 - Use type size_t instead of uint for a couple of objects.

Changes in v2:
 - Use struct_size() helper in more places.
 - Update changelog text with testing results on Linux 5.12.0-rc2.
 - Fix issue with use of struct_size() with the right struct object.
 - Use flex_array_size() helper.

 fs/xfs/libxfs/xfs_log_format.h |  12 ++--
 fs/xfs/xfs_extfree_item.c      | 102 +++++++++++++++++++++++----------
 fs/xfs/xfs_ondisk.h            |   8 +--
 3 files changed, 83 insertions(+), 39 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h
index 8bd00da6d2a4..9934a465b441 100644
--- a/fs/xfs/libxfs/xfs_log_format.h
+++ b/fs/xfs/libxfs/xfs_log_format.h
@@ -574,7 +574,7 @@ typedef struct xfs_efi_log_format {
 	uint16_t		efi_size;	/* size of this item */
 	uint32_t		efi_nextents;	/* # extents to free */
 	uint64_t		efi_id;		/* efi identifier */
-	xfs_extent_t		efi_extents[1];	/* array of extents to free */
+	xfs_extent_t		efi_extents[];	/* array of extents to free */
 } xfs_efi_log_format_t;
 
 typedef struct xfs_efi_log_format_32 {
@@ -582,7 +582,7 @@ typedef struct xfs_efi_log_format_32 {
 	uint16_t		efi_size;	/* size of this item */
 	uint32_t		efi_nextents;	/* # extents to free */
 	uint64_t		efi_id;		/* efi identifier */
-	xfs_extent_32_t		efi_extents[1];	/* array of extents to free */
+	xfs_extent_32_t		efi_extents[];	/* array of extents to free */
 } __attribute__((packed)) xfs_efi_log_format_32_t;
 
 typedef struct xfs_efi_log_format_64 {
@@ -590,7 +590,7 @@ typedef struct xfs_efi_log_format_64 {
 	uint16_t		efi_size;	/* size of this item */
 	uint32_t		efi_nextents;	/* # extents to free */
 	uint64_t		efi_id;		/* efi identifier */
-	xfs_extent_64_t		efi_extents[1];	/* array of extents to free */
+	xfs_extent_64_t		efi_extents[];	/* array of extents to free */
 } xfs_efi_log_format_64_t;
 
 /*
@@ -603,7 +603,7 @@ typedef struct xfs_efd_log_format {
 	uint16_t		efd_size;	/* size of this item */
 	uint32_t		efd_nextents;	/* # of extents freed */
 	uint64_t		efd_efi_id;	/* id of corresponding efi */
-	xfs_extent_t		efd_extents[1];	/* array of extents freed */
+	xfs_extent_t		efd_extents[];	/* array of extents freed */
 } xfs_efd_log_format_t;
 
 typedef struct xfs_efd_log_format_32 {
@@ -611,7 +611,7 @@ typedef struct xfs_efd_log_format_32 {
 	uint16_t		efd_size;	/* size of this item */
 	uint32_t		efd_nextents;	/* # of extents freed */
 	uint64_t		efd_efi_id;	/* id of corresponding efi */
-	xfs_extent_32_t		efd_extents[1];	/* array of extents freed */
+	xfs_extent_32_t		efd_extents[];	/* array of extents freed */
 } __attribute__((packed)) xfs_efd_log_format_32_t;
 
 typedef struct xfs_efd_log_format_64 {
@@ -619,7 +619,7 @@ typedef struct xfs_efd_log_format_64 {
 	uint16_t		efd_size;	/* size of this item */
 	uint32_t		efd_nextents;	/* # of extents freed */
 	uint64_t		efd_efi_id;	/* id of corresponding efi */
-	xfs_extent_64_t		efd_extents[1];	/* array of extents freed */
+	xfs_extent_64_t		efd_extents[];	/* array of extents freed */
 } xfs_efd_log_format_64_t;
 
 /*
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index 93223ebb3372..17b3ff8ce05f 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -73,8 +73,8 @@ static inline int
 xfs_efi_item_sizeof(
 	struct xfs_efi_log_item *efip)
 {
-	return sizeof(struct xfs_efi_log_format) +
-	       (efip->efi_format.efi_nextents - 1) * sizeof(xfs_extent_t);
+	return struct_size(&efip->efi_format, efi_extents,
+			   efip->efi_format.efi_nextents);
 }
 
 STATIC void
@@ -153,17 +153,14 @@ xfs_efi_init(
 
 {
 	struct xfs_efi_log_item	*efip;
-	uint			size;
 
 	ASSERT(nextents > 0);
-	if (nextents > XFS_EFI_MAX_FAST_EXTENTS) {
-		size = (uint)(sizeof(struct xfs_efi_log_item) +
-			((nextents - 1) * sizeof(xfs_extent_t)));
-		efip = kmem_zalloc(size, 0);
-	} else {
+	if (nextents > XFS_EFI_MAX_FAST_EXTENTS)
+		efip = kmem_zalloc(struct_size(efip, efi_format.efi_extents,
+					       nextents), 0);
+	else
 		efip = kmem_cache_zalloc(xfs_efi_zone,
 					 GFP_KERNEL | __GFP_NOFAIL);
-	}
 
 	xfs_log_item_init(mp, &efip->efi_item, XFS_LI_EFI, &xfs_efi_item_ops);
 	efip->efi_format.efi_nextents = nextents;
@@ -174,6 +171,36 @@ xfs_efi_init(
 	return efip;
 }
 
+/*
+ * Calculates the size of structure xfs_efi_log_format followed by an
+ * array of n number of efi_extents elements.
+ */
+static inline size_t
+sizeof_efi_log_format(size_t n)
+{
+	return struct_size((struct xfs_efi_log_format *)0, efi_extents, n);
+}
+
+/*
+ * Calculates the size of structure xfs_efi_log_format_32 followed by an
+ * array of n number of efi_extents elements.
+ */
+static inline size_t
+sizeof_efi_log_format_32(size_t n)
+{
+	return struct_size((struct xfs_efi_log_format_32 *)0, efi_extents, n);
+}
+
+/*
+ * Calculates the size of structure xfs_efi_log_format_64 followed by an
+ * array of n number of efi_extents elements.
+ */
+static inline size_t
+sizeof_efi_log_format_64(size_t n)
+{
+	return struct_size((struct xfs_efi_log_format_64 *)0, efi_extents, n);
+}
+
 /*
  * Copy an EFI format buffer from the given buf, and into the destination
  * EFI format structure.
@@ -186,12 +213,9 @@ xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt)
 {
 	xfs_efi_log_format_t *src_efi_fmt = buf->i_addr;
 	uint i;
-	uint len = sizeof(xfs_efi_log_format_t) + 
-		(src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_t);  
-	uint len32 = sizeof(xfs_efi_log_format_32_t) + 
-		(src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_32_t);  
-	uint len64 = sizeof(xfs_efi_log_format_64_t) + 
-		(src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_64_t);  
+	size_t len = sizeof_efi_log_format(src_efi_fmt->efi_nextents);
+	size_t len32 = sizeof_efi_log_format_32(src_efi_fmt->efi_nextents);
+	size_t len64 = sizeof_efi_log_format_64(src_efi_fmt->efi_nextents);
 
 	if (buf->i_len == len) {
 		memcpy((char *)dst_efi_fmt, (char*)src_efi_fmt, len);
@@ -253,8 +277,8 @@ static inline int
 xfs_efd_item_sizeof(
 	struct xfs_efd_log_item *efdp)
 {
-	return sizeof(xfs_efd_log_format_t) +
-	       (efdp->efd_format.efd_nextents - 1) * sizeof(xfs_extent_t);
+	return struct_size(&efdp->efd_format, efd_extents,
+			   efdp->efd_format.efd_nextents);
 }
 
 STATIC void
@@ -328,14 +352,12 @@ xfs_trans_get_efd(
 
 	ASSERT(nextents > 0);
 
-	if (nextents > XFS_EFD_MAX_FAST_EXTENTS) {
-		efdp = kmem_zalloc(sizeof(struct xfs_efd_log_item) +
-				(nextents - 1) * sizeof(struct xfs_extent),
-				0);
-	} else {
+	if (nextents > XFS_EFD_MAX_FAST_EXTENTS)
+		efdp = kmem_zalloc(struct_size(efdp, efd_format.efd_extents,
+					nextents), 0);
+	else
 		efdp = kmem_cache_zalloc(xfs_efd_zone,
 					GFP_KERNEL | __GFP_NOFAIL);
-	}
 
 	xfs_log_item_init(tp->t_mountp, &efdp->efd_item, XFS_LI_EFD,
 			  &xfs_efd_item_ops);
@@ -666,11 +688,13 @@ xfs_efi_item_relog(
 	tp->t_flags |= XFS_TRANS_DIRTY;
 	efdp = xfs_trans_get_efd(tp, EFI_ITEM(intent), count);
 	efdp->efd_next_extent = count;
-	memcpy(efdp->efd_format.efd_extents, extp, count * sizeof(*extp));
+	memcpy(efdp->efd_format.efd_extents, extp,
+	       flex_array_size(&efdp->efd_format, efd_extents, count));
 	set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags);
 
 	efip = xfs_efi_init(tp->t_mountp, count);
-	memcpy(efip->efi_format.efi_extents, extp, count * sizeof(*extp));
+	memcpy(efip->efi_format.efi_extents, extp,
+	       flex_array_size(&efip->efi_format, efi_extents, count));
 	atomic_set(&efip->efi_next_extent, count);
 	xfs_trans_add_item(tp, &efip->efi_item);
 	set_bit(XFS_LI_DIRTY, &efip->efi_item.li_flags);
@@ -729,6 +753,26 @@ const struct xlog_recover_item_ops xlog_efi_item_ops = {
 	.commit_pass2		= xlog_recover_efi_commit_pass2,
 };
 
+/*
+ * Calculates the size of structure xfs_efd_log_format_32 followed by an
+ * array of n number of efd_extents elements.
+ */
+static inline size_t
+sizeof_efd_log_format_32(size_t n)
+{
+	return struct_size((struct xfs_efd_log_format_32 *)0, efd_extents, n);
+}
+
+/*
+ * Calculates the size of structure xfs_efd_log_format_64 followed by an
+ * array of n number of efd_extents elements.
+ */
+static inline size_t
+sizeof_efd_log_format_64(size_t n)
+{
+	return struct_size((struct xfs_efd_log_format_64 *)0, efd_extents, n);
+}
+
 /*
  * This routine is called when an EFD format structure is found in a committed
  * transaction in the log. Its purpose is to cancel the corresponding EFI if it
@@ -746,10 +790,10 @@ xlog_recover_efd_commit_pass2(
 	struct xfs_efd_log_format	*efd_formatp;
 
 	efd_formatp = item->ri_buf[0].i_addr;
-	ASSERT((item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_32_t) +
-		((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_32_t)))) ||
-	       (item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_64_t) +
-		((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_64_t)))));
+	ASSERT(item->ri_buf[0].i_len ==
+			sizeof_efd_log_format_32(efd_formatp->efd_nextents) ||
+	       item->ri_buf[0].i_len ==
+			sizeof_efd_log_format_64(efd_formatp->efd_nextents));
 
 	xlog_recover_release_intent(log, XFS_LI_EFI, efd_formatp->efd_efi_id);
 	return 0;
diff --git a/fs/xfs/xfs_ondisk.h b/fs/xfs/xfs_ondisk.h
index 0aa87c210104..f58e0510385a 100644
--- a/fs/xfs/xfs_ondisk.h
+++ b/fs/xfs/xfs_ondisk.h
@@ -118,10 +118,10 @@ xfs_check_ondisk_structs(void)
 	/* log structures */
 	XFS_CHECK_STRUCT_SIZE(struct xfs_buf_log_format,	88);
 	XFS_CHECK_STRUCT_SIZE(struct xfs_dq_logformat,		24);
-	XFS_CHECK_STRUCT_SIZE(struct xfs_efd_log_format_32,	28);
-	XFS_CHECK_STRUCT_SIZE(struct xfs_efd_log_format_64,	32);
-	XFS_CHECK_STRUCT_SIZE(struct xfs_efi_log_format_32,	28);
-	XFS_CHECK_STRUCT_SIZE(struct xfs_efi_log_format_64,	32);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_efd_log_format_32,	16);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_efd_log_format_64,	16);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_efi_log_format_32,	16);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_efi_log_format_64,	16);
 	XFS_CHECK_STRUCT_SIZE(struct xfs_extent_32,		12);
 	XFS_CHECK_STRUCT_SIZE(struct xfs_extent_64,		16);
 	XFS_CHECK_STRUCT_SIZE(struct xfs_log_dinode,		176);
-- 
2.27.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ