reparse_partition_table() will delete a device's existing partition cdevs and allocate new ones according to the new partition table. Holding a reference to a cdev prevents it from bring removed to avoid dangling pointers and use-after-frees. Unfortunately, not all users call cdev_open on the cdev and increment the usage count, instead using functions like cdev_by_name, which don't call cdev_open. The proper solution for this is probably to change all functions that return a cdev to actually take a reference to the cdev. This will involve quite a bit of work though, so for now, restore old behavior by making reparsing of the partition tables dependent on CONFIG_PARTITION_MANIPULATION=y. The option isn't fully appropriate as partition manipulation can happen by writing to the parent block device, but not noticing changes of partitions is the behavior we had before. Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx> --- common/partitions.c | 2 ++ include/disks.h | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/common/partitions.c b/common/partitions.c index 17c2f1eb281a..0b10377e7327 100644 --- a/common/partitions.c +++ b/common/partitions.c @@ -266,6 +266,7 @@ int parse_partition_table(struct block_device *blk) return rc; } +#ifdef CONFIG_PARTITION_MANIPULATION int reparse_partition_table(struct block_device *blk) { struct cdev *cdev = &blk->cdev; @@ -285,6 +286,7 @@ int reparse_partition_table(struct block_device *blk) return parse_partition_table(blk); } +#endif int partition_parser_register(struct partition_parser *p) { diff --git a/include/disks.h b/include/disks.h index ccb50d3ce94f..a3673d1e276f 100644 --- a/include/disks.h +++ b/include/disks.h @@ -3,6 +3,9 @@ #ifndef DISKS_H #define DISKS_H +#include <linux/types.h> +#include <linux/errno.h> + struct block_device; /** Size of one sector in bytes */ @@ -24,6 +27,14 @@ struct partition_entry { } __attribute__ ((packed)); extern int parse_partition_table(struct block_device*); + +#ifdef CONFIG_PARTITION_MANIPULATION int reparse_partition_table(struct block_device *blk); +#else +static inline int reparse_partition_table(struct block_device *blk) +{ + return -ENOSYS; +} +#endif #endif /* DISKS_H */ -- 2.39.2