Skip to content

Commit b56c1c5

Browse files
joannekoongbrauner
authored andcommitted
iomap: use find_next_bit() for uptodate bitmap scanning
Use find_next_bit()/find_next_zero_bit() for iomap uptodate bitmap scanning. This uses __ffs() internally and is more efficient for finding the next uptodate or non-uptodate bit than iterating through the the bitmap range testing every bit. Signed-off-by: Joanne Koong <joannelkoong@gmail.com> Link: https://patch.msgid.link/20251111193658.3495942-10-joannelkoong@gmail.com Reviewed-by: Darrick J. Wong <djwong@kernel.org> Suggested-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent fed9c62 commit b56c1c5

1 file changed

Lines changed: 32 additions & 20 deletions

File tree

fs/iomap/buffered-io.c

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,28 @@ static inline bool ifs_is_fully_uptodate(struct folio *folio,
3838
return bitmap_full(ifs->state, i_blocks_per_folio(inode, folio));
3939
}
4040

41-
static inline bool ifs_block_is_uptodate(struct iomap_folio_state *ifs,
42-
unsigned int block)
41+
/*
42+
* Find the next uptodate block in the folio. end_blk is inclusive.
43+
* If no uptodate block is found, this will return end_blk + 1.
44+
*/
45+
static unsigned ifs_next_uptodate_block(struct folio *folio,
46+
unsigned start_blk, unsigned end_blk)
4347
{
44-
return test_bit(block, ifs->state);
48+
struct iomap_folio_state *ifs = folio->private;
49+
50+
return find_next_bit(ifs->state, end_blk + 1, start_blk);
51+
}
52+
53+
/*
54+
* Find the next non-uptodate block in the folio. end_blk is inclusive.
55+
* If no non-uptodate block is found, this will return end_blk + 1.
56+
*/
57+
static unsigned ifs_next_nonuptodate_block(struct folio *folio,
58+
unsigned start_blk, unsigned end_blk)
59+
{
60+
struct iomap_folio_state *ifs = folio->private;
61+
62+
return find_next_zero_bit(ifs->state, end_blk + 1, start_blk);
4563
}
4664

4765
static bool ifs_set_range_uptodate(struct folio *folio,
@@ -277,14 +295,11 @@ static void iomap_adjust_read_range(struct inode *inode, struct folio *folio,
277295
* to avoid reading in already uptodate ranges.
278296
*/
279297
if (ifs) {
280-
unsigned int i, blocks_skipped;
298+
unsigned int next, blocks_skipped;
281299

282-
/* move forward for each leading block marked uptodate */
283-
for (i = first; i <= last; i++)
284-
if (!ifs_block_is_uptodate(ifs, i))
285-
break;
300+
next = ifs_next_nonuptodate_block(folio, first, last);
301+
blocks_skipped = next - first;
286302

287-
blocks_skipped = i - first;
288303
if (blocks_skipped) {
289304
unsigned long block_offset = *pos & (block_size - 1);
290305
unsigned bytes_skipped =
@@ -294,15 +309,15 @@ static void iomap_adjust_read_range(struct inode *inode, struct folio *folio,
294309
poff += bytes_skipped;
295310
plen -= bytes_skipped;
296311
}
297-
first = i;
312+
first = next;
298313

299314
/* truncate len if we find any trailing uptodate block(s) */
300-
while (++i <= last) {
301-
if (ifs_block_is_uptodate(ifs, i)) {
315+
if (++next <= last) {
316+
next = ifs_next_uptodate_block(folio, next, last);
317+
if (next <= last) {
302318
plen -= iomap_bytes_to_truncate(*pos + plen,
303-
block_bits, last - i + 1);
304-
last = i - 1;
305-
break;
319+
block_bits, last - next + 1);
320+
last = next - 1;
306321
}
307322
}
308323
}
@@ -639,7 +654,7 @@ bool iomap_is_partially_uptodate(struct folio *folio, size_t from, size_t count)
639654
{
640655
struct iomap_folio_state *ifs = folio->private;
641656
struct inode *inode = folio->mapping->host;
642-
unsigned first, last, i;
657+
unsigned first, last;
643658

644659
if (!ifs)
645660
return false;
@@ -651,10 +666,7 @@ bool iomap_is_partially_uptodate(struct folio *folio, size_t from, size_t count)
651666
first = from >> inode->i_blkbits;
652667
last = (from + count - 1) >> inode->i_blkbits;
653668

654-
for (i = first; i <= last; i++)
655-
if (!ifs_block_is_uptodate(ifs, i))
656-
return false;
657-
return true;
669+
return ifs_next_nonuptodate_block(folio, first, last) > last;
658670
}
659671
EXPORT_SYMBOL_GPL(iomap_is_partially_uptodate);
660672

0 commit comments

Comments
 (0)