diff options
Diffstat (limited to 'fs/buffer.c')
-rw-r--r-- | fs/buffer.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/fs/buffer.c b/fs/buffer.c index f65ef8821c73..35527dca1dbc 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -452,6 +452,7 @@ static void end_buffer_async_write(struct buffer_head *bh, int uptodate) | |||
452 | bdevname(bh->b_bdev, b)); | 452 | bdevname(bh->b_bdev, b)); |
453 | } | 453 | } |
454 | set_bit(AS_EIO, &page->mapping->flags); | 454 | set_bit(AS_EIO, &page->mapping->flags); |
455 | set_buffer_write_io_error(bh); | ||
455 | clear_buffer_uptodate(bh); | 456 | clear_buffer_uptodate(bh); |
456 | SetPageError(page); | 457 | SetPageError(page); |
457 | } | 458 | } |
@@ -571,6 +572,10 @@ EXPORT_SYMBOL(mark_buffer_async_write); | |||
571 | static inline void __remove_assoc_queue(struct buffer_head *bh) | 572 | static inline void __remove_assoc_queue(struct buffer_head *bh) |
572 | { | 573 | { |
573 | list_del_init(&bh->b_assoc_buffers); | 574 | list_del_init(&bh->b_assoc_buffers); |
575 | WARN_ON(!bh->b_assoc_map); | ||
576 | if (buffer_write_io_error(bh)) | ||
577 | set_bit(AS_EIO, &bh->b_assoc_map->flags); | ||
578 | bh->b_assoc_map = NULL; | ||
574 | } | 579 | } |
575 | 580 | ||
576 | int inode_has_buffers(struct inode *inode) | 581 | int inode_has_buffers(struct inode *inode) |
@@ -669,6 +674,7 @@ void mark_buffer_dirty_inode(struct buffer_head *bh, struct inode *inode) | |||
669 | spin_lock(&buffer_mapping->private_lock); | 674 | spin_lock(&buffer_mapping->private_lock); |
670 | list_move_tail(&bh->b_assoc_buffers, | 675 | list_move_tail(&bh->b_assoc_buffers, |
671 | &mapping->private_list); | 676 | &mapping->private_list); |
677 | bh->b_assoc_map = mapping; | ||
672 | spin_unlock(&buffer_mapping->private_lock); | 678 | spin_unlock(&buffer_mapping->private_lock); |
673 | } | 679 | } |
674 | } | 680 | } |
@@ -765,7 +771,7 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list) | |||
765 | spin_lock(lock); | 771 | spin_lock(lock); |
766 | while (!list_empty(list)) { | 772 | while (!list_empty(list)) { |
767 | bh = BH_ENTRY(list->next); | 773 | bh = BH_ENTRY(list->next); |
768 | list_del_init(&bh->b_assoc_buffers); | 774 | __remove_assoc_queue(bh); |
769 | if (buffer_dirty(bh) || buffer_locked(bh)) { | 775 | if (buffer_dirty(bh) || buffer_locked(bh)) { |
770 | list_add(&bh->b_assoc_buffers, &tmp); | 776 | list_add(&bh->b_assoc_buffers, &tmp); |
771 | if (buffer_dirty(bh)) { | 777 | if (buffer_dirty(bh)) { |
@@ -786,7 +792,7 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list) | |||
786 | 792 | ||
787 | while (!list_empty(&tmp)) { | 793 | while (!list_empty(&tmp)) { |
788 | bh = BH_ENTRY(tmp.prev); | 794 | bh = BH_ENTRY(tmp.prev); |
789 | __remove_assoc_queue(bh); | 795 | list_del_init(&bh->b_assoc_buffers); |
790 | get_bh(bh); | 796 | get_bh(bh); |
791 | spin_unlock(lock); | 797 | spin_unlock(lock); |
792 | wait_on_buffer(bh); | 798 | wait_on_buffer(bh); |
@@ -1167,6 +1173,7 @@ void __bforget(struct buffer_head *bh) | |||
1167 | 1173 | ||
1168 | spin_lock(&buffer_mapping->private_lock); | 1174 | spin_lock(&buffer_mapping->private_lock); |
1169 | list_del_init(&bh->b_assoc_buffers); | 1175 | list_del_init(&bh->b_assoc_buffers); |
1176 | bh->b_assoc_map = NULL; | ||
1170 | spin_unlock(&buffer_mapping->private_lock); | 1177 | spin_unlock(&buffer_mapping->private_lock); |
1171 | } | 1178 | } |
1172 | __brelse(bh); | 1179 | __brelse(bh); |