aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/page-io.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/page-io.c')
-rw-r--r--fs/ext4/page-io.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index 48786cdb5e6c..6625d210fb45 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -25,6 +25,7 @@
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/mm.h> 27#include <linux/mm.h>
28#include <linux/ratelimit.h>
28 29
29#include "ext4_jbd2.h" 30#include "ext4_jbd2.h"
30#include "xattr.h" 31#include "xattr.h"
@@ -55,7 +56,7 @@ void ext4_exit_pageio(void)
55static void buffer_io_error(struct buffer_head *bh) 56static void buffer_io_error(struct buffer_head *bh)
56{ 57{
57 char b[BDEVNAME_SIZE]; 58 char b[BDEVNAME_SIZE];
58 printk(KERN_ERR "Buffer I/O error on device %s, logical block %llu\n", 59 printk_ratelimited(KERN_ERR "Buffer I/O error on device %s, logical block %llu\n",
59 bdevname(bh->b_bdev, b), 60 bdevname(bh->b_bdev, b),
60 (unsigned long long)bh->b_blocknr); 61 (unsigned long long)bh->b_blocknr);
61} 62}
@@ -308,6 +309,7 @@ ext4_io_end_t *ext4_get_io_end(ext4_io_end_t *io_end)
308 return io_end; 309 return io_end;
309} 310}
310 311
312/* BIO completion function for page writeback */
311static void ext4_end_bio(struct bio *bio, int error) 313static void ext4_end_bio(struct bio *bio, int error)
312{ 314{
313 ext4_io_end_t *io_end = bio->bi_private; 315 ext4_io_end_t *io_end = bio->bi_private;
@@ -318,18 +320,6 @@ static void ext4_end_bio(struct bio *bio, int error)
318 if (test_bit(BIO_UPTODATE, &bio->bi_flags)) 320 if (test_bit(BIO_UPTODATE, &bio->bi_flags))
319 error = 0; 321 error = 0;
320 322
321 if (io_end->flag & EXT4_IO_END_UNWRITTEN) {
322 /*
323 * Link bio into list hanging from io_end. We have to do it
324 * atomically as bio completions can be racing against each
325 * other.
326 */
327 bio->bi_private = xchg(&io_end->bio, bio);
328 } else {
329 ext4_finish_bio(bio);
330 bio_put(bio);
331 }
332
333 if (error) { 323 if (error) {
334 struct inode *inode = io_end->inode; 324 struct inode *inode = io_end->inode;
335 325
@@ -341,7 +331,24 @@ static void ext4_end_bio(struct bio *bio, int error)
341 (unsigned long long) 331 (unsigned long long)
342 bi_sector >> (inode->i_blkbits - 9)); 332 bi_sector >> (inode->i_blkbits - 9));
343 } 333 }
344 ext4_put_io_end_defer(io_end); 334
335 if (io_end->flag & EXT4_IO_END_UNWRITTEN) {
336 /*
337 * Link bio into list hanging from io_end. We have to do it
338 * atomically as bio completions can be racing against each
339 * other.
340 */
341 bio->bi_private = xchg(&io_end->bio, bio);
342 ext4_put_io_end_defer(io_end);
343 } else {
344 /*
345 * Drop io_end reference early. Inode can get freed once
346 * we finish the bio.
347 */
348 ext4_put_io_end_defer(io_end);
349 ext4_finish_bio(bio);
350 bio_put(bio);
351 }
345} 352}
346 353
347void ext4_io_submit(struct ext4_io_submit *io) 354void ext4_io_submit(struct ext4_io_submit *io)