From: Simon Glass <simon.glass@canonical.com> The set_bit(), clear_bit(), and change_bit() functions only modify the first word of a bitmap, regardless of the bit number. For bit numbers
= 64 on 64-bit systems, the shift wraps around and modifies the wrong bit position.
Fix these functions to properly calculate the word offset before modifying the bit. This is needed for block bitmap operations where bit numbers can be in the thousands. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/stub.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/fs/ext4l/stub.c b/fs/ext4l/stub.c index 2b7618df64c..f072cb5713f 100644 --- a/fs/ext4l/stub.c +++ b/fs/ext4l/stub.c @@ -77,26 +77,27 @@ typedef struct journal_s journal_t; /* * Bit operations - sandbox declares these extern but doesn't implement them. + * These work on bitmaps where nr is the absolute bit number. */ void set_bit(int nr, void *addr) { - unsigned long *p = (unsigned long *)addr; + unsigned long *p = (unsigned long *)addr + (nr / BITS_PER_LONG); - *p |= (1UL << nr); + *p |= (1UL << (nr % BITS_PER_LONG)); } void clear_bit(int nr, void *addr) { - unsigned long *p = (unsigned long *)addr; + unsigned long *p = (unsigned long *)addr + (nr / BITS_PER_LONG); - *p &= ~(1UL << nr); + *p &= ~(1UL << (nr % BITS_PER_LONG)); } void change_bit(int nr, void *addr) { - unsigned long *p = (unsigned long *)addr; + unsigned long *p = (unsigned long *)addr + (nr / BITS_PER_LONG); - *p ^= (1UL << nr); + *p ^= (1UL << (nr % BITS_PER_LONG)); } /* -- 2.43.0