Skip to content

Commit 0713e5f

Browse files
ukernelidryomov
authored andcommitted
ceph: optimize pagevec iterating in ceph_writepages_start()
ceph_writepages_start() supports writing non-continuous pages. If it encounters a non-dirty or non-writeable page in pagevec, it can continue to check the rest pages in pagevec. Signed-off-by: "Yan, Zheng" <[email protected]> Signed-off-by: Ilya Dryomov <[email protected]>
1 parent 05455e1 commit 0713e5f

File tree

1 file changed

+25
-29
lines changed

1 file changed

+25
-29
lines changed

fs/ceph/addr.c

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,6 @@ static int ceph_writepages_start(struct address_space *mapping,
851851

852852
while (!done && index <= end) {
853853
unsigned i;
854-
int first;
855854
pgoff_t strip_unit_end = 0;
856855
int num_ops = 0, op_idx;
857856
int pvec_pages, locked_pages = 0;
@@ -864,7 +863,6 @@ static int ceph_writepages_start(struct address_space *mapping,
864863
max_pages = max_pages_ever;
865864

866865
get_more_pages:
867-
first = -1;
868866
want = min(end - index,
869867
min((pgoff_t)PAGEVEC_SIZE,
870868
max_pages - (pgoff_t)locked_pages) - 1)
@@ -888,7 +886,7 @@ static int ceph_writepages_start(struct address_space *mapping,
888886
unlikely(page->mapping != mapping)) {
889887
dout("!dirty or !mapping %p\n", page);
890888
unlock_page(page);
891-
break;
889+
continue;
892890
}
893891
if (!wbc->range_cyclic && page->index > end) {
894892
dout("end of range %p\n", page);
@@ -901,10 +899,6 @@ static int ceph_writepages_start(struct address_space *mapping,
901899
unlock_page(page);
902900
break;
903901
}
904-
if (wbc->sync_mode != WB_SYNC_NONE) {
905-
dout("waiting on writeback %p\n", page);
906-
wait_on_page_writeback(page);
907-
}
908902
if (page_offset(page) >= ceph_wbc.i_size) {
909903
dout("%p page eof %llu\n",
910904
page, ceph_wbc.i_size);
@@ -913,9 +907,13 @@ static int ceph_writepages_start(struct address_space *mapping,
913907
break;
914908
}
915909
if (PageWriteback(page)) {
916-
dout("%p under writeback\n", page);
917-
unlock_page(page);
918-
break;
910+
if (wbc->sync_mode == WB_SYNC_NONE) {
911+
dout("%p under writeback\n", page);
912+
unlock_page(page);
913+
continue;
914+
}
915+
dout("waiting on writeback %p\n", page);
916+
wait_on_page_writeback(page);
919917
}
920918

921919
/* only if matching snap context */
@@ -924,15 +922,13 @@ static int ceph_writepages_start(struct address_space *mapping,
924922
dout("page snapc %p %lld > oldest %p %lld\n",
925923
pgsnapc, pgsnapc->seq, snapc, snapc->seq);
926924
unlock_page(page);
927-
if (!locked_pages)
928-
continue; /* keep looking for snap */
929-
break;
925+
continue;
930926
}
931927

932928
if (!clear_page_dirty_for_io(page)) {
933929
dout("%p !clear_page_dirty_for_io\n", page);
934930
unlock_page(page);
935-
break;
931+
continue;
936932
}
937933

938934
/*
@@ -988,8 +984,6 @@ static int ceph_writepages_start(struct address_space *mapping,
988984
}
989985

990986
/* note position of first page in pvec */
991-
if (first < 0)
992-
first = i;
993987
dout("%p will write page %p idx %lu\n",
994988
inode, page, page->index);
995989

@@ -1000,32 +994,34 @@ static int ceph_writepages_start(struct address_space *mapping,
1000994
BLK_RW_ASYNC);
1001995
}
1002996

1003-
pages[locked_pages] = page;
1004-
locked_pages++;
997+
998+
pages[locked_pages++] = page;
999+
pvec.pages[i] = NULL;
1000+
10051001
len += PAGE_SIZE;
10061002
}
10071003

10081004
/* did we get anything? */
10091005
if (!locked_pages)
10101006
goto release_pvec_pages;
10111007
if (i) {
1012-
int j;
1013-
BUG_ON(!locked_pages || first < 0);
1008+
unsigned j, n = 0;
1009+
/* shift unused page to beginning of pvec */
1010+
for (j = 0; j < pvec_pages; j++) {
1011+
if (!pvec.pages[j])
1012+
continue;
1013+
if (n < j)
1014+
pvec.pages[n] = pvec.pages[j];
1015+
n++;
1016+
}
1017+
pvec.nr = n;
10141018

10151019
if (pvec_pages && i == pvec_pages &&
10161020
locked_pages < max_pages) {
10171021
dout("reached end pvec, trying for more\n");
1018-
pagevec_reinit(&pvec);
1022+
pagevec_release(&pvec);
10191023
goto get_more_pages;
10201024
}
1021-
1022-
/* shift unused pages over in the pvec... we
1023-
* will need to release them below. */
1024-
for (j = i; j < pvec_pages; j++) {
1025-
dout(" pvec leftover page %p\n", pvec.pages[j]);
1026-
pvec.pages[j-i+first] = pvec.pages[j];
1027-
}
1028-
pvec.nr -= i-first;
10291025
}
10301026

10311027
new_request:

0 commit comments

Comments
 (0)