Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso...
[muen/linux.git] / fs / buffer.c
index a3399aa6a2bd57e8bc69e8b2c09820f927c748fe..233e2983c5db6d27b210cda0c5760c429948e456 100644 (file)
@@ -49,7 +49,7 @@
 
 static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
 static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,
-                        struct writeback_control *wbc);
+                        enum rw_hint hint, struct writeback_control *wbc);
 
 #define BH_ENTRY(list) list_entry((list), struct buffer_head, b_assoc_buffers)
 
@@ -178,7 +178,7 @@ void end_buffer_write_sync(struct buffer_head *bh, int uptodate)
                set_buffer_uptodate(bh);
        } else {
                buffer_io_error(bh, ", lost sync page write");
-               set_buffer_write_io_error(bh);
+               mark_buffer_write_io_error(bh);
                clear_buffer_uptodate(bh);
        }
        unlock_buffer(bh);
@@ -352,8 +352,7 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate)
                set_buffer_uptodate(bh);
        } else {
                buffer_io_error(bh, ", lost async page write");
-               mapping_set_error(page->mapping, -EIO);
-               set_buffer_write_io_error(bh);
+               mark_buffer_write_io_error(bh);
                clear_buffer_uptodate(bh);
                SetPageError(page);
        }
@@ -481,8 +480,6 @@ static void __remove_assoc_queue(struct buffer_head *bh)
 {
        list_del_init(&bh->b_assoc_buffers);
        WARN_ON(!bh->b_assoc_map);
-       if (buffer_write_io_error(bh))
-               set_bit(AS_EIO, &bh->b_assoc_map->flags);
        bh->b_assoc_map = NULL;
 }
 
@@ -1181,6 +1178,17 @@ void mark_buffer_dirty(struct buffer_head *bh)
 }
 EXPORT_SYMBOL(mark_buffer_dirty);
 
+void mark_buffer_write_io_error(struct buffer_head *bh)
+{
+       set_buffer_write_io_error(bh);
+       /* FIXME: do we need to set this in both places? */
+       if (bh->b_page && bh->b_page->mapping)
+               mapping_set_error(bh->b_page->mapping, -EIO);
+       if (bh->b_assoc_map)
+               mapping_set_error(bh->b_assoc_map, -EIO);
+}
+EXPORT_SYMBOL(mark_buffer_write_io_error);
+
 /*
  * Decrement a buffer_head's reference count.  If all buffers against a page
  * have zero reference count, are clean and unlocked, and if the page is clean
@@ -1829,7 +1837,8 @@ int __block_write_full_page(struct inode *inode, struct page *page,
        do {
                struct buffer_head *next = bh->b_this_page;
                if (buffer_async_write(bh)) {
-                       submit_bh_wbc(REQ_OP_WRITE, write_flags, bh, wbc);
+                       submit_bh_wbc(REQ_OP_WRITE, write_flags, bh,
+                                       inode->i_write_hint, wbc);
                        nr_underway++;
                }
                bh = next;
@@ -1883,7 +1892,8 @@ recover:
                struct buffer_head *next = bh->b_this_page;
                if (buffer_async_write(bh)) {
                        clear_buffer_dirty(bh);
-                       submit_bh_wbc(REQ_OP_WRITE, write_flags, bh, wbc);
+                       submit_bh_wbc(REQ_OP_WRITE, write_flags, bh,
+                                       inode->i_write_hint, wbc);
                        nr_underway++;
                }
                bh = next;
@@ -3038,7 +3048,7 @@ static void end_bio_bh_io_sync(struct bio *bio)
        if (unlikely(bio_flagged(bio, BIO_QUIET)))
                set_bit(BH_Quiet, &bh->b_state);
 
-       bh->b_end_io(bh, !bio->bi_error);
+       bh->b_end_io(bh, !bio->bi_status);
        bio_put(bio);
 }
 
@@ -3091,7 +3101,7 @@ void guard_bio_eod(int op, struct bio *bio)
 }
 
 static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,
-                        struct writeback_control *wbc)
+                        enum rw_hint write_hint, struct writeback_control *wbc)
 {
        struct bio *bio;
 
@@ -3120,6 +3130,7 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,
 
        bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9);
        bio->bi_bdev = bh->b_bdev;
+       bio->bi_write_hint = write_hint;
 
        bio_add_page(bio, bh->b_page, bh->b_size, bh_offset(bh));
        BUG_ON(bio->bi_iter.bi_size != bh->b_size);
@@ -3142,7 +3153,7 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,
 
 int submit_bh(int op, int op_flags, struct buffer_head *bh)
 {
-       return submit_bh_wbc(op, op_flags, bh, NULL);
+       return submit_bh_wbc(op, op_flags, bh, 0, NULL);
 }
 EXPORT_SYMBOL(submit_bh);
 
@@ -3279,8 +3290,6 @@ drop_buffers(struct page *page, struct buffer_head **buffers_to_free)
 
        bh = head;
        do {
-               if (buffer_write_io_error(bh) && page->mapping)
-                       mapping_set_error(page->mapping, -EIO);
                if (buffer_busy(bh))
                        goto failed;
                bh = bh->b_this_page;