Merge tag 'defconfig-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[linux-2.6-microblaze.git] / block / partitions / core.c
index 4230d4f..58c4c36 100644 (file)
@@ -135,8 +135,8 @@ static struct parsed_partitions *check_partition(struct gendisk *hd)
        }
        state->pp_buf[0] = '\0';
 
-       state->bdev = hd->part0;
-       disk_name(hd, 0, state->name);
+       state->disk = hd;
+       snprintf(state->name, BDEVNAME_SIZE, "%s", hd->disk_name);
        snprintf(state->pp_buf, PAGE_SIZE, " %s:", state->name);
        if (isdigit(state->name[strlen(state->name)-1]))
                sprintf(state->name, "p");
@@ -259,9 +259,8 @@ static const struct attribute_group *part_attr_groups[] = {
 
 static void part_release(struct device *dev)
 {
-       if (MAJOR(dev->devt) == BLOCK_EXT_MAJOR)
-               blk_free_ext_minor(MINOR(dev->devt));
-       bdput(dev_to_bdev(dev));
+       put_disk(dev_to_bdev(dev)->bd_disk);
+       iput(dev_to_bdev(dev)->bd_inode);
 }
 
 static int part_uevent(struct device *dev, struct kobj_uevent_env *env)
@@ -281,12 +280,10 @@ struct device_type part_type = {
        .uevent         = part_uevent,
 };
 
-/*
- * Must be called either with open_mutex held, before a disk can be opened or
- * after all disk users are gone.
- */
 static void delete_partition(struct block_device *part)
 {
+       lockdep_assert_held(&part->bd_disk->open_mutex);
+
        fsync_bdev(part);
        __invalidate_device(part, true);
 
@@ -351,20 +348,17 @@ static struct block_device *add_partition(struct gendisk *disk, int partno,
        if (xa_load(&disk->part_tbl, partno))
                return ERR_PTR(-EBUSY);
 
+       /* ensure we always have a reference to the whole disk */
+       get_device(disk_to_dev(disk));
+
+       err = -ENOMEM;
        bdev = bdev_alloc(disk, partno);
        if (!bdev)
-               return ERR_PTR(-ENOMEM);
+               goto out_put_disk;
 
        bdev->bd_start_sect = start;
        bdev_set_nr_sectors(bdev, len);
 
-       if (info) {
-               err = -ENOMEM;
-               bdev->bd_meta_info = kmemdup(info, sizeof(*info), GFP_KERNEL);
-               if (!bdev->bd_meta_info)
-                       goto out_bdput;
-       }
-
        pdev = &bdev->bd_device;
        dname = dev_name(ddev);
        if (isdigit(dname[strlen(dname) - 1]))
@@ -388,6 +382,13 @@ static struct block_device *add_partition(struct gendisk *disk, int partno,
        }
        pdev->devt = devt;
 
+       if (info) {
+               err = -ENOMEM;
+               bdev->bd_meta_info = kmemdup(info, sizeof(*info), GFP_KERNEL);
+               if (!bdev->bd_meta_info)
+                       goto out_put;
+       }
+
        /* delay uevent until 'holders' subdir is created */
        dev_set_uevent_suppress(pdev, 1);
        err = device_add(pdev);
@@ -417,14 +418,13 @@ static struct block_device *add_partition(struct gendisk *disk, int partno,
                kobject_uevent(&pdev->kobj, KOBJ_ADD);
        return bdev;
 
-out_bdput:
-       bdput(bdev);
-       return ERR_PTR(err);
 out_del:
        kobject_put(bdev->bd_holder_dir);
        device_del(pdev);
 out_put:
        put_device(pdev);
+out_put_disk:
+       put_disk(disk);
        return ERR_PTR(err);
 }
 
@@ -449,15 +449,14 @@ static bool partition_overlaps(struct gendisk *disk, sector_t start,
        return overlap;
 }
 
-int bdev_add_partition(struct block_device *bdev, int partno,
-               sector_t start, sector_t length)
+int bdev_add_partition(struct gendisk *disk, int partno, sector_t start,
+               sector_t length)
 {
        struct block_device *part;
-       struct gendisk *disk = bdev->bd_disk;
        int ret;
 
        mutex_lock(&disk->open_mutex);
-       if (!(disk->flags & GENHD_FL_UP)) {
+       if (!disk_live(disk)) {
                ret = -ENXIO;
                goto out;
        }
@@ -475,13 +474,13 @@ out:
        return ret;
 }
 
-int bdev_del_partition(struct block_device *bdev, int partno)
+int bdev_del_partition(struct gendisk *disk, int partno)
 {
        struct block_device *part = NULL;
        int ret = -ENXIO;
 
-       mutex_lock(&bdev->bd_disk->open_mutex);
-       part = xa_load(&bdev->bd_disk->part_tbl, partno);
+       mutex_lock(&disk->open_mutex);
+       part = xa_load(&disk->part_tbl, partno);
        if (!part)
                goto out_unlock;
 
@@ -492,18 +491,18 @@ int bdev_del_partition(struct block_device *bdev, int partno)
        delete_partition(part);
        ret = 0;
 out_unlock:
-       mutex_unlock(&bdev->bd_disk->open_mutex);
+       mutex_unlock(&disk->open_mutex);
        return ret;
 }
 
-int bdev_resize_partition(struct block_device *bdev, int partno,
-               sector_t start, sector_t length)
+int bdev_resize_partition(struct gendisk *disk, int partno, sector_t start,
+               sector_t length)
 {
        struct block_device *part = NULL;
        int ret = -ENXIO;
 
-       mutex_lock(&bdev->bd_disk->open_mutex);
-       part = xa_load(&bdev->bd_disk->part_tbl, partno);
+       mutex_lock(&disk->open_mutex);
+       part = xa_load(&disk->part_tbl, partno);
        if (!part)
                goto out_unlock;
 
@@ -512,14 +511,14 @@ int bdev_resize_partition(struct block_device *bdev, int partno,
                goto out_unlock;
 
        ret = -EBUSY;
-       if (partition_overlaps(bdev->bd_disk, start, length, partno))
+       if (partition_overlaps(disk, start, length, partno))
                goto out_unlock;
 
        bdev_set_nr_sectors(part, length);
 
        ret = 0;
 out_unlock:
-       mutex_unlock(&bdev->bd_disk->open_mutex);
+       mutex_unlock(&disk->open_mutex);
        return ret;
 }
 
@@ -667,7 +666,7 @@ int bdev_disk_changed(struct gendisk *disk, bool invalidate)
 
        lockdep_assert_held(&disk->open_mutex);
 
-       if (!(disk->flags & GENHD_FL_UP))
+       if (!disk_live(disk))
                return -ENXIO;
 
 rescan:
@@ -715,10 +714,10 @@ EXPORT_SYMBOL_GPL(bdev_disk_changed);
 
 void *read_part_sector(struct parsed_partitions *state, sector_t n, Sector *p)
 {
-       struct address_space *mapping = state->bdev->bd_inode->i_mapping;
+       struct address_space *mapping = state->disk->part0->bd_inode->i_mapping;
        struct page *page;
 
-       if (n >= get_capacity(state->bdev->bd_disk)) {
+       if (n >= get_capacity(state->disk)) {
                state->access_beyond_eod = true;
                return NULL;
        }