LGTM
在 2024/7/13 16:45, Zhang Yi 写道:
hulk inclusion category: perf bugzilla: https://gitee.com/openeuler/kernel/issues/IACNS4 CVE: NA
The block range calculation in ifs_clear_range_dirty() is incorrect when partial clear a range in a folio. We can't clear the dirty bit of the first block or the last block if the start or end offset is blocksize unaligned, this has not yet caused any issue since we always clear a whole folio in iomap_writepage_map()->iomap_clear_range_dirty(). Fix this by round up the first block and round down the last block and correct the calculation of nr_blks.
Signed-off-by: Zhang Yi yi.zhang@huawei.com
fs/iomap/buffered-io.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index 049b3a6f9b08..db191503cfcd 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -136,11 +136,14 @@ static void ifs_clear_range_dirty(struct folio *folio, { struct inode *inode = folio->mapping->host; unsigned int blks_per_folio = i_blocks_per_folio(inode, folio);
- unsigned int first_blk = (off >> inode->i_blkbits);
- unsigned int last_blk = (off + len - 1) >> inode->i_blkbits;
- unsigned int nr_blks = last_blk - first_blk + 1;
unsigned int first_blk = DIV_ROUND_UP(off, i_blocksize(inode));
unsigned int last_blk = (off + len) >> inode->i_blkbits;
unsigned int nr_blks = last_blk - first_blk; unsigned long flags;
if (!nr_blks)
return;
spin_lock_irqsave(&ifs->state_lock, flags); bitmap_clear(ifs->state, first_blk + blks_per_folio, nr_blks); spin_unlock_irqrestore(&ifs->state_lock, flags);