All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] btrfs: add special case to setget helpers for 64k pages
@ 2021-07-01 16:00 David Sterba
  2021-07-01 21:57 ` Gustavo A. R. Silva
  2021-07-02  7:10 ` Christoph Hellwig
  0 siblings, 2 replies; 16+ messages in thread
From: David Sterba @ 2021-07-01 16:00 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba, Gustavo A . R . Silva

On 64K pages the size of the extent_buffer::pages array is 1 and
compilation with -Warray-bounds warns due to

  kaddr = page_address(eb->pages[idx + 1]);

when reading byte range crossing page boundary.

This does never actually overflow the array because on 64K because all
the data fit in one page and bounds are checked by check_setget_bounds.

To fix the reported overflow and warning add a copy of the non-crossing
read/write code and put it behind a condition that's evaluated at
compile time. That way only one implementation remains due to dead code
elimination.

Link: https://lore.kernel.org/lkml/20210623083901.1d49d19d@canb.auug.org.au/
CC: Gustavo A. R. Silva <gustavoars@kernel.org>
Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/struct-funcs.c | 66 +++++++++++++++++++++++++----------------
 1 file changed, 41 insertions(+), 25 deletions(-)

diff --git a/fs/btrfs/struct-funcs.c b/fs/btrfs/struct-funcs.c
index 8260f8bb3ff0..51204b280da8 100644
--- a/fs/btrfs/struct-funcs.c
+++ b/fs/btrfs/struct-funcs.c
@@ -73,14 +73,18 @@ u##bits btrfs_get_token_##bits(struct btrfs_map_token *token,		\
 	}								\
 	token->kaddr = page_address(token->eb->pages[idx]);		\
 	token->offset = idx << PAGE_SHIFT;				\
-	if (oip + size <= PAGE_SIZE)					\
+	if (INLINE_EXTENT_BUFFER_PAGES == 1) {				\
 		return get_unaligned_le##bits(token->kaddr + oip);	\
+	} else {							\
+		if (oip + size <= PAGE_SIZE)				\
+			return get_unaligned_le##bits(token->kaddr + oip); \
 									\
-	memcpy(lebytes, token->kaddr + oip, part);			\
-	token->kaddr = page_address(token->eb->pages[idx + 1]);		\
-	token->offset = (idx + 1) << PAGE_SHIFT;			\
-	memcpy(lebytes + part, token->kaddr, size - part);		\
-	return get_unaligned_le##bits(lebytes);				\
+		memcpy(lebytes, token->kaddr + oip, part);		\
+		token->kaddr = page_address(token->eb->pages[idx + 1]);	\
+		token->offset = (idx + 1) << PAGE_SHIFT;		\
+		memcpy(lebytes + part, token->kaddr, size - part);	\
+		return get_unaligned_le##bits(lebytes);			\
+	}								\
 }									\
 u##bits btrfs_get_##bits(const struct extent_buffer *eb,		\
 			 const void *ptr, unsigned long off)		\
@@ -94,13 +98,17 @@ u##bits btrfs_get_##bits(const struct extent_buffer *eb,		\
 	u8 lebytes[sizeof(u##bits)];					\
 									\
 	ASSERT(check_setget_bounds(eb, ptr, off, size));		\
-	if (oip + size <= PAGE_SIZE)					\
+	if (INLINE_EXTENT_BUFFER_PAGES == 1) {				\
 		return get_unaligned_le##bits(kaddr + oip);		\
+	} else {							\
+		if (oip + size <= PAGE_SIZE)				\
+			return get_unaligned_le##bits(kaddr + oip);	\
 									\
-	memcpy(lebytes, kaddr + oip, part);				\
-	kaddr = page_address(eb->pages[idx + 1]);			\
-	memcpy(lebytes + part, kaddr, size - part);			\
-	return get_unaligned_le##bits(lebytes);				\
+		memcpy(lebytes, kaddr + oip, part);			\
+		kaddr = page_address(eb->pages[idx + 1]);		\
+		memcpy(lebytes + part, kaddr, size - part);		\
+		return get_unaligned_le##bits(lebytes);			\
+	}								\
 }									\
 void btrfs_set_token_##bits(struct btrfs_map_token *token,		\
 			    const void *ptr, unsigned long off,		\
@@ -124,15 +132,19 @@ void btrfs_set_token_##bits(struct btrfs_map_token *token,		\
 	}								\
 	token->kaddr = page_address(token->eb->pages[idx]);		\
 	token->offset = idx << PAGE_SHIFT;				\
-	if (oip + size <= PAGE_SIZE) {					\
+	if (INLINE_EXTENT_BUFFER_PAGES == 1) {				\
 		put_unaligned_le##bits(val, token->kaddr + oip);	\
-		return;							\
+	} else {							\
+		if (oip + size <= PAGE_SIZE) {				\
+			put_unaligned_le##bits(val, token->kaddr + oip); \
+			return;						\
+		}							\
+		put_unaligned_le##bits(val, lebytes);			\
+		memcpy(token->kaddr + oip, lebytes, part);		\
+		token->kaddr = page_address(token->eb->pages[idx + 1]);	\
+		token->offset = (idx + 1) << PAGE_SHIFT;		\
+		memcpy(token->kaddr, lebytes + part, size - part);	\
 	}								\
-	put_unaligned_le##bits(val, lebytes);				\
-	memcpy(token->kaddr + oip, lebytes, part);			\
-	token->kaddr = page_address(token->eb->pages[idx + 1]);		\
-	token->offset = (idx + 1) << PAGE_SHIFT;			\
-	memcpy(token->kaddr, lebytes + part, size - part);		\
 }									\
 void btrfs_set_##bits(const struct extent_buffer *eb, void *ptr,	\
 		      unsigned long off, u##bits val)			\
@@ -146,15 +158,19 @@ void btrfs_set_##bits(const struct extent_buffer *eb, void *ptr,	\
 	u8 lebytes[sizeof(u##bits)];					\
 									\
 	ASSERT(check_setget_bounds(eb, ptr, off, size));		\
-	if (oip + size <= PAGE_SIZE) {					\
+	if (INLINE_EXTENT_BUFFER_PAGES == 1) {				\
 		put_unaligned_le##bits(val, kaddr + oip);		\
-		return;							\
-	}								\
+	} else {							\
+		if (oip + size <= PAGE_SIZE) {				\
+			put_unaligned_le##bits(val, kaddr + oip);	\
+			return;						\
+		}							\
 									\
-	put_unaligned_le##bits(val, lebytes);				\
-	memcpy(kaddr + oip, lebytes, part);				\
-	kaddr = page_address(eb->pages[idx + 1]);			\
-	memcpy(kaddr, lebytes + part, size - part);			\
+		put_unaligned_le##bits(val, lebytes);			\
+		memcpy(kaddr + oip, lebytes, part);			\
+		kaddr = page_address(eb->pages[idx + 1]);		\
+		memcpy(kaddr, lebytes + part, size - part);		\
+	}								\
 }
 
 DEFINE_BTRFS_SETGET_BITS(8)
-- 
2.31.1


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

end of thread, other threads:[~2021-07-28 16:03 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-01 16:00 [PATCH] btrfs: add special case to setget helpers for 64k pages David Sterba
2021-07-01 21:57 ` Gustavo A. R. Silva
2021-07-01 23:59   ` Qu Wenruo
2021-07-02  0:09     ` Gustavo A. R. Silva
2021-07-02  0:21       ` Qu Wenruo
2021-07-02  0:39         ` Gustavo A. R. Silva
2021-07-02  0:39           ` Qu Wenruo
2021-07-02  1:09             ` Gustavo A. R. Silva
2021-07-02 10:22           ` David Sterba
2021-07-02  7:10 ` Christoph Hellwig
2021-07-02 11:06   ` David Sterba
2021-07-05  8:33     ` Christoph Hellwig
2021-07-08 14:34       ` David Sterba
2021-07-14 23:37         ` Gustavo A. R. Silva
2021-07-28 15:32           ` David Sterba
2021-07-28 16:00             ` David Sterba

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.