pandora: defconfig: update
[pandora-kernel.git] / block / genhd.c
index 6edf228..4c3f6db 100644 (file)
@@ -28,10 +28,10 @@ struct kobject *block_depr;
 /* for extended dynamic devt allocation, currently only one major is used */
 #define NR_EXT_DEVT            (1 << MINORBITS)
 
-/* For extended devt allocation.  ext_devt_mutex prevents look up
+/* For extended devt allocation.  ext_devt_lock prevents look up
  * results from going away underneath its user.
  */
-static DEFINE_MUTEX(ext_devt_mutex);
+static DEFINE_SPINLOCK(ext_devt_lock);
 static DEFINE_IDR(ext_devt_idr);
 
 static struct device_type disk_type;
@@ -421,13 +421,13 @@ int blk_alloc_devt(struct hd_struct *part, dev_t *devt)
        do {
                if (!idr_pre_get(&ext_devt_idr, GFP_KERNEL))
                        return -ENOMEM;
-               mutex_lock(&ext_devt_mutex);
+               spin_lock(&ext_devt_lock);
                rc = idr_get_new(&ext_devt_idr, part, &idx);
                if (!rc && idx >= NR_EXT_DEVT) {
                        idr_remove(&ext_devt_idr, idx);
                        rc = -EBUSY;
                }
-               mutex_unlock(&ext_devt_mutex);
+               spin_unlock(&ext_devt_lock);
        } while (rc == -EAGAIN);
 
        if (rc)
@@ -448,15 +448,13 @@ int blk_alloc_devt(struct hd_struct *part, dev_t *devt)
  */
 void blk_free_devt(dev_t devt)
 {
-       might_sleep();
-
        if (devt == MKDEV(0, 0))
                return;
 
        if (MAJOR(devt) == BLOCK_EXT_MAJOR) {
-               mutex_lock(&ext_devt_mutex);
+               spin_lock(&ext_devt_lock);
                idr_remove(&ext_devt_idr, blk_mangle_minor(MINOR(devt)));
-               mutex_unlock(&ext_devt_mutex);
+               spin_unlock(&ext_devt_lock);
        }
 }
 
@@ -519,7 +517,7 @@ void register_disk(struct gendisk *disk)
 
        ddev->parent = disk->driverfs_dev;
 
-       dev_set_name(ddev, disk->disk_name);
+       dev_set_name(ddev, "%s", disk->disk_name);
 
        /* delay uevents, until we scanned partition table */
        dev_set_uevent_suppress(ddev, 1);
@@ -663,7 +661,6 @@ void del_gendisk(struct gendisk *disk)
        if (!sysfs_deprecated)
                sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
        device_del(disk_to_dev(disk));
-       blk_free_devt(disk_to_dev(disk)->devt);
 }
 EXPORT_SYMBOL(del_gendisk);
 
@@ -688,13 +685,13 @@ struct gendisk *get_gendisk(dev_t devt, int *partno)
        } else {
                struct hd_struct *part;
 
-               mutex_lock(&ext_devt_mutex);
+               spin_lock(&ext_devt_lock);
                part = idr_find(&ext_devt_idr, blk_mangle_minor(MINOR(devt)));
                if (part && get_disk(part_to_disk(part))) {
                        *partno = part->partno;
                        disk = part_to_disk(part);
                }
-               mutex_unlock(&ext_devt_mutex);
+               spin_unlock(&ext_devt_lock);
        }
 
        return disk;
@@ -832,6 +829,7 @@ static void disk_seqf_stop(struct seq_file *seqf, void *v)
        if (iter) {
                class_dev_iter_exit(iter);
                kfree(iter);
+               seqf->private = NULL;
        }
 }
 
@@ -1073,9 +1071,16 @@ int disk_expand_part_tbl(struct gendisk *disk, int partno)
        struct disk_part_tbl *old_ptbl = disk->part_tbl;
        struct disk_part_tbl *new_ptbl;
        int len = old_ptbl ? old_ptbl->len : 0;
-       int target = partno + 1;
+       int i, target;
        size_t size;
-       int i;
+
+       /*
+        * check for int overflow, since we can get here from blkpg_ioctl()
+        * with a user passed 'partno'.
+        */
+       target = partno + 1;
+       if (target < 0)
+               return -EINVAL;
 
        /* disk_max_parts() is zero during initialization, ignore if so */
        if (disk_max_parts(disk) && target > disk_max_parts(disk))
@@ -1102,6 +1107,7 @@ static void disk_release(struct device *dev)
 {
        struct gendisk *disk = dev_to_disk(dev);
 
+       blk_free_devt(dev->devt);
        disk_release_events(disk);
        kfree(disk->random);
        disk_replace_part_tbl(disk, NULL);