提交 f275635e 编写于 作者: Y Yan, Zheng 提交者: Ilya Dryomov

ceph: wait on writeback after writing snapshot data

In sync mode, writepages() needs to write all dirty pages. But
it can only write dirty pages associated with the oldest snapc.
To write dirty pages associated with next snapc, it needs to wait
until current writes complete.

Without this wait, writepages() keeps looking up dirty pages, but
the found dirty pages are not writeable. It wastes CPU time.
Signed-off-by: N"Yan, Zheng" <zyan@redhat.com>
Signed-off-by: NIlya Dryomov <idryomov@gmail.com>
上级 7e1ee54a
...@@ -1165,6 +1165,30 @@ static int ceph_writepages_start(struct address_space *mapping, ...@@ -1165,6 +1165,30 @@ static int ceph_writepages_start(struct address_space *mapping,
/* more to do; loop back to beginning of file */ /* more to do; loop back to beginning of file */
dout("writepages looping back to beginning of file\n"); dout("writepages looping back to beginning of file\n");
end = start_index - 1; /* OK even when start_index == 0 */ end = start_index - 1; /* OK even when start_index == 0 */
/* to write dirty pages associated with next snapc,
* we need to wait until current writes complete */
if (wbc->sync_mode != WB_SYNC_NONE &&
start_index == 0 && /* all dirty pages were checked */
!ceph_wbc.head_snapc) {
struct page *page;
unsigned i, nr;
index = 0;
while ((index <= end) &&
(nr = pagevec_lookup_tag(&pvec, mapping, &index,
PAGECACHE_TAG_WRITEBACK,
PAGEVEC_SIZE))) {
for (i = 0; i < nr; i++) {
page = pvec.pages[i];
if (page_snap_context(page) != snapc)
continue;
wait_on_page_writeback(page);
}
pagevec_release(&pvec);
cond_resched();
}
}
start_index = 0; start_index = 0;
index = 0; index = 0;
goto retry; goto retry;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册