diff --git a/block/blk.h b/block/blk.h index 475bbb40bb83f78e76d2e59145d716779c7b88f5..4410ae9da37836db1ff3b99a2d82f3333ae3cbdb 100644 --- a/block/blk.h +++ b/block/blk.h @@ -419,6 +419,7 @@ static inline int blkdev_zone_mgmt_ioctl(struct block_device *bdev, #endif /* CONFIG_BLK_DEV_ZONED */ struct block_device *bdev_alloc(struct gendisk *disk, u8 partno); +void bdev_inode_failed(struct block_device *bdev); void bdev_add(struct block_device *bdev, dev_t dev); int blk_alloc_ext_minor(void); diff --git a/block/genhd.c b/block/genhd.c index 039e7c17523b598a1035422bcc6b6fd673c6dc5e..cb4313a7c6185d8d68ea1d72f9d14736ae7a45be 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -383,6 +383,14 @@ int disk_scan_partitions(struct gendisk *disk, blk_mode_t mode) return ret; } +void bdev_inode_failed(struct block_device *bdev) +{ + struct inode *inode = bdev->bd_inode; + + make_bad_inode(inode); + unlock_new_inode(inode); +} + /** * device_add_disk - add disk information to kernel list * @parent: parent device for the disk @@ -452,8 +460,12 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk, ddev->parent = parent; ddev->groups = groups; dev_set_name(ddev, "%s", disk->disk_name); - if (!(disk->flags & GENHD_FL_HIDDEN)) + if (!(disk->flags & GENHD_FL_HIDDEN)) { ddev->devt = MKDEV(disk->major, disk->first_minor); + disk->part0->bd_inode->i_state |= I_NEW; + bdev_add(disk->part0, ddev->devt); + } + ret = device_add(ddev); if (ret) goto out_free_ext_minor; @@ -505,7 +517,7 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk, if (get_capacity(disk) && disk_has_partscan(disk)) set_bit(GD_NEED_PART_SCAN, &disk->state); - bdev_add(disk->part0, ddev->devt); + unlock_new_inode(disk->part0->bd_inode); if (get_capacity(disk)) disk_scan_partitions(disk, BLK_OPEN_READ); @@ -546,6 +558,8 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk, out_device_del: device_del(ddev); out_free_ext_minor: + if (!(disk->flags & GENHD_FL_HIDDEN)) + bdev_inode_failed(disk->part0); if (disk->major == BLOCK_EXT_MAJOR) blk_free_ext_minor(disk->first_minor); out_exit_elevator: diff --git a/block/partitions/core.c b/block/partitions/core.c index 549ce89a657b25c5d21577ace675c353ca9a4d3a..c69e369955b9b6a99ebae5c66904402858b803f5 100644 --- a/block/partitions/core.c +++ b/block/partitions/core.c @@ -376,6 +376,9 @@ static struct block_device *add_partition(struct gendisk *disk, int partno, goto out_put; } + bdev->bd_inode->i_state |= I_NEW; + bdev_add(bdev, devt); + /* delay uevent until 'holders' subdir is created */ dev_set_uevent_suppress(pdev, 1); err = device_add(pdev); @@ -398,7 +401,7 @@ static struct block_device *add_partition(struct gendisk *disk, int partno, err = xa_insert(&disk->part_tbl, partno, bdev, GFP_KERNEL); if (err) goto out_del; - bdev_add(bdev, devt); + unlock_new_inode(bdev->bd_inode); /* suppress uevent if the disk suppresses it */ if (!dev_get_uevent_suppress(ddev)) @@ -409,6 +412,7 @@ static struct block_device *add_partition(struct gendisk *disk, int partno, kobject_put(bdev->bd_holder_dir); device_del(pdev); out_put: + bdev_inode_failed(bdev); put_device(pdev); return ERR_PTR(err); out_put_disk: