提交 f91e0d0c 编写于 作者: Q Qu Wenruo 提交者: David Sterba

btrfs: factor out btree page submission code to a helper

In btree_write_cache_pages() we have a btree page submission routine
buried deeply in a nested loop.

This patch will extract that part of code into a helper function,
submit_eb_page(), to do the same work.

Since submit_eb_page() now can return >0 for successful extent
buffer submission, remove the "ASSERT(ret <= 0);" line.
Reviewed-by: NJosef Bacik <josef@toxicpanda.com>
Signed-off-by: NQu Wenruo <wqu@suse.com>
Reviewed-by: NDavid Sterba <dsterba@suse.com>
Signed-off-by: NDavid Sterba <dsterba@suse.com>
上级 f44cf410
...@@ -3987,10 +3987,81 @@ static noinline_for_stack int write_one_eb(struct extent_buffer *eb, ...@@ -3987,10 +3987,81 @@ static noinline_for_stack int write_one_eb(struct extent_buffer *eb,
return ret; return ret;
} }
/*
* Submit all page(s) of one extent buffer.
*
* @page: the page of one extent buffer
* @eb_context: to determine if we need to submit this page, if current page
* belongs to this eb, we don't need to submit
*
* The caller should pass each page in their bytenr order, and here we use
* @eb_context to determine if we have submitted pages of one extent buffer.
*
* If we have, we just skip until we hit a new page that doesn't belong to
* current @eb_context.
*
* If not, we submit all the page(s) of the extent buffer.
*
* Return >0 if we have submitted the extent buffer successfully.
* Return 0 if we don't need to submit the page, as it's already submitted by
* previous call.
* Return <0 for fatal error.
*/
static int submit_eb_page(struct page *page, struct writeback_control *wbc,
struct extent_page_data *epd,
struct extent_buffer **eb_context)
{
struct address_space *mapping = page->mapping;
struct extent_buffer *eb;
int ret;
if (!PagePrivate(page))
return 0;
spin_lock(&mapping->private_lock);
if (!PagePrivate(page)) {
spin_unlock(&mapping->private_lock);
return 0;
}
eb = (struct extent_buffer *)page->private;
/*
* Shouldn't happen and normally this would be a BUG_ON but no point
* crashing the machine for something we can survive anyway.
*/
if (WARN_ON(!eb)) {
spin_unlock(&mapping->private_lock);
return 0;
}
if (eb == *eb_context) {
spin_unlock(&mapping->private_lock);
return 0;
}
ret = atomic_inc_not_zero(&eb->refs);
spin_unlock(&mapping->private_lock);
if (!ret)
return 0;
*eb_context = eb;
ret = lock_extent_buffer_for_io(eb, epd);
if (ret <= 0) {
free_extent_buffer(eb);
return ret;
}
ret = write_one_eb(eb, wbc, epd);
free_extent_buffer(eb);
if (ret < 0)
return ret;
return 1;
}
int btree_write_cache_pages(struct address_space *mapping, int btree_write_cache_pages(struct address_space *mapping,
struct writeback_control *wbc) struct writeback_control *wbc)
{ {
struct extent_buffer *eb, *prev_eb = NULL; struct extent_buffer *eb_context = NULL;
struct extent_page_data epd = { struct extent_page_data epd = {
.bio = NULL, .bio = NULL,
.extent_locked = 0, .extent_locked = 0,
...@@ -4036,55 +4107,13 @@ int btree_write_cache_pages(struct address_space *mapping, ...@@ -4036,55 +4107,13 @@ int btree_write_cache_pages(struct address_space *mapping,
for (i = 0; i < nr_pages; i++) { for (i = 0; i < nr_pages; i++) {
struct page *page = pvec.pages[i]; struct page *page = pvec.pages[i];
if (!PagePrivate(page)) ret = submit_eb_page(page, wbc, &epd, &eb_context);
continue; if (ret == 0)
spin_lock(&mapping->private_lock);
if (!PagePrivate(page)) {
spin_unlock(&mapping->private_lock);
continue;
}
eb = (struct extent_buffer *)page->private;
/*
* Shouldn't happen and normally this would be a BUG_ON
* but no sense in crashing the users box for something
* we can survive anyway.
*/
if (WARN_ON(!eb)) {
spin_unlock(&mapping->private_lock);
continue;
}
if (eb == prev_eb) {
spin_unlock(&mapping->private_lock);
continue; continue;
} if (ret < 0) {
ret = atomic_inc_not_zero(&eb->refs);
spin_unlock(&mapping->private_lock);
if (!ret)
continue;
prev_eb = eb;
ret = lock_extent_buffer_for_io(eb, &epd);
if (!ret) {
free_extent_buffer(eb);
continue;
} else if (ret < 0) {
done = 1;
free_extent_buffer(eb);
break;
}
ret = write_one_eb(eb, wbc, &epd);
if (ret) {
done = 1; done = 1;
free_extent_buffer(eb);
break; break;
} }
free_extent_buffer(eb);
/* /*
* the filesystem may choose to bump up nr_to_write. * the filesystem may choose to bump up nr_to_write.
...@@ -4105,7 +4134,6 @@ int btree_write_cache_pages(struct address_space *mapping, ...@@ -4105,7 +4134,6 @@ int btree_write_cache_pages(struct address_space *mapping,
index = 0; index = 0;
goto retry; goto retry;
} }
ASSERT(ret <= 0);
if (ret < 0) { if (ret < 0) {
end_write_bio(&epd, ret); end_write_bio(&epd, ret);
return ret; return ret;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册