Skip to content

Commit

Permalink
ceph: wait on writeback after writing snapshot data
Browse files Browse the repository at this point in the history
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: "Yan, Zheng" <zyan@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
  • Loading branch information
Yan, Zheng authored and Ilya Dryomov committed Sep 6, 2017
1 parent 7e1ee54 commit f275635
Showing 1 changed file with 24 additions and 0 deletions.
24 changes: 24 additions & 0 deletions fs/ceph/addr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,30 @@ static int ceph_writepages_start(struct address_space *mapping,
/* more to do; loop back to beginning of file */
dout("writepages looping back to beginning of file\n");
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;
index = 0;
goto retry;
Expand Down

0 comments on commit f275635

Please sign in to comment.