[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20200824183424.4222-1-willy@infradead.org>
Date: Mon, 24 Aug 2020 19:34:24 +0100
From: "Matthew Wilcox (Oracle)" <willy@...radead.org>
To: David Howells <dhowells@...hat.com>
Cc: "Matthew Wilcox (Oracle)" <willy@...radead.org>,
linux-afs@...ts.infradead.org, linux-kernel@...r.kernel.org
Subject: [PATCH] afs: Use a pagevec in afs_writepages()
This amortises the overhead of retrieving pages from the pagecache
and the overhead of freeing pages if we happen to end up with the
last references to the pages.
Signed-off-by: Matthew Wilcox (Oracle) <willy@...radead.org>
---
fs/afs/write.c | 41 ++++++++++++++++++++++++-----------------
1 file changed, 24 insertions(+), 17 deletions(-)
diff --git a/fs/afs/write.c b/fs/afs/write.c
index a121c247d95a..2d20037c7ff0 100644
--- a/fs/afs/write.c
+++ b/fs/afs/write.c
@@ -673,16 +673,24 @@ static int afs_writepages_region(struct address_space *mapping,
struct writeback_control *wbc,
pgoff_t index, pgoff_t end, pgoff_t *_next)
{
- struct page *page;
- int ret, n;
+ struct pagevec pvec;
+ int ret, i = 0;
_enter(",,%lx,%lx,", index, end);
+ pagevec_init(&pvec);
do {
- n = find_get_pages_range_tag(mapping, &index, end,
- PAGECACHE_TAG_DIRTY, 1, &page);
- if (!n)
- break;
+ struct page *page;
+
+ if (i == pagevec_count(&pvec)) {
+ pagevec_release(&pvec);
+ if (!pagevec_lookup_range_tag(&pvec, mapping,
+ &index, end, PAGECACHE_TAG_DIRTY))
+ break;
+ i = 0;
+ }
+
+ page = pvec.pages[i++];
_debug("wback %lx", page->index);
@@ -693,15 +701,11 @@ static int afs_writepages_region(struct address_space *mapping,
* back from swapper_space to tmpfs file mapping
*/
ret = lock_page_killable(page);
- if (ret < 0) {
- put_page(page);
- _leave(" = %d", ret);
- return ret;
- }
+ if (ret < 0)
+ goto err;
if (page->mapping != mapping || !PageDirty(page)) {
unlock_page(page);
- put_page(page);
continue;
}
@@ -709,7 +713,6 @@ static int afs_writepages_region(struct address_space *mapping,
unlock_page(page);
if (wbc->sync_mode != WB_SYNC_NONE)
wait_on_page_writeback(page);
- put_page(page);
continue;
}
@@ -717,19 +720,23 @@ static int afs_writepages_region(struct address_space *mapping,
BUG();
ret = afs_write_back_from_locked_page(mapping, wbc, page, end);
put_page(page);
- if (ret < 0) {
- _leave(" = %d", ret);
- return ret;
- }
+ if (ret < 0)
+ goto err;
wbc->nr_to_write -= ret;
cond_resched();
} while (index < end && wbc->nr_to_write > 0);
+ pagevec_release(&pvec);
*_next = index;
_leave(" = 0 [%lx]", *_next);
return 0;
+
+err:
+ pagevec_release(&pvec);
+ _leave(" = %d", ret);
+ return ret;
}
/*
--
2.28.0
Powered by blists - more mailing lists