Commit 0e64a39d authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] Fix the __block_write_full_page() error path.

Fix the ENOSPC recovery code in __block_write_full_page()

- Don't write out clean buffers.

- Set PG_writeback before submitting the IO.  Otherwise the completion
  handler will go BUG when it sees a non-PageWriteback page.  If the IO
  is very fast, or synchronous.
parent d98b1feb
......@@ -1784,6 +1784,7 @@ static int __block_write_full_page(struct inode *inode,
if (err == 0)
return ret;
return err;
recover:
/*
* ENOSPC, or some other error. We may already have added some
......@@ -1795,7 +1796,8 @@ static int __block_write_full_page(struct inode *inode,
bh = head;
/* Recovery: lock and submit the mapped buffers */
do {
if (buffer_mapped(bh)) {
get_bh(bh);
if (buffer_mapped(bh) && buffer_dirty(bh)) {
lock_buffer(bh);
mark_buffer_async_write(bh);
} else {
......@@ -1805,21 +1807,21 @@ static int __block_write_full_page(struct inode *inode,
*/
clear_buffer_dirty(bh);
}
bh = bh->b_this_page;
} while (bh != head);
} while ((bh = bh->b_this_page) != head);
SetPageError(page);
BUG_ON(PageWriteback(page));
SetPageWriteback(page);
unlock_page(page);
do {
struct buffer_head *next = bh->b_this_page;
if (buffer_async_write(bh)) {
set_buffer_uptodate(bh);
clear_buffer_dirty(bh);
submit_bh(WRITE, bh);
nr_underway++;
}
put_bh(bh);
bh = next;
} while (bh != head);
BUG_ON(PageWriteback(page));
SetPageWriteback(page);
unlock_page(page);
goto done;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment