Merge branch 'stable/for-jens-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorJens Axboe <axboe@kernel.dk>
Fri, 18 May 2012 14:17:41 +0000 (16:17 +0200)
committerJens Axboe <axboe@kernel.dk>
Fri, 18 May 2012 14:17:41 +0000 (16:17 +0200)
Konrad writes:

Please git pull the following branch:

 git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen.git stable/for-jens-3.5

in your for-3.5/drivers branch. The changes in it are rather simple - cleaning
up some code and adding proper mechanism to unload without leaking memory.

drivers/block/xen-blkfront.c

index 4e86393..60eed4b 100644 (file)
@@ -526,6 +526,14 @@ static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset)
        return 0;
 }
 
+static char *encode_disk_name(char *ptr, unsigned int n)
+{
+       if (n >= 26)
+               ptr = encode_disk_name(ptr, n / 26 - 1);
+       *ptr = 'a' + n % 26;
+       return ptr + 1;
+}
+
 static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
                               struct blkfront_info *info,
                               u16 vdisk_info, u16 sector_size)
@@ -536,6 +544,7 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
        unsigned int offset;
        int minor;
        int nr_parts;
+       char *ptr;
 
        BUG_ON(info->gd != NULL);
        BUG_ON(info->rq != NULL);
@@ -560,7 +569,11 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
                                        "emulated IDE disks,\n\t choose an xvd device name"
                                        "from xvde on\n", info->vdevice);
        }
-       err = -ENODEV;
+       if (minor >> MINORBITS) {
+               pr_warn("blkfront: %#x's minor (%#x) out of range; ignoring\n",
+                       info->vdevice, minor);
+               return -ENODEV;
+       }
 
        if ((minor % nr_parts) == 0)
                nr_minors = nr_parts;
@@ -574,23 +587,14 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
        if (gd == NULL)
                goto release;
 
-       if (nr_minors > 1) {
-               if (offset < 26)
-                       sprintf(gd->disk_name, "%s%c", DEV_NAME, 'a' + offset);
-               else
-                       sprintf(gd->disk_name, "%s%c%c", DEV_NAME,
-                               'a' + ((offset / 26)-1), 'a' + (offset % 26));
-       } else {
-               if (offset < 26)
-                       sprintf(gd->disk_name, "%s%c%d", DEV_NAME,
-                               'a' + offset,
-                               minor & (nr_parts - 1));
-               else
-                       sprintf(gd->disk_name, "%s%c%c%d", DEV_NAME,
-                               'a' + ((offset / 26) - 1),
-                               'a' + (offset % 26),
-                               minor & (nr_parts - 1));
-       }
+       strcpy(gd->disk_name, DEV_NAME);
+       ptr = encode_disk_name(gd->disk_name + sizeof(DEV_NAME) - 1, offset);
+       BUG_ON(ptr >= gd->disk_name + DISK_NAME_LEN);
+       if (nr_minors > 1)
+               *ptr = 0;
+       else
+               snprintf(ptr, gd->disk_name + DISK_NAME_LEN - ptr,
+                        "%d", minor & (nr_parts - 1));
 
        gd->major = XENVBD_MAJOR;
        gd->first_minor = minor;
@@ -1496,7 +1500,9 @@ module_init(xlblk_init);
 
 static void __exit xlblk_exit(void)
 {
-       return xenbus_unregister_driver(&blkfront_driver);
+       xenbus_unregister_driver(&blkfront_driver);
+       unregister_blkdev(XENVBD_MAJOR, DEV_NAME);
+       kfree(minors);
 }
 module_exit(xlblk_exit);