[PATCH 4/5] xfs: fix attribute log iovec sizing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Dave Chinner <dchinner@xxxxxxxxxx>

The sizing of the attri name and value log iovecs is incorrect.
This results in memory corruption and crashes on a kernel with
the current CIL scalability patchset applied as it relies on the
callers playing by slightly different alignment rules.

Convert the attri code to the new xlog_calc_iovec_size() API to
fix these issues.

Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx>
---
 fs/xfs/xfs_attr_item.c | 29 ++++++++---------------------
 1 file changed, 8 insertions(+), 21 deletions(-)

diff --git a/fs/xfs/xfs_attr_item.c b/fs/xfs/xfs_attr_item.c
index 4072972a2ed8..bd4089eb8087 100644
--- a/fs/xfs/xfs_attr_item.c
+++ b/fs/xfs/xfs_attr_item.c
@@ -42,13 +42,6 @@
 static const struct xfs_item_ops xfs_attri_item_ops;
 static const struct xfs_item_ops xfs_attrd_item_ops;
 
-/* iovec length must be 32-bit aligned */
-static inline size_t ATTR_NVEC_SIZE(size_t size)
-{
-	return size == sizeof(int32_t) ? size :
-	       sizeof(int32_t) + round_up(size, sizeof(int32_t));
-}
-
 static inline struct xfs_attri_log_item *ATTRI_ITEM(struct xfs_log_item *lip)
 {
 	return container_of(lip, struct xfs_attri_log_item, attri_item);
@@ -89,19 +82,15 @@ xfs_attri_item_size(
 {
 	struct xfs_attri_log_item       *attrip = ATTRI_ITEM(lip);
 
-	*nvecs += 1;
-	*nbytes += sizeof(struct xfs_attri_log_format);
+	*nvecs += 2;
+	*nbytes += sizeof(struct xfs_attri_log_format) +
+			xlog_calc_iovec_len(attrip->attri_name_len);
 
-	/* Attr set and remove operations require a name */
-	ASSERT(attrip->attri_name_len > 0);
+	if (!attrip->attri_value_len)
+		return;
 
 	*nvecs += 1;
-	*nbytes += ATTR_NVEC_SIZE(attrip->attri_name_len);
-
-	if (attrip->attri_value_len > 0) {
-		*nvecs += 1;
-		*nbytes += ATTR_NVEC_SIZE(attrip->attri_value_len);
-	}
+	*nbytes += xlog_calc_iovec_len(attrip->attri_value_len);
 }
 
 /*
@@ -137,12 +126,10 @@ xfs_attri_item_format(
 			&attrip->attri_format,
 			sizeof(struct xfs_attri_log_format));
 	xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ATTR_NAME,
-			attrip->attri_name,
-			ATTR_NVEC_SIZE(attrip->attri_name_len));
+			attrip->attri_name, attrip->attri_name_len);
 	if (attrip->attri_value_len > 0)
 		xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ATTR_VALUE,
-				attrip->attri_value,
-				ATTR_NVEC_SIZE(attrip->attri_value_len));
+				attrip->attri_value, attrip->attri_value_len);
 }
 
 /*
-- 
2.31.1




[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux