Linux 6.9-rc1
[linux-2.6-microblaze.git] / block / genhd.c
index d36fabf..bb29a68 100644 (file)
@@ -25,8 +25,9 @@
 #include <linux/pm_runtime.h>
 #include <linux/badblocks.h>
 #include <linux/part_stat.h>
-#include "blk-throttle.h"
+#include <linux/blktrace_api.h>
 
+#include "blk-throttle.h"
 #include "blk.h"
 #include "blk-mq-sched.h"
 #include "blk-rq-qos.h"
@@ -57,12 +58,7 @@ static DEFINE_IDA(ext_devt_ida);
 
 void set_capacity(struct gendisk *disk, sector_t sectors)
 {
-       struct block_device *bdev = disk->part0;
-
-       spin_lock(&bdev->bd_size_lock);
-       i_size_write(bdev->bd_inode, (loff_t)sectors << SECTOR_SHIFT);
-       bdev->bd_nr_sectors = sectors;
-       spin_unlock(&bdev->bd_size_lock);
+       bdev_set_nr_sectors(disk->part0, sectors);
 }
 EXPORT_SYMBOL(set_capacity);
 
@@ -258,7 +254,7 @@ int __register_blkdev(unsigned int major, const char *name,
 #ifdef CONFIG_BLOCK_LEGACY_AUTOLOAD
        p->probe = probe;
 #endif
-       strlcpy(p->name, name, sizeof(p->name));
+       strscpy(p->name, name, sizeof(p->name));
        p->next = NULL;
        index = major_to_index(major);
 
@@ -323,18 +319,6 @@ void blk_free_ext_minor(unsigned int minor)
        ida_free(&ext_devt_ida, minor);
 }
 
-static char *bdevt_str(dev_t devt, char *buf)
-{
-       if (MAJOR(devt) <= 0xff && MINOR(devt) <= 0xff) {
-               char tbuf[BDEVT_SIZE];
-               snprintf(tbuf, BDEVT_SIZE, "%02x%02x", MAJOR(devt), MINOR(devt));
-               snprintf(buf, BDEVT_SIZE, "%-9s", tbuf);
-       } else
-               snprintf(buf, BDEVT_SIZE, "%03x:%05x", MAJOR(devt), MINOR(devt));
-
-       return buf;
-}
-
 void disk_uevent(struct gendisk *disk, enum kobject_action action)
 {
        struct block_device *part;
@@ -356,9 +340,10 @@ void disk_uevent(struct gendisk *disk, enum kobject_action action)
 }
 EXPORT_SYMBOL_GPL(disk_uevent);
 
-int disk_scan_partitions(struct gendisk *disk, fmode_t mode)
+int disk_scan_partitions(struct gendisk *disk, blk_mode_t mode)
 {
-       struct block_device *bdev;
+       struct file *file;
+       int ret = 0;
 
        if (disk->flags & (GENHD_FL_NO_PART | GENHD_FL_HIDDEN))
                return -EINVAL;
@@ -367,12 +352,36 @@ int disk_scan_partitions(struct gendisk *disk, fmode_t mode)
        if (disk->open_partitions)
                return -EBUSY;
 
+       /*
+        * If the device is opened exclusively by current thread already, it's
+        * safe to scan partitons, otherwise, use bd_prepare_to_claim() to
+        * synchronize with other exclusive openers and other partition
+        * scanners.
+        */
+       if (!(mode & BLK_OPEN_EXCL)) {
+               ret = bd_prepare_to_claim(disk->part0, disk_scan_partitions,
+                                         NULL);
+               if (ret)
+                       return ret;
+       }
+
        set_bit(GD_NEED_PART_SCAN, &disk->state);
-       bdev = blkdev_get_by_dev(disk_devt(disk), mode, NULL);
-       if (IS_ERR(bdev))
-               return PTR_ERR(bdev);
-       blkdev_put(bdev, mode);
-       return 0;
+       file = bdev_file_open_by_dev(disk_devt(disk), mode & ~BLK_OPEN_EXCL,
+                                    NULL, NULL);
+       if (IS_ERR(file))
+               ret = PTR_ERR(file);
+       else
+               fput(file);
+
+       /*
+        * If blkdev_get_by_dev() failed early, GD_NEED_PART_SCAN is still set,
+        * and this will cause that re-assemble partitioned raid device will
+        * creat partition for underlying disk.
+        */
+       clear_bit(GD_NEED_PART_SCAN, &disk->state);
+       if (!(mode & BLK_OPEN_EXCL))
+               bd_abort_claiming(disk->part0, disk_scan_partitions);
+       return ret;
 }
 
 /**
@@ -403,6 +412,9 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
         */
        elevator_init_mq(disk->queue);
 
+       /* Mark bdev as having a submit_bio, if needed */
+       disk->part0->bd_has_submit_bio = disk->fops->submit_bio != NULL;
+
        /*
         * If the driver provides an explicit major number it also must provide
         * the number of minors numbers supported, and those will be used to
@@ -410,24 +422,27 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
         * Otherwise just allocate the device numbers for both the whole device
         * and all partitions from the extended dev_t space.
         */
+       ret = -EINVAL;
        if (disk->major) {
                if (WARN_ON(!disk->minors))
-                       return -EINVAL;
+                       goto out_exit_elevator;
 
                if (disk->minors > DISK_MAX_PARTS) {
                        pr_err("block: can't allocate more than %d partitions\n",
                                DISK_MAX_PARTS);
                        disk->minors = DISK_MAX_PARTS;
                }
-               if (disk->first_minor + disk->minors > MINORMASK + 1)
-                       return -EINVAL;
+               if (disk->first_minor > MINORMASK ||
+                   disk->minors > MINORMASK + 1 ||
+                   disk->first_minor + disk->minors > MINORMASK + 1)
+                       goto out_exit_elevator;
        } else {
                if (WARN_ON(disk->minors))
-                       return -EINVAL;
+                       goto out_exit_elevator;
 
                ret = blk_alloc_ext_minor();
                if (ret < 0)
-                       return ret;
+                       goto out_exit_elevator;
                disk->major = BLOCK_EXT_MAJOR;
                disk->first_minor = ret;
        }
@@ -448,12 +463,10 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
        if (ret)
                goto out_device_del;
 
-       if (!sysfs_deprecated) {
-               ret = sysfs_create_link(block_depr, &ddev->kobj,
-                                       kobject_name(&ddev->kobj));
-               if (ret)
-                       goto out_device_del;
-       }
+       ret = sysfs_create_link(block_depr, &ddev->kobj,
+                               kobject_name(&ddev->kobj));
+       if (ret)
+               goto out_device_del;
 
        /*
         * avoid probable deadlock caused by allocating memory with
@@ -462,15 +475,11 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
         */
        pm_runtime_set_memalloc_noio(ddev, true);
 
-       ret = blk_integrity_add(disk);
-       if (ret)
-               goto out_del_block_link;
-
        disk->part0->bd_holder_dir =
                kobject_create_and_add("holders", &ddev->kobj);
        if (!disk->part0->bd_holder_dir) {
                ret = -ENOMEM;
-               goto out_del_integrity;
+               goto out_del_block_link;
        }
        disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
        if (!disk->slave_dir) {
@@ -478,10 +487,6 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
                goto out_put_holder_dir;
        }
 
-       ret = bd_register_pending_holders(disk);
-       if (ret < 0)
-               goto out_put_slave_dir;
-
        ret = blk_register_queue(disk);
        if (ret)
                goto out_put_slave_dir;
@@ -497,9 +502,14 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
                if (ret)
                        goto out_unregister_bdi;
 
+               /* Make sure the first partition scan will be proceed */
+               if (get_capacity(disk) && !(disk->flags & GENHD_FL_NO_PART) &&
+                   !test_bit(GD_SUPPRESS_PART_SCAN, &disk->state))
+                       set_bit(GD_NEED_PART_SCAN, &disk->state);
+
                bdev_add(disk->part0, ddev->devt);
                if (get_capacity(disk))
-                       disk_scan_partitions(disk, FMODE_READ);
+                       disk_scan_partitions(disk, BLK_OPEN_READ);
 
                /*
                 * Announce the disk and partitions after all partitions are
@@ -507,6 +517,13 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
                 */
                dev_set_uevent_suppress(ddev, 0);
                disk_uevent(disk, KOBJ_ADD);
+       } else {
+               /*
+                * Even if the block_device for a hidden gendisk is not
+                * registered, it needs to have a valid bd_dev so that the
+                * freeing of the dynamic major works.
+                */
+               disk->part0->bd_dev = MKDEV(disk->major, disk->first_minor);
        }
 
        disk_update_readahead(disk);
@@ -519,24 +536,75 @@ out_unregister_bdi:
                bdi_unregister(disk->bdi);
 out_unregister_queue:
        blk_unregister_queue(disk);
+       rq_qos_exit(disk->queue);
 out_put_slave_dir:
        kobject_put(disk->slave_dir);
+       disk->slave_dir = NULL;
 out_put_holder_dir:
        kobject_put(disk->part0->bd_holder_dir);
-out_del_integrity:
-       blk_integrity_del(disk);
 out_del_block_link:
-       if (!sysfs_deprecated)
-               sysfs_remove_link(block_depr, dev_name(ddev));
+       sysfs_remove_link(block_depr, dev_name(ddev));
+       pm_runtime_set_memalloc_noio(ddev, false);
 out_device_del:
        device_del(ddev);
 out_free_ext_minor:
        if (disk->major == BLOCK_EXT_MAJOR)
                blk_free_ext_minor(disk->first_minor);
+out_exit_elevator:
+       if (disk->queue->elevator)
+               elevator_exit(disk->queue);
        return ret;
 }
 EXPORT_SYMBOL(device_add_disk);
 
+static void blk_report_disk_dead(struct gendisk *disk, bool surprise)
+{
+       struct block_device *bdev;
+       unsigned long idx;
+
+       /*
+        * On surprise disk removal, bdev_mark_dead() may call into file
+        * systems below. Make it clear that we're expecting to not hold
+        * disk->open_mutex.
+        */
+       lockdep_assert_not_held(&disk->open_mutex);
+
+       rcu_read_lock();
+       xa_for_each(&disk->part_tbl, idx, bdev) {
+               if (!kobject_get_unless_zero(&bdev->bd_device.kobj))
+                       continue;
+               rcu_read_unlock();
+
+               bdev_mark_dead(bdev, surprise);
+
+               put_device(&bdev->bd_device);
+               rcu_read_lock();
+       }
+       rcu_read_unlock();
+}
+
+static void __blk_mark_disk_dead(struct gendisk *disk)
+{
+       /*
+        * Fail any new I/O.
+        */
+       if (test_and_set_bit(GD_DEAD, &disk->state))
+               return;
+
+       if (test_bit(GD_OWNS_QUEUE, &disk->state))
+               blk_queue_flag_set(QUEUE_FLAG_DYING, disk->queue);
+
+       /*
+        * Stop buffered writers from dirtying pages that can't be written out.
+        */
+       set_capacity(disk, 0);
+
+       /*
+        * Prevent new I/O from crossing bio_queue_enter().
+        */
+       blk_queue_start_drain(disk->queue);
+}
+
 /**
  * blk_mark_disk_dead - mark a disk as dead
  * @disk: disk to mark as dead
@@ -546,8 +614,8 @@ EXPORT_SYMBOL(device_add_disk);
  */
 void blk_mark_disk_dead(struct gendisk *disk)
 {
-       set_bit(GD_DEAD, &disk->state);
-       blk_queue_start_drain(disk->queue);
+       __blk_mark_disk_dead(disk);
+       blk_report_disk_dead(disk, true);
 }
 EXPORT_SYMBOL_GPL(blk_mark_disk_dead);
 
@@ -573,36 +641,39 @@ EXPORT_SYMBOL_GPL(blk_mark_disk_dead);
 void del_gendisk(struct gendisk *disk)
 {
        struct request_queue *q = disk->queue;
+       struct block_device *part;
+       unsigned long idx;
 
        might_sleep();
 
        if (WARN_ON_ONCE(!disk_live(disk) && !(disk->flags & GENHD_FL_HIDDEN)))
                return;
 
-       blk_integrity_del(disk);
        disk_del_events(disk);
 
+       /*
+        * Prevent new openers by unlinked the bdev inode.
+        */
        mutex_lock(&disk->open_mutex);
-       remove_inode_hash(disk->part0->bd_inode);
-       blk_drop_partitions(disk);
+       xa_for_each(&disk->part_tbl, idx, part)
+               remove_inode_hash(part->bd_inode);
        mutex_unlock(&disk->open_mutex);
 
-       fsync_bdev(disk->part0);
-       __invalidate_device(disk->part0, true);
-
        /*
-        * Fail any new I/O.
+        * Tell the file system to write back all dirty data and shut down if
+        * it hasn't been notified earlier.
         */
-       set_bit(GD_DEAD, &disk->state);
-       if (test_bit(GD_OWNS_QUEUE, &disk->state))
-               blk_queue_flag_set(QUEUE_FLAG_DYING, q);
-       set_capacity(disk, 0);
+       if (!test_bit(GD_DEAD, &disk->state))
+               blk_report_disk_dead(disk, false);
+       __blk_mark_disk_dead(disk);
 
        /*
-        * Prevent new I/O from crossing bio_queue_enter().
+        * Drop all partitions now that the disk is marked dead.
         */
-       blk_queue_start_drain(q);
-       blk_mq_freeze_queue_wait(q);
+       mutex_lock(&disk->open_mutex);
+       xa_for_each_start(&disk->part_tbl, idx, part, 1)
+               drop_partition(part);
+       mutex_unlock(&disk->open_mutex);
 
        if (!(disk->flags & GENHD_FL_HIDDEN)) {
                sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
@@ -618,19 +689,23 @@ void del_gendisk(struct gendisk *disk)
 
        kobject_put(disk->part0->bd_holder_dir);
        kobject_put(disk->slave_dir);
+       disk->slave_dir = NULL;
 
        part_stat_set_all(disk->part0, 0);
        disk->part0->bd_stamp = 0;
-       if (!sysfs_deprecated)
-               sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
+       sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
        pm_runtime_set_memalloc_noio(disk_to_dev(disk), false);
        device_del(disk_to_dev(disk));
 
-       blk_throtl_cancel_bios(disk->queue);
+       blk_mq_freeze_queue_wait(q);
+
+       blk_throtl_cancel_bios(disk);
 
        blk_sync_queue(q);
        blk_flush_integrity();
-       blk_mq_cancel_work_sync(q);
+
+       if (queue_is_mq(q))
+               blk_mq_cancel_work_sync(q);
 
        blk_mq_quiesce_queue(q);
        if (q->elevator) {
@@ -722,57 +797,6 @@ void blk_request_module(dev_t devt)
 }
 #endif /* CONFIG_BLOCK_LEGACY_AUTOLOAD */
 
-/*
- * print a full list of all partitions - intended for places where the root
- * filesystem can't be mounted and thus to give the victim some idea of what
- * went wrong
- */
-void __init printk_all_partitions(void)
-{
-       struct class_dev_iter iter;
-       struct device *dev;
-
-       class_dev_iter_init(&iter, &block_class, NULL, &disk_type);
-       while ((dev = class_dev_iter_next(&iter))) {
-               struct gendisk *disk = dev_to_disk(dev);
-               struct block_device *part;
-               char devt_buf[BDEVT_SIZE];
-               unsigned long idx;
-
-               /*
-                * Don't show empty devices or things that have been
-                * suppressed
-                */
-               if (get_capacity(disk) == 0 || (disk->flags & GENHD_FL_HIDDEN))
-                       continue;
-
-               /*
-                * Note, unlike /proc/partitions, I am showing the numbers in
-                * hex - the same format as the root= option takes.
-                */
-               rcu_read_lock();
-               xa_for_each(&disk->part_tbl, idx, part) {
-                       if (!bdev_nr_sectors(part))
-                               continue;
-                       printk("%s%s %10llu %pg %s",
-                              bdev_is_partition(part) ? "  " : "",
-                              bdevt_str(part->bd_dev, devt_buf),
-                              bdev_nr_sectors(part) >> 1, part,
-                              part->bd_meta_info ?
-                                       part->bd_meta_info->uuid : "");
-                       if (bdev_is_partition(part))
-                               printk("\n");
-                       else if (dev->parent && dev->parent->driver)
-                               printk(" driver: %s\n",
-                                       dev->parent->driver->name);
-                       else
-                               printk(" (driver?)\n");
-               }
-               rcu_read_unlock();
-       }
-       class_dev_iter_exit(&iter);
-}
-
 #ifdef CONFIG_PROC_FS
 /* iterator */
 static void *disk_seqf_start(struct seq_file *seqf, loff_t *pos)
@@ -863,7 +887,6 @@ static int __init genhd_device_init(void)
 {
        int error;
 
-       block_class.dev_kobj = sysfs_dev_block_kobj;
        error = class_register(&block_class);
        if (unlikely(error))
                return error;
@@ -872,8 +895,7 @@ static int __init genhd_device_init(void)
        register_blkdev(BLOCK_EXT_MAJOR, "blkext");
 
        /* create top-level block dir */
-       if (!sysfs_deprecated)
-               block_depr = kobject_create_and_add("block", NULL);
+       block_depr = kobject_create_and_add("block", NULL);
        return 0;
 }
 
@@ -995,9 +1017,8 @@ ssize_t part_inflight_show(struct device *dev, struct device_attribute *attr,
 static ssize_t disk_capability_show(struct device *dev,
                                    struct device_attribute *attr, char *buf)
 {
-       struct gendisk *disk = dev_to_disk(dev);
-
-       return sprintf(buf, "%x\n", disk->flags);
+       dev_warn_once(dev, "the capability attribute has been deprecated.\n");
+       return sprintf(buf, "0\n");
 }
 
 static ssize_t disk_alignment_offset_show(struct device *dev,
@@ -1113,6 +1134,9 @@ static const struct attribute_group *disk_attr_groups[] = {
        &disk_attr_group,
 #ifdef CONFIG_BLK_DEV_IO_TRACE
        &blk_trace_attr_group,
+#endif
+#ifdef CONFIG_BLK_DEV_INTEGRITY
+       &blk_integrity_attr_group,
 #endif
        NULL
 };
@@ -1138,6 +1162,8 @@ static void disk_release(struct device *dev)
        might_sleep();
        WARN_ON_ONCE(disk_live(disk));
 
+       blk_trace_remove(disk->queue);
+
        /*
         * To undo the all initialization from blk_mq_init_allocated_queue in
         * case of a probe failure where add_disk is never called we have to
@@ -1150,7 +1176,8 @@ static void disk_release(struct device *dev)
            !test_bit(GD_ADDED, &disk->state))
                blk_mq_exit_queue(disk->queue);
 
-       blkcg_exit_queue(disk->queue);
+       blkcg_exit_disk(disk);
+
        bioset_exit(&disk->bio_split);
 
        disk_release_events(disk);
@@ -1167,19 +1194,19 @@ static void disk_release(struct device *dev)
        iput(disk->part0->bd_inode);    /* frees the disk */
 }
 
-static int block_uevent(struct device *dev, struct kobj_uevent_env *env)
+static int block_uevent(const struct device *dev, struct kobj_uevent_env *env)
 {
-       struct gendisk *disk = dev_to_disk(dev);
+       const struct gendisk *disk = dev_to_disk(dev);
 
        return add_uevent_var(env, "DISKSEQ=%llu", disk->diskseq);
 }
 
-struct class block_class = {
+const struct class block_class = {
        .name           = "block",
        .dev_uevent     = block_uevent,
 };
 
-static char *block_devnode(struct device *dev, umode_t *mode,
+static char *block_devnode(const struct device *dev, umode_t *mode,
                           kuid_t *uid, kgid_t *gid)
 {
        struct gendisk *disk = dev_to_disk(dev);
@@ -1305,35 +1332,6 @@ dev_t part_devt(struct gendisk *disk, u8 partno)
        return devt;
 }
 
-dev_t blk_lookup_devt(const char *name, int partno)
-{
-       dev_t devt = MKDEV(0, 0);
-       struct class_dev_iter iter;
-       struct device *dev;
-
-       class_dev_iter_init(&iter, &block_class, NULL, &disk_type);
-       while ((dev = class_dev_iter_next(&iter))) {
-               struct gendisk *disk = dev_to_disk(dev);
-
-               if (strcmp(dev_name(dev), name))
-                       continue;
-
-               if (partno < disk->minors) {
-                       /* We need to return the right devno, even
-                        * if the partition doesn't exist yet.
-                        */
-                       devt = MKDEV(MAJOR(dev->devt),
-                                    MINOR(dev->devt) + partno);
-               } else {
-                       devt = part_devt(disk, partno);
-                       if (devt)
-                               break;
-               }
-       }
-       class_dev_iter_exit(&iter);
-       return devt;
-}
-
 struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
                struct lock_class_key *lkclass)
 {
@@ -1363,7 +1361,7 @@ struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
        if (xa_insert(&disk->part_tbl, 0, disk->part0, GFP_KERNEL))
                goto out_destroy_part_tbl;
 
-       if (blkcg_init_queue(q))
+       if (blkcg_init_disk(disk))
                goto out_erase_part0;
 
        rand_initialize_disk(disk);
@@ -1393,19 +1391,21 @@ out_free_disk:
        return NULL;
 }
 
-struct gendisk *__blk_alloc_disk(int node, struct lock_class_key *lkclass)
+struct gendisk *__blk_alloc_disk(struct queue_limits *lim, int node,
+               struct lock_class_key *lkclass)
 {
+       struct queue_limits default_lim = { };
        struct request_queue *q;
        struct gendisk *disk;
 
-       q = blk_alloc_queue(node, false);
-       if (!q)
-               return NULL;
+       q = blk_alloc_queue(lim ? lim : &default_lim, node);
+       if (IS_ERR(q))
+               return ERR_CAST(q);
 
        disk = __alloc_disk_node(q, node, lkclass);
        if (!disk) {
                blk_put_queue(q);
-               return NULL;
+               return ERR_PTR(-ENOMEM);
        }
        set_bit(GD_OWNS_QUEUE, &disk->state);
        return disk;