Message ID | 1583290274-5525-4-git-send-email-light.hsieh@mediatek.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | set ro attribute of block device according to write-protection status | expand |
On Wed, Mar 04, 2020 at 10:51:14AM +0800, light.hsieh@mediatek.com wrote: > From: Light Hsieh <light.hsieh@mediatek.com> > > For storage device with write-protection support, e.g. eMMC, register > check_disk_range_wp() in struct block_device_operations for checking > write-protection status. When creating block device for a partition, set > read/write policy according to result of check_disk_range_wp() operation > (if registered). > > Without this patch, ro attribute is not set for created block device of > write-protected partition. User perform asynchronous buffered write to > such partition won't get immediate error and therefore he won't be awared > that write is not actually performed. > With this patch, ro attribute is set for created block device of > write-protected partition. User perform asynchronous buffered write to > such partition will get immediate error and therefore he will be awared. NAK. This is complete BS. Partitions are a complete software concepts and idiotic features like a range read only should not interact with it at all (and I urge all Linux users to never make use of such broken features, so the less support we have for them, the better).
diff --git a/block/partition-generic.c b/block/partition-generic.c index 564fae7..69088e8 100644 --- a/block/partition-generic.c +++ b/block/partition-generic.c @@ -394,6 +394,16 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, goto out_free_info; pdev->devt = devt; + if (!p->policy) { + if (disk->fops->check_disk_range_wp) { + err = disk->fops->check_disk_range_wp(disk, start, len); + if (err > 0) + p->policy = 1; + else if (err != 0) + goto out_free_info; + } + } + /* delay uevent until 'holders' subdir is created */ dev_set_uevent_suppress(pdev, 1); err = device_add(pdev); diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index ee85abf..af81311 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -1047,6 +1047,7 @@ static int mmc_blk_compat_ioctl(struct block_device *bdev, fmode_t mode, #ifdef CONFIG_COMPAT .compat_ioctl = mmc_blk_compat_ioctl, #endif + .check_disk_range_wp = mmc_blk_check_disk_range_wp, }; static int mmc_blk_part_switch_pre(struct mmc_card *card, diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 053ea4b..7814290 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1707,6 +1707,7 @@ struct block_device_operations { void (*swap_slot_free_notify) (struct block_device *, unsigned long); int (*report_zones)(struct gendisk *, sector_t sector, unsigned int nr_zones, report_zones_cb cb, void *data); + int (*check_disk_range_wp)(struct gendisk *d, sector_t s, sector_t l); struct module *owner; const struct pr_ops *pr_ops; };