From c8361788f2657117a30e2e41152658c5600f023c Mon Sep 17 00:00:00 2001 From: Gao Xiang Date: Mon, 3 Nov 2025 10:43:50 +0800 Subject: [PATCH] anolis: block: fix race between device_add() and bd_inode hashing ANBZ: #26925 For more details, see the upstream bug report. Due to the codebase difference, let's temporarily workaround ANCK 6.6 first. Fixes: 8235b5c1e8c1 ("block: call bdev_add later in device_add_disk") Closes: https://lore.kernel.org/r/43375218-2a80-4a7a-b8bb-465f6419b595@linux.alibaba.com Signed-off-by: Gao Xiang --- block/blk.h | 1 + block/genhd.c | 18 ++++++++++++++++-- block/partitions/core.c | 6 +++++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/block/blk.h b/block/blk.h index 475bbb40bb83..4410ae9da378 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 039e7c17523b..cb4313a7c618 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 549ce89a657b..c69e369955b9 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: -- Gitee