]> 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 755741c211a4a1f1f8ebc85ee51d2cdd92887bf1..d63cc5e9d3b5d93eaf03463c83a8dc6ab54b2741 100644 (file)
@@ -45,25 +45,6 @@ void ext4_exit_pageio(void)
        kmem_cache_destroy(io_end_cachep);
 }
 
-/*
- * This function is called by ext4_evict_inode() to make sure there is
- * no more pending I/O completion work left to do.
- */
-void ext4_ioend_shutdown(struct inode *inode)
-{
-       wait_queue_head_t *wq = ext4_ioend_wq(inode);
-
-       wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_ioend_count) == 0));
-       /*
-        * We need to make sure the work structure is finished being
-        * used before we let the inode get destroyed.
-        */
-       if (work_pending(&EXT4_I(inode)->i_rsv_conversion_work))
-               cancel_work_sync(&EXT4_I(inode)->i_rsv_conversion_work);
-       if (work_pending(&EXT4_I(inode)->i_unrsv_conversion_work))
-               cancel_work_sync(&EXT4_I(inode)->i_unrsv_conversion_work);
-}
-
 /*
  * Print an buffer I/O error compatible with the fs/buffer.c.  This
  * provides compatibility with dmesg scrapers that look for a specific
@@ -158,7 +139,14 @@ static void ext4_clear_io_unwritten_flag(ext4_io_end_t *io_end)
                wake_up_all(ext4_ioend_wq(inode));
 }
 
-/* check a range of space and convert unwritten extents to written. */
+/*
+ * Check a range of space and convert unwritten extents to written. Note that
+ * we are protected from truncate touching same part of extent tree by the
+ * fact that truncate code waits for all DIO to finish (thus exclusion from
+ * direct IO is achieved) and also waits for PageWriteback bits. Thus we
+ * cannot get to ext4_ext_truncate() before all IOs overlapping that range are
+ * completed (happens from ext4_free_ioend()).
+ */
 static int ext4_end_io(ext4_io_end_t *io)
 {
        struct inode *inode = io->inode;
@@ -274,22 +262,6 @@ void ext4_end_io_unrsv_work(struct work_struct *work)
        ext4_do_flush_completed_IO(&ei->vfs_inode, &ei->i_unrsv_conversion_list);
 }
 
-int ext4_flush_unwritten_io(struct inode *inode)
-{
-       int ret, err;
-
-       WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex) &&
-                    !(inode->i_state & I_FREEING));
-       ret = ext4_do_flush_completed_IO(inode,
-                                        &EXT4_I(inode)->i_rsv_conversion_list);
-       err = ext4_do_flush_completed_IO(inode,
-                                        &EXT4_I(inode)->i_unrsv_conversion_list);
-       if (!ret)
-               ret = err;
-       ext4_unwritten_wait(inode);
-       return ret;
-}
-
 ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags)
 {
        ext4_io_end_t *io = kmem_cache_zalloc(io_end_cachep, flags);
@@ -336,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;
@@ -346,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;
 
@@ -369,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)
@@ -400,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;