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

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: N"Yan, Zheng" <zyan@redhat.com>
Signed-off-by: NIlya Dryomov <idryomov@gmail.com>
上级 05455e11
...@@ -851,7 +851,6 @@ static int ceph_writepages_start(struct address_space *mapping, ...@@ -851,7 +851,6 @@ static int ceph_writepages_start(struct address_space *mapping,
while (!done && index <= end) { while (!done && index <= end) {
unsigned i; unsigned i;
int first;
pgoff_t strip_unit_end = 0; pgoff_t strip_unit_end = 0;
int num_ops = 0, op_idx; int num_ops = 0, op_idx;
int pvec_pages, locked_pages = 0; int pvec_pages, locked_pages = 0;
...@@ -864,7 +863,6 @@ static int ceph_writepages_start(struct address_space *mapping, ...@@ -864,7 +863,6 @@ static int ceph_writepages_start(struct address_space *mapping,
max_pages = max_pages_ever; max_pages = max_pages_ever;
get_more_pages: get_more_pages:
first = -1;
want = min(end - index, want = min(end - index,
min((pgoff_t)PAGEVEC_SIZE, min((pgoff_t)PAGEVEC_SIZE,
max_pages - (pgoff_t)locked_pages) - 1) max_pages - (pgoff_t)locked_pages) - 1)
...@@ -888,7 +886,7 @@ static int ceph_writepages_start(struct address_space *mapping, ...@@ -888,7 +886,7 @@ static int ceph_writepages_start(struct address_space *mapping,
unlikely(page->mapping != mapping)) { unlikely(page->mapping != mapping)) {
dout("!dirty or !mapping %p\n", page); dout("!dirty or !mapping %p\n", page);
unlock_page(page); unlock_page(page);
break; continue;
} }
if (!wbc->range_cyclic && page->index > end) { if (!wbc->range_cyclic && page->index > end) {
dout("end of range %p\n", page); dout("end of range %p\n", page);
...@@ -901,10 +899,6 @@ static int ceph_writepages_start(struct address_space *mapping, ...@@ -901,10 +899,6 @@ static int ceph_writepages_start(struct address_space *mapping,
unlock_page(page); unlock_page(page);
break; break;
} }
if (wbc->sync_mode != WB_SYNC_NONE) {
dout("waiting on writeback %p\n", page);
wait_on_page_writeback(page);
}
if (page_offset(page) >= ceph_wbc.i_size) { if (page_offset(page) >= ceph_wbc.i_size) {
dout("%p page eof %llu\n", dout("%p page eof %llu\n",
page, ceph_wbc.i_size); page, ceph_wbc.i_size);
...@@ -913,9 +907,13 @@ static int ceph_writepages_start(struct address_space *mapping, ...@@ -913,9 +907,13 @@ static int ceph_writepages_start(struct address_space *mapping,
break; break;
} }
if (PageWriteback(page)) { if (PageWriteback(page)) {
dout("%p under writeback\n", page); if (wbc->sync_mode == WB_SYNC_NONE) {
unlock_page(page); dout("%p under writeback\n", page);
break; unlock_page(page);
continue;
}
dout("waiting on writeback %p\n", page);
wait_on_page_writeback(page);
} }
/* only if matching snap context */ /* only if matching snap context */
...@@ -924,15 +922,13 @@ static int ceph_writepages_start(struct address_space *mapping, ...@@ -924,15 +922,13 @@ static int ceph_writepages_start(struct address_space *mapping,
dout("page snapc %p %lld > oldest %p %lld\n", dout("page snapc %p %lld > oldest %p %lld\n",
pgsnapc, pgsnapc->seq, snapc, snapc->seq); pgsnapc, pgsnapc->seq, snapc, snapc->seq);
unlock_page(page); unlock_page(page);
if (!locked_pages) continue;
continue; /* keep looking for snap */
break;
} }
if (!clear_page_dirty_for_io(page)) { if (!clear_page_dirty_for_io(page)) {
dout("%p !clear_page_dirty_for_io\n", page); dout("%p !clear_page_dirty_for_io\n", page);
unlock_page(page); unlock_page(page);
break; continue;
} }
/* /*
...@@ -988,8 +984,6 @@ static int ceph_writepages_start(struct address_space *mapping, ...@@ -988,8 +984,6 @@ static int ceph_writepages_start(struct address_space *mapping,
} }
/* note position of first page in pvec */ /* note position of first page in pvec */
if (first < 0)
first = i;
dout("%p will write page %p idx %lu\n", dout("%p will write page %p idx %lu\n",
inode, page, page->index); inode, page, page->index);
...@@ -1000,8 +994,10 @@ static int ceph_writepages_start(struct address_space *mapping, ...@@ -1000,8 +994,10 @@ static int ceph_writepages_start(struct address_space *mapping,
BLK_RW_ASYNC); BLK_RW_ASYNC);
} }
pages[locked_pages] = page;
locked_pages++; pages[locked_pages++] = page;
pvec.pages[i] = NULL;
len += PAGE_SIZE; len += PAGE_SIZE;
} }
...@@ -1009,23 +1005,23 @@ static int ceph_writepages_start(struct address_space *mapping, ...@@ -1009,23 +1005,23 @@ static int ceph_writepages_start(struct address_space *mapping,
if (!locked_pages) if (!locked_pages)
goto release_pvec_pages; goto release_pvec_pages;
if (i) { if (i) {
int j; unsigned j, n = 0;
BUG_ON(!locked_pages || first < 0); /* shift unused page to beginning of pvec */
for (j = 0; j < pvec_pages; j++) {
if (!pvec.pages[j])
continue;
if (n < j)
pvec.pages[n] = pvec.pages[j];
n++;
}
pvec.nr = n;
if (pvec_pages && i == pvec_pages && if (pvec_pages && i == pvec_pages &&
locked_pages < max_pages) { locked_pages < max_pages) {
dout("reached end pvec, trying for more\n"); dout("reached end pvec, trying for more\n");
pagevec_reinit(&pvec); pagevec_release(&pvec);
goto get_more_pages; goto get_more_pages;
} }
/* shift unused pages over in the pvec... we
* will need to release them below. */
for (j = i; j < pvec_pages; j++) {
dout(" pvec leftover page %p\n", pvec.pages[j]);
pvec.pages[j-i+first] = pvec.pages[j];
}
pvec.nr -= i-first;
} }
new_request: new_request:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册