aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r--fs/btrfs/extent_io.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 1ff438fd5bc2..eeb75281894e 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -3628,6 +3628,13 @@ void wait_on_extent_buffer_writeback(struct extent_buffer *eb)
3628 TASK_UNINTERRUPTIBLE); 3628 TASK_UNINTERRUPTIBLE);
3629} 3629}
3630 3630
3631static void end_extent_buffer_writeback(struct extent_buffer *eb)
3632{
3633 clear_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags);
3634 smp_mb__after_atomic();
3635 wake_up_bit(&eb->bflags, EXTENT_BUFFER_WRITEBACK);
3636}
3637
3631/* 3638/*
3632 * Lock eb pages and flush the bio if we can't the locks 3639 * Lock eb pages and flush the bio if we can't the locks
3633 * 3640 *
@@ -3699,8 +3706,11 @@ static noinline_for_stack int lock_extent_buffer_for_io(struct extent_buffer *eb
3699 3706
3700 if (!trylock_page(p)) { 3707 if (!trylock_page(p)) {
3701 if (!flush) { 3708 if (!flush) {
3702 ret = flush_write_bio(epd); 3709 int err;
3703 if (ret < 0) { 3710
3711 err = flush_write_bio(epd);
3712 if (err < 0) {
3713 ret = err;
3704 failed_page_nr = i; 3714 failed_page_nr = i;
3705 goto err_unlock; 3715 goto err_unlock;
3706 } 3716 }
@@ -3715,16 +3725,23 @@ err_unlock:
3715 /* Unlock already locked pages */ 3725 /* Unlock already locked pages */
3716 for (i = 0; i < failed_page_nr; i++) 3726 for (i = 0; i < failed_page_nr; i++)
3717 unlock_page(eb->pages[i]); 3727 unlock_page(eb->pages[i]);
3728 /*
3729 * Clear EXTENT_BUFFER_WRITEBACK and wake up anyone waiting on it.
3730 * Also set back EXTENT_BUFFER_DIRTY so future attempts to this eb can
3731 * be made and undo everything done before.
3732 */
3733 btrfs_tree_lock(eb);
3734 spin_lock(&eb->refs_lock);
3735 set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags);
3736 end_extent_buffer_writeback(eb);
3737 spin_unlock(&eb->refs_lock);
3738 percpu_counter_add_batch(&fs_info->dirty_metadata_bytes, eb->len,
3739 fs_info->dirty_metadata_batch);
3740 btrfs_clear_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN);
3741 btrfs_tree_unlock(eb);
3718 return ret; 3742 return ret;
3719} 3743}
3720 3744
3721static void end_extent_buffer_writeback(struct extent_buffer *eb)
3722{
3723 clear_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags);
3724 smp_mb__after_atomic();
3725 wake_up_bit(&eb->bflags, EXTENT_BUFFER_WRITEBACK);
3726}
3727
3728static void set_btree_ioerr(struct page *page) 3745static void set_btree_ioerr(struct page *page)
3729{ 3746{
3730 struct extent_buffer *eb = (struct extent_buffer *)page->private; 3747 struct extent_buffer *eb = (struct extent_buffer *)page->private;