drm: Reject page_flip for !DRIVER_MODESET
[pandora-kernel.git] / drivers / block / loop.c
index 68b205a..d659135 100644 (file)
@@ -422,7 +422,7 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
 
                /*
                 * We use punch hole to reclaim the free space used by the
-                * image a.k.a. discard. However we do support discard if
+                * image a.k.a. discard. However we do not support discard if
                 * encryption is enabled, because it may give an attacker
                 * useful information.
                 */
@@ -797,7 +797,7 @@ static void loop_config_discard(struct loop_device *lo)
        }
 
        q->limits.discard_granularity = inode->i_sb->s_blocksize;
-       q->limits.discard_alignment = inode->i_sb->s_blocksize;
+       q->limits.discard_alignment = 0;
        q->limits.max_discard_sectors = UINT_MAX >> 9;
        q->limits.discard_zeroes_data = 1;
        queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
@@ -907,6 +907,11 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
                lo->lo_flags |= LO_FLAGS_PARTSCAN;
        if (lo->lo_flags & LO_FLAGS_PARTSCAN)
                ioctl_by_bdev(bdev, BLKRRPART, 0);
+
+       /* Grab the block_device to prevent its destruction after we
+        * put /dev/loopXX inode. Later in loop_clr_fd() we bdput(bdev).
+        */
+       bdgrab(bdev);
        return 0;
 
 out_clr:
@@ -1003,8 +1008,10 @@ static int loop_clr_fd(struct loop_device *lo)
        memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
        memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
        memset(lo->lo_file_name, 0, LO_NAME_SIZE);
-       if (bdev)
+       if (bdev) {
+               bdput(bdev);
                invalidate_bdev(bdev);
+       }
        set_capacity(lo->lo_disk, 0);
        loop_sysfs_exit(lo);
        if (bdev) {
@@ -1262,11 +1269,9 @@ static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev)
        /* the width of sector_t may be narrow for bit-shift */
        sz = sec;
        sz <<= 9;
-       mutex_lock(&bdev->bd_mutex);
        bd_set_size(bdev, sz);
        /* let user-space know about the new size */
        kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE);
-       mutex_unlock(&bdev->bd_mutex);
 
  out:
        return err;
@@ -1630,7 +1635,7 @@ static int loop_add(struct loop_device **l, int i)
 
        lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
        if (!lo->lo_queue)
-               goto out_free_dev;
+               goto out_free_idr;
 
        disk = lo->lo_disk = alloc_disk(1 << part_shift);
        if (!disk)
@@ -1674,6 +1679,8 @@ static int loop_add(struct loop_device **l, int i)
 
 out_free_queue:
        blk_cleanup_queue(lo->lo_queue);
+out_free_idr:
+       idr_remove(&loop_index_idr, i);
 out_free_dev:
        kfree(lo);
 out:
@@ -1737,7 +1744,7 @@ static struct kobject *loop_probe(dev_t dev, int *part, void *data)
        if (err < 0)
                err = loop_add(&lo, MINOR(dev) >> part_shift);
        if (err < 0)
-               kobj = ERR_PTR(err);
+               kobj = NULL;
        else
                kobj = get_disk(lo->lo_disk);
        mutex_unlock(&loop_index_mutex);
@@ -1836,11 +1843,15 @@ static int __init loop_init(void)
                max_part = (1UL << part_shift) - 1;
        }
 
-       if ((1UL << part_shift) > DISK_MAX_PARTS)
-               return -EINVAL;
+       if ((1UL << part_shift) > DISK_MAX_PARTS) {
+               err = -EINVAL;
+               goto misc_out;
+       }
 
-       if (max_loop > 1UL << (MINORBITS - part_shift))
-               return -EINVAL;
+       if (max_loop > 1UL << (MINORBITS - part_shift)) {
+               err = -EINVAL;
+               goto misc_out;
+       }
 
        /*
         * If max_loop is specified, create that many devices upfront.
@@ -1858,8 +1869,10 @@ static int __init loop_init(void)
                range = 1UL << MINORBITS;
        }
 
-       if (register_blkdev(LOOP_MAJOR, "loop"))
-               return -EIO;
+       if (register_blkdev(LOOP_MAJOR, "loop")) {
+               err = -EIO;
+               goto misc_out;
+       }
 
        blk_register_region(MKDEV(LOOP_MAJOR, 0), range,
                                  THIS_MODULE, loop_probe, NULL, NULL);
@@ -1872,6 +1885,10 @@ static int __init loop_init(void)
 
        printk(KERN_INFO "loop: module loaded\n");
        return 0;
+
+misc_out:
+       misc_deregister(&loop_misc);
+       return err;
 }
 
 static int loop_exit_cb(int id, void *ptr, void *data)