Skip to content

Commit f275635

Browse files
ukernelidryomov
authored andcommitted
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: "Yan, Zheng" <[email protected]> Signed-off-by: Ilya Dryomov <[email protected]>
1 parent 7e1ee54 commit f275635

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

fs/ceph/addr.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,6 +1165,30 @@ static int ceph_writepages_start(struct address_space *mapping,
11651165
/* more to do; loop back to beginning of file */
11661166
dout("writepages looping back to beginning of file\n");
11671167
end = start_index - 1; /* OK even when start_index == 0 */
1168+
1169+
/* to write dirty pages associated with next snapc,
1170+
* we need to wait until current writes complete */
1171+
if (wbc->sync_mode != WB_SYNC_NONE &&
1172+
start_index == 0 && /* all dirty pages were checked */
1173+
!ceph_wbc.head_snapc) {
1174+
struct page *page;
1175+
unsigned i, nr;
1176+
index = 0;
1177+
while ((index <= end) &&
1178+
(nr = pagevec_lookup_tag(&pvec, mapping, &index,
1179+
PAGECACHE_TAG_WRITEBACK,
1180+
PAGEVEC_SIZE))) {
1181+
for (i = 0; i < nr; i++) {
1182+
page = pvec.pages[i];
1183+
if (page_snap_context(page) != snapc)
1184+
continue;
1185+
wait_on_page_writeback(page);
1186+
}
1187+
pagevec_release(&pvec);
1188+
cond_resched();
1189+
}
1190+
}
1191+
11681192
start_index = 0;
11691193
index = 0;
11701194
goto retry;

0 commit comments

Comments
 (0)