]> Pileus Git - ~andy/linux/blobdiff - fs/ext4/page-io.c
ext4: fix warning in ext4_evict_inode()
[~andy/linux] / fs / ext4 / page-io.c
index ce8c15a7eabcccd8cf9231723119014a24dd885a..d63cc5e9d3b5d93eaf03463c83a8dc6ab54b2741 100644 (file)
@@ -308,6 +308,7 @@ ext4_io_end_t *ext4_get_io_end(ext4_io_end_t *io_end)
        return io_end;
 }
 
+/* BIO completion function for page writeback */
 static void ext4_end_bio(struct bio *bio, int error)
 {
        ext4_io_end_t *io_end = bio->bi_private;
@@ -318,18 +319,6 @@ static void ext4_end_bio(struct bio *bio, int error)
        if (test_bit(BIO_UPTODATE, &bio->bi_flags))
                error = 0;
 
-       if (io_end->flag & EXT4_IO_END_UNWRITTEN) {
-               /*
-                * Link bio into list hanging from io_end. We have to do it
-                * atomically as bio completions can be racing against each
-                * other.
-                */
-               bio->bi_private = xchg(&io_end->bio, bio);
-       } else {
-               ext4_finish_bio(bio);
-               bio_put(bio);
-       }
-
        if (error) {
                struct inode *inode = io_end->inode;
 
@@ -341,7 +330,24 @@ static void ext4_end_bio(struct bio *bio, int error)
                             (unsigned long long)
                             bi_sector >> (inode->i_blkbits - 9));
        }
-       ext4_put_io_end_defer(io_end);
+
+       if (io_end->flag & EXT4_IO_END_UNWRITTEN) {
+               /*
+                * Link bio into list hanging from io_end. We have to do it
+                * atomically as bio completions can be racing against each
+                * other.
+                */
+               bio->bi_private = xchg(&io_end->bio, bio);
+               ext4_put_io_end_defer(io_end);
+       } else {
+               /*
+                * Drop io_end reference early. Inode can get freed once
+                * we finish the bio.
+                */
+               ext4_put_io_end_defer(io_end);
+               ext4_finish_bio(bio);
+               bio_put(bio);
+       }
 }
 
 void ext4_io_submit(struct ext4_io_submit *io)
@@ -372,6 +378,8 @@ static int io_submit_init_bio(struct ext4_io_submit *io,
        struct bio *bio;
 
        bio = bio_alloc(GFP_NOIO, min(nvecs, BIO_MAX_PAGES));
+       if (!bio)
+               return -ENOMEM;
        bio->bi_sector = bh->b_blocknr * (bh->b_size >> 9);
        bio->bi_bdev = bh->b_bdev;
        bio->bi_end_io = ext4_end_bio;