[PATCH 2/2] btrfs: replace 64-bit division with a shift

From: Arnd Bergmann
Date: Tue Feb 25 2025 - 14:44:50 EST


From: Arnd Bergmann <arnd@xxxxxxxx>

folio_size() is not a compile-time constant, so in some configurations,
the DIV_ROUND_UP() turns into a 64-bit division that is not allowed
on 32-bit architectures.

x86_64-linux-ld: fs/btrfs/extent_io.o: in function `writepage_delalloc':
extent_io.c:(.text+0x2b6e): undefined reference to `__udivdi3'

This is probably not the correct solution, but it should illustrate
the issue. A trivial fix would be DIV64_U64_ROUND_UP(), which of course
is very expensive. Maybe there should be a DIV_ROUND_UP_FOLIO macro?

Fixes: aba063bf9336 ("btrfs: prepare extent_io.c for future larger folio support")
Signed-off-by: Arnd Bergmann <arnd@xxxxxxxx>
---
fs/btrfs/extent_io.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 7dc996e7e249..e4ba4fa3f48c 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -1505,8 +1505,7 @@ static noinline_for_stack int writepage_delalloc(struct btrfs_inode *inode,
* delalloc_end is already one less than the total length, so
* we don't subtract one from folio_size().
*/
- delalloc_to_write +=
- DIV_ROUND_UP(delalloc_end + 1 - page_start, folio_size(folio));
+ delalloc_to_write += (delalloc_end + 1 - page_start + folio_size(folio) - 1) >> folio_order(folio);

/*
* If all ranges are submitted asynchronously, we just need to account
--
2.39.5