blk: reuse lookup_sem to serialize partition operations
hulk inclusion
category: bugfix
bugzilla: 55097
CVE: NA
-------------------------------------------------
Now there no protection between partition operations (e.g, partition
rescan) and delete_partition() in del_gendisk(), so the following
scenario is possible:
CPU 1
blkdev_ioctl del_gendisk
blkdev_reread_part
lock bd_mutex
drop_partitions
check_partition
lock lookup_sem
// for each partition
deletion_partion
// for each partition
add_partition
The newly added partitions, the device files (e.g, /dev/sdXN)
and the symlinks in /sys/class/block will be left behind. If
the deleted disk is online again, the scan of partition will
fail with the following error:
sysfs: cannot create duplicate filename '/class/block/sdaN'
sdX: pN could not be added: 17
Vanilla kernel tries to fix that by commit c76f48eb
("block: take bd_mutex around delete_partitions in del_gendisk"),
but it introduces dead-lock for nbd/loop/xen-frontblk drivers.
These in-tree drivers can be fixed, but there may be other affected
block drivers, especially the out-of-tree ones, so fixing it in
another way.
Two methods are considered. The first is waiting for the end
of partition operations in del_gendisk(). It is OK but it needs
adding new fields in gendisk (bool & wait_queue_head_t). The second
is reusing lookup_sem and GENHD_FL_UP to serialize partition operations
and del_gendisk(). Now the latter is chose and here are the details.
There are six partition operations:
(1) add_partition() in blkpg_ioctl()
(2) deletion_partion() in blkpg_ioctl()
(3) resize in blkpg_ioctl()
(4) partition rescan in __blkdev_reread_part()
(5) partition revalidate in bdev_disk_changed()
(6) deletion_partion() in del_gendisk()
op (1)~(5) already take bd_mutex, so using down_read() to
serialize with down_write() in del_gendisk() is OK. op (3)
only updates the values in hd_struct, so no lock is needed,
because it already increase the ref of hd_struct.
lookup_sem is used to prevent a newly-created blocking device inode from
associating with a deleting gendisk, and the locking order is:
part->bd_mutex -> disk->lookup_sem
or
whole->bd_mutex -> disk->lookup_sem
Now it is also used to serialize the partition operations and the new
locking order will be:
part->bd_mutex -> whole->bd_mutex -> disk->lookup_sem
and it is OK.
Signed-off-by: NHou Tao <houtao1@huawei.com>
Reviewed-by: NJason Yan <yanaijie@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
Showing
想要评论请 注册 或 登录