diff options
Diffstat (limited to 'fs/buffer.c')
-rw-r--r-- | fs/buffer.c | 65 |
1 files changed, 28 insertions, 37 deletions
diff --git a/fs/buffer.c b/fs/buffer.c index ce9844d7c10f..cbdfc0c79aae 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -1604,53 +1604,44 @@ void clean_bdev_aliases(struct block_device *bdev, sector_t block, sector_t len) { struct inode *bd_inode = bdev->bd_inode; struct address_space *bd_mapping = bd_inode->i_mapping; - struct folio_batch fbatch; + struct folio_iter_batched iter; + struct folio *folio; pgoff_t index = block >> (PAGE_SHIFT - bd_inode->i_blkbits); pgoff_t end; - int i, count; struct buffer_head *bh; struct buffer_head *head; end = (block + len - 1) >> (PAGE_SHIFT - bd_inode->i_blkbits); - folio_batch_init(&fbatch); - while (filemap_get_folios(bd_mapping, &index, end, &fbatch)) { - count = folio_batch_count(&fbatch); - for (i = 0; i < count; i++) { - struct folio *folio = fbatch.folios[i]; - if (!folio_buffers(folio)) - continue; - /* - * We use folio lock instead of bd_mapping->private_lock - * to pin buffers here since we can afford to sleep and - * it scales better than a global spinlock lock. - */ - folio_lock(folio); - /* Recheck when the folio is locked which pins bhs */ - head = folio_buffers(folio); - if (!head) - goto unlock_page; - bh = head; - do { - if (!buffer_mapped(bh) || (bh->b_blocknr < block)) - goto next; - if (bh->b_blocknr >= block + len) - break; - clear_buffer_dirty(bh); - wait_on_buffer(bh); - clear_buffer_req(bh); + for_each_folio_batched(bd_mapping, iter, index, end, folio) { + if (!folio_buffers(folio)) + continue; + /* + * We use folio lock instead of bd_mapping->private_lock + * to pin buffers here since we can afford to sleep and + * it scales better than a global spinlock lock. + */ + folio_lock(folio); + /* Recheck when the folio is locked which pins bhs */ + head = folio_buffers(folio); + if (!head) + goto unlock_page; + bh = head; + do { + if (!buffer_mapped(bh) || (bh->b_blocknr < block)) + goto next; + if (bh->b_blocknr >= block + len) + break; + clear_buffer_dirty(bh); + wait_on_buffer(bh); + clear_buffer_req(bh); next: - bh = bh->b_this_page; - } while (bh != head); + bh = bh->b_this_page; + } while (bh != head); unlock_page: - folio_unlock(folio); - } - folio_batch_release(&fbatch); - cond_resched(); - /* End of range already reached? */ - if (index > end || !index) - break; + folio_unlock(folio); } + folio_iter_batched_exit(&iter); } EXPORT_SYMBOL(clean_bdev_aliases); |