Merge tag 'staging-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[sfrench/cifs-2.6.git] / fs / block_dev.c
index 78d3257435c00b76633ee6168a2586ccfa70118c..9ee3117ee0bfa471e3aeafaca312ca4f3e0e5e0d 100644 (file)
@@ -264,7 +264,8 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter,
        bio_for_each_segment_all(bvec, &bio, i, iter_all) {
                if (should_dirty && !PageCompound(bvec->bv_page))
                        set_page_dirty_lock(bvec->bv_page);
-               put_page(bvec->bv_page);
+               if (!bio_flagged(&bio, BIO_NO_PAGE_REF))
+                       put_page(bvec->bv_page);
        }
 
        if (unlikely(bio.bi_status))
@@ -307,10 +308,10 @@ static void blkdev_bio_end_io(struct bio *bio)
        struct blkdev_dio *dio = bio->bi_private;
        bool should_dirty = dio->should_dirty;
 
-       if (dio->multi_bio && !atomic_dec_and_test(&dio->ref)) {
-               if (bio->bi_status && !dio->bio.bi_status)
-                       dio->bio.bi_status = bio->bi_status;
-       } else {
+       if (bio->bi_status && !dio->bio.bi_status)
+               dio->bio.bi_status = bio->bi_status;
+
+       if (!dio->multi_bio || atomic_dec_and_test(&dio->ref)) {
                if (!dio->is_sync) {
                        struct kiocb *iocb = dio->iocb;
                        ssize_t ret;
@@ -789,17 +790,9 @@ static struct inode *bdev_alloc_inode(struct super_block *sb)
        return &ei->vfs_inode;
 }
 
-static void bdev_i_callback(struct rcu_head *head)
-{
-       struct inode *inode = container_of(head, struct inode, i_rcu);
-       struct bdev_inode *bdi = BDEV_I(inode);
-
-       kmem_cache_free(bdev_cachep, bdi);
-}
-
-static void bdev_destroy_inode(struct inode *inode)
+static void bdev_free_inode(struct inode *inode)
 {
-       call_rcu(&inode->i_rcu, bdev_i_callback);
+       kmem_cache_free(bdev_cachep, BDEV_I(inode));
 }
 
 static void init_once(void *foo)
@@ -839,7 +832,7 @@ static void bdev_evict_inode(struct inode *inode)
 static const struct super_operations bdev_sops = {
        .statfs = simple_statfs,
        .alloc_inode = bdev_alloc_inode,
-       .destroy_inode = bdev_destroy_inode,
+       .free_inode = bdev_free_inode,
        .drop_inode = generic_delete_inode,
        .evict_inode = bdev_evict_inode,
 };