Skip to content

Commit 590e9d9

Browse files
ukernelidryomov
authored andcommitted
ceph: fix "range cyclic" mode writepages
In range cyclic mode, writepages() should first write dirty pages in range [writeback_index, (pgoff_t)-1], then write pages in range [0, writeback_index -1]. Besides, if writepages() encounters a page that beyond EOF, it should restart from the beginning. Signed-off-by: "Yan, Zheng" <[email protected]> Signed-off-by: Ilya Dryomov <[email protected]>
1 parent 0e5ecac commit 590e9d9

File tree

1 file changed

+24
-17
lines changed

1 file changed

+24
-17
lines changed

fs/ceph/addr.c

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -781,16 +781,15 @@ static int ceph_writepages_start(struct address_space *mapping,
781781
struct ceph_inode_info *ci = ceph_inode(inode);
782782
struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
783783
struct ceph_vino vino = ceph_vino(inode);
784-
pgoff_t index, start, end;
785-
int range_whole = 0;
786-
int should_loop = 1;
784+
pgoff_t index, start_index, end;
787785
struct ceph_snap_context *snapc = NULL, *last_snapc = NULL, *pgsnapc;
788786
struct pagevec pvec;
789-
int done = 0;
790787
int rc = 0;
791788
unsigned int wsize = i_blocksize(inode);
792789
struct ceph_osd_request *req = NULL;
793790
struct ceph_writeback_ctl ceph_wbc;
791+
bool should_loop, range_whole = false;
792+
bool stop, done = false;
794793

795794
dout("writepages_start %p (mode=%s)\n", inode,
796795
wbc->sync_mode == WB_SYNC_NONE ? "NONE" :
@@ -810,20 +809,22 @@ static int ceph_writepages_start(struct address_space *mapping,
810809

811810
pagevec_init(&pvec, 0);
812811

812+
start_index = wbc->range_cyclic ? mapping->writeback_index : 0;
813+
813814
/* where to start/end? */
814815
if (wbc->range_cyclic) {
815-
start = mapping->writeback_index; /* Start from prev offset */
816+
index = start_index;
816817
end = -1;
817-
dout(" cyclic, start at %lu\n", start);
818+
should_loop = (index > 0);
819+
dout(" cyclic, start at %lu\n", index);
818820
} else {
819-
start = wbc->range_start >> PAGE_SHIFT;
821+
index = wbc->range_start >> PAGE_SHIFT;
820822
end = wbc->range_end >> PAGE_SHIFT;
821823
if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
822-
range_whole = 1;
823-
should_loop = 0;
824-
dout(" not cyclic, %lu to %lu\n", start, end);
824+
range_whole = true;
825+
should_loop = false;
826+
dout(" not cyclic, %lu to %lu\n", index, end);
825827
}
826-
index = start;
827828

828829
retry:
829830
/* find oldest snap context with dirty data */
@@ -847,7 +848,8 @@ static int ceph_writepages_start(struct address_space *mapping,
847848
}
848849
last_snapc = snapc;
849850

850-
while (!done && index <= end) {
851+
stop = false;
852+
while (!stop && index <= end) {
851853
int num_ops = 0, op_idx;
852854
unsigned i, pvec_pages, max_pages, locked_pages = 0;
853855
struct page **pages = NULL, **data_pages;
@@ -885,9 +887,11 @@ static int ceph_writepages_start(struct address_space *mapping,
885887
unlock_page(page);
886888
continue;
887889
}
888-
if (!wbc->range_cyclic && page->index > end) {
890+
if (page->index > end) {
889891
dout("end of range %p\n", page);
890-
done = 1;
892+
/* can't be range_cyclic (1st pass) because
893+
* end == -1 in that case. */
894+
stop = done = true;
891895
unlock_page(page);
892896
break;
893897
}
@@ -899,7 +903,8 @@ static int ceph_writepages_start(struct address_space *mapping,
899903
if (page_offset(page) >= ceph_wbc.i_size) {
900904
dout("%p page eof %llu\n",
901905
page, ceph_wbc.i_size);
902-
done = 1;
906+
/* not done if range_cyclic */
907+
stop = true;
903908
unlock_page(page);
904909
break;
905910
}
@@ -1132,7 +1137,7 @@ static int ceph_writepages_start(struct address_space *mapping,
11321137
goto new_request;
11331138

11341139
if (wbc->nr_to_write <= 0)
1135-
done = 1;
1140+
stop = done = true;
11361141

11371142
release_pvec_pages:
11381143
dout("pagevec_release on %d pages (%p)\n", (int)pvec.nr,
@@ -1146,7 +1151,9 @@ static int ceph_writepages_start(struct address_space *mapping,
11461151
if (should_loop && !done) {
11471152
/* more to do; loop back to beginning of file */
11481153
dout("writepages looping back to beginning of file\n");
1149-
should_loop = 0;
1154+
should_loop = false;
1155+
end = start_index - 1;
1156+
11501157
index = 0;
11511158
goto retry;
11521159
}

0 commit comments

Comments
 (0)