afs: convert afs_writepages_region() to use filemap_get_folios_tag()
Convert to use folios throughout. This function is in preparation to remove find_get_pages_range_tag(). Also modify this function to write the whole batch one at a time, rather than calling for a new set every single write. Link: https://lkml.kernel.org/r/20230104211448.4804-6-vishal.moola@gmail.com Signed-off-by: Vishal Moola (Oracle) <vishal.moola@gmail.com> Tested-by: David Howells <dhowells@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
0fff435f06
commit
acc8d8588c
1 changed files with 63 additions and 61 deletions
124
fs/afs/write.c
124
fs/afs/write.c
|
@ -704,85 +704,87 @@ static int afs_writepages_region(struct address_space *mapping,
|
||||||
bool max_one_loop)
|
bool max_one_loop)
|
||||||
{
|
{
|
||||||
struct folio *folio;
|
struct folio *folio;
|
||||||
struct page *head_page;
|
struct folio_batch fbatch;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
unsigned int i;
|
||||||
int n, skips = 0;
|
int n, skips = 0;
|
||||||
|
|
||||||
_enter("%llx,%llx,", start, end);
|
_enter("%llx,%llx,", start, end);
|
||||||
|
folio_batch_init(&fbatch);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
pgoff_t index = start / PAGE_SIZE;
|
pgoff_t index = start / PAGE_SIZE;
|
||||||
|
|
||||||
n = find_get_pages_range_tag(mapping, &index, end / PAGE_SIZE,
|
n = filemap_get_folios_tag(mapping, &index, end / PAGE_SIZE,
|
||||||
PAGECACHE_TAG_DIRTY, 1, &head_page);
|
PAGECACHE_TAG_DIRTY, &fbatch);
|
||||||
|
|
||||||
if (!n)
|
if (!n)
|
||||||
break;
|
break;
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
folio = fbatch.folios[i];
|
||||||
|
start = folio_pos(folio); /* May regress with THPs */
|
||||||
|
|
||||||
folio = page_folio(head_page);
|
_debug("wback %lx", folio_index(folio));
|
||||||
start = folio_pos(folio); /* May regress with THPs */
|
|
||||||
|
|
||||||
_debug("wback %lx", folio_index(folio));
|
/* At this point we hold neither the i_pages lock nor the
|
||||||
|
* page lock: the page may be truncated or invalidated
|
||||||
|
* (changing page->mapping to NULL), or even swizzled
|
||||||
|
* back from swapper_space to tmpfs file mapping
|
||||||
|
*/
|
||||||
|
if (wbc->sync_mode != WB_SYNC_NONE) {
|
||||||
|
ret = folio_lock_killable(folio);
|
||||||
|
if (ret < 0) {
|
||||||
|
folio_batch_release(&fbatch);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!folio_trylock(folio))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* At this point we hold neither the i_pages lock nor the
|
if (folio->mapping != mapping ||
|
||||||
* page lock: the page may be truncated or invalidated
|
!folio_test_dirty(folio)) {
|
||||||
* (changing page->mapping to NULL), or even swizzled
|
start += folio_size(folio);
|
||||||
* back from swapper_space to tmpfs file mapping
|
folio_unlock(folio);
|
||||||
*/
|
continue;
|
||||||
if (wbc->sync_mode != WB_SYNC_NONE) {
|
}
|
||||||
ret = folio_lock_killable(folio);
|
|
||||||
|
if (folio_test_writeback(folio) ||
|
||||||
|
folio_test_fscache(folio)) {
|
||||||
|
folio_unlock(folio);
|
||||||
|
if (wbc->sync_mode != WB_SYNC_NONE) {
|
||||||
|
folio_wait_writeback(folio);
|
||||||
|
#ifdef CONFIG_AFS_FSCACHE
|
||||||
|
folio_wait_fscache(folio);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
start += folio_size(folio);
|
||||||
|
}
|
||||||
|
if (wbc->sync_mode == WB_SYNC_NONE) {
|
||||||
|
if (skips >= 5 || need_resched()) {
|
||||||
|
*_next = start;
|
||||||
|
_leave(" = 0 [%llx]", *_next);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
skips++;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!folio_clear_dirty_for_io(folio))
|
||||||
|
BUG();
|
||||||
|
ret = afs_write_back_from_locked_folio(mapping, wbc,
|
||||||
|
folio, start, end);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
folio_put(folio);
|
_leave(" = %zd", ret);
|
||||||
|
folio_batch_release(&fbatch);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (!folio_trylock(folio)) {
|
start += ret;
|
||||||
folio_put(folio);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (folio_mapping(folio) != mapping ||
|
folio_batch_release(&fbatch);
|
||||||
!folio_test_dirty(folio)) {
|
|
||||||
start += folio_size(folio);
|
|
||||||
folio_unlock(folio);
|
|
||||||
folio_put(folio);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (folio_test_writeback(folio) ||
|
|
||||||
folio_test_fscache(folio)) {
|
|
||||||
folio_unlock(folio);
|
|
||||||
if (wbc->sync_mode != WB_SYNC_NONE) {
|
|
||||||
folio_wait_writeback(folio);
|
|
||||||
#ifdef CONFIG_AFS_FSCACHE
|
|
||||||
folio_wait_fscache(folio);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
start += folio_size(folio);
|
|
||||||
}
|
|
||||||
folio_put(folio);
|
|
||||||
if (wbc->sync_mode == WB_SYNC_NONE) {
|
|
||||||
if (skips >= 5 || need_resched())
|
|
||||||
break;
|
|
||||||
skips++;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!folio_clear_dirty_for_io(folio))
|
|
||||||
BUG();
|
|
||||||
ret = afs_write_back_from_locked_folio(mapping, wbc, folio, start, end);
|
|
||||||
folio_put(folio);
|
|
||||||
if (ret < 0) {
|
|
||||||
_leave(" = %zd", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
start += ret;
|
|
||||||
|
|
||||||
if (max_one_loop)
|
|
||||||
break;
|
|
||||||
|
|
||||||
cond_resched();
|
cond_resched();
|
||||||
} while (wbc->nr_to_write > 0);
|
} while (wbc->nr_to_write > 0);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue