Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial
[linux-2.6-block.git] / fs / block_dev.c
index 2eca00ec43706bb78955cd221a24593942625d57..9ccabe3bb7de1635ba3cac78751db68bb5ead93e 100644 (file)
@@ -885,6 +885,8 @@ static void bdev_evict_inode(struct inode *inode)
        spin_lock(&bdev_lock);
        list_del_init(&bdev->bd_list);
        spin_unlock(&bdev_lock);
+       /* Detach inode from wb early as bdi_put() may free bdi->wb */
+       inode_detach_wb(inode);
        if (bdev->bd_bdi != &noop_backing_dev_info) {
                bdi_put(bdev->bd_bdi);
                bdev->bd_bdi = &noop_backing_dev_info;
@@ -1451,7 +1453,6 @@ int revalidate_disk(struct gendisk *disk)
 
        if (disk->fops->revalidate_disk)
                ret = disk->fops->revalidate_disk(disk);
-       blk_integrity_revalidate(disk);
        bdev = bdget_disk(disk, 0);
        if (!bdev)
                return ret;
@@ -1556,8 +1557,6 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
                bdev->bd_disk = disk;
                bdev->bd_queue = disk->queue;
                bdev->bd_contains = bdev;
-               if (bdev->bd_bdi == &noop_backing_dev_info)
-                       bdev->bd_bdi = bdi_get(disk->queue->backing_dev_info);
 
                if (!partno) {
                        ret = -ENXIO;
@@ -1622,6 +1621,9 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
                        }
                        bd_set_size(bdev, (loff_t)bdev->bd_part->nr_sects << 9);
                }
+
+               if (bdev->bd_bdi == &noop_backing_dev_info)
+                       bdev->bd_bdi = bdi_get(disk->queue->backing_dev_info);
        } else {
                if (bdev->bd_contains == bdev) {
                        ret = 0;
@@ -1653,8 +1655,6 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
        bdev->bd_disk = NULL;
        bdev->bd_part = NULL;
        bdev->bd_queue = NULL;
-       bdi_put(bdev->bd_bdi);
-       bdev->bd_bdi = &noop_backing_dev_info;
        if (bdev != bdev->bd_contains)
                __blkdev_put(bdev->bd_contains, mode, 1);
        bdev->bd_contains = NULL;
@@ -1876,12 +1876,6 @@ static void __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
                kill_bdev(bdev);
 
                bdev_write_inode(bdev);
-               /*
-                * Detaching bdev inode from its wb in __destroy_inode()
-                * is too late: the queue which embeds its bdi (along with
-                * root wb) can be gone as soon as we put_disk() below.
-                */
-               inode_detach_wb(bdev->bd_inode);
        }
        if (bdev->bd_contains == bdev) {
                if (disk->fops->release)
@@ -2074,7 +2068,6 @@ static long blkdev_fallocate(struct file *file, int mode, loff_t start,
                             loff_t len)
 {
        struct block_device *bdev = I_BDEV(bdev_file_inode(file));
-       struct request_queue *q = bdev_get_queue(bdev);
        struct address_space *mapping;
        loff_t end = start + len - 1;
        loff_t isize;
@@ -2110,18 +2103,13 @@ static long blkdev_fallocate(struct file *file, int mode, loff_t start,
        case FALLOC_FL_ZERO_RANGE:
        case FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE:
                error = blkdev_issue_zeroout(bdev, start >> 9, len >> 9,
-                                           GFP_KERNEL, false);
+                                           GFP_KERNEL, BLKDEV_ZERO_NOUNMAP);
                break;
        case FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE:
-               /* Only punch if the device can do zeroing discard. */
-               if (!blk_queue_discard(q) || !q->limits.discard_zeroes_data)
-                       return -EOPNOTSUPP;
-               error = blkdev_issue_discard(bdev, start >> 9, len >> 9,
-                                            GFP_KERNEL, 0);
+               error = blkdev_issue_zeroout(bdev, start >> 9, len >> 9,
+                                            GFP_KERNEL, BLKDEV_ZERO_NOFALLBACK);
                break;
        case FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE | FALLOC_FL_NO_HIDE_STALE:
-               if (!blk_queue_discard(q))
-                       return -EOPNOTSUPP;
                error = blkdev_issue_discard(bdev, start >> 9, len >> 9,
                                             GFP_KERNEL, 0);
                break;