Thanks Mikulas for the patch! This works like a charm. Here's how I tested: On Android, for an APEX file in /system partition, I create a dm-linear device with "shared" mode on top of the dm-verity device underlying the system partition. Previously, this failed with EBUSY because the dm-verity device is owned by the /system filesystem. But I was able to create it in a shared mode with your patch applied. Thanks again! Jooyung On Tue, Nov 12, 2024 at 1:49 AM Mikulas Patocka <mpatocka@xxxxxxxxxx> wrote: > > Hi > > On Fri, 8 Nov 2024, Jooyung Han wrote: > > > Hi Mikulas, > > > > Would it be reasonable to allow this? Or, to reduce the risk or impact > > on other users, how about introducing a flag for dm-linear constructor > > to open a table device without setting the holder. I don't know how to > > describe this, not-exclusive? The dm-linear constructor would look like > > "<dev_path> <offset> [no_exclusive]", when "no_exclusive" is set, it > > will open a table device without setting a holder. > > > > I'd like to get your opinion about this idea. Especially if there's any > > risks about not setting the holder when opening a DM table device. > > > > Besides, there's one more question about dm-verity. Even though there's > > a field named "data_start" (comment saying it's "data offset in 512-byte > > sectors"): https://elixir.bootlin.com/linux/v6.11.4/source/drivers/md/dm-verity.h#L49, > > it's not set in its constructor and always zero after initialization. I > > think it's reasonable for the constructor to set it with an argument > > passed. What do you think? > > Yes, we could set it in the constructor. > > > Thanks. > > I've created this (totally untested) patch that makes it possible to add a > flag DM_OPEN_SHARED to the flags in the create ioctl - when the flag is > used, all devices open by the specified device are open in a shared mode. > Does the patch work for you? > > Mikulas > > > > From: Mikulas Patocka <mpatocka@xxxxxxxxxx> > > This commit adds a new flag DM_OPEN_SHARED. The flag may be used on the > create ioctl. When it is used, the underlying devices that are opened > will be open in a shareable mode, so that the user can mount filesystems > on them or perform other activity. > > Signed-off-by: Mikulas Patocka <mpatocka@xxxxxxxxxx> > > --- > drivers/md/dm-core.h | 1 + > drivers/md/dm-ioctl.c | 4 ++-- > drivers/md/dm.c | 9 +++++++-- > include/linux/device-mapper.h | 2 +- > include/uapi/linux/dm-ioctl.h | 6 ++++++ > 5 files changed, 17 insertions(+), 5 deletions(-) > > Index: linux-2.6/drivers/md/dm-core.h > =================================================================== > --- linux-2.6.orig/drivers/md/dm-core.h 2024-07-30 14:06:48.000000000 +0200 > +++ linux-2.6/drivers/md/dm-core.h 2024-11-11 17:34:13.000000000 +0100 > @@ -161,6 +161,7 @@ struct mapped_device { > #define DMF_SUSPENDED_INTERNALLY 7 > #define DMF_POST_SUSPENDING 8 > #define DMF_EMULATE_ZONE_APPEND 9 > +#define DMF_OPEN_SHARED 10 > > void disable_discard(struct mapped_device *md); > void disable_write_zeroes(struct mapped_device *md); > Index: linux-2.6/drivers/md/dm-ioctl.c > =================================================================== > --- linux-2.6.orig/drivers/md/dm-ioctl.c 2024-09-02 17:35:39.000000000 +0200 > +++ linux-2.6/drivers/md/dm-ioctl.c 2024-11-11 17:35:51.000000000 +0100 > @@ -888,7 +888,7 @@ static int dev_create(struct file *filp, > if (param->flags & DM_PERSISTENT_DEV_FLAG) > m = MINOR(huge_decode_dev(param->dev)); > > - r = dm_create(m, &md); > + r = dm_create(m, param->flags, &md); > if (r) > return r; > > @@ -2283,7 +2283,7 @@ int __init dm_early_create(struct dm_ioc > m = MINOR(huge_decode_dev(dmi->dev)); > > /* alloc dm device */ > - r = dm_create(m, &md); > + r = dm_create(m, 0, &md); > if (r) > return r; > > Index: linux-2.6/drivers/md/dm.c > =================================================================== > --- linux-2.6.orig/drivers/md/dm.c 2024-11-07 12:49:13.000000000 +0100 > +++ linux-2.6/drivers/md/dm.c 2024-11-11 17:35:05.000000000 +0100 > @@ -737,7 +737,9 @@ static struct table_device *open_table_d > return ERR_PTR(-ENOMEM); > refcount_set(&td->count, 1); > > - bdev_file = bdev_file_open_by_dev(dev, mode, _dm_claim_ptr, NULL); > + bdev_file = bdev_file_open_by_dev(dev, mode, > + test_bit(DMF_OPEN_SHARED, &md->flags) ? NULL :_dm_claim_ptr, > + NULL); > if (IS_ERR(bdev_file)) { > r = PTR_ERR(bdev_file); > goto out_free_td; > @@ -2489,7 +2491,7 @@ static struct dm_table *__unbind(struct > /* > * Constructor for a new device. > */ > -int dm_create(int minor, struct mapped_device **result) > +int dm_create(int minor, uint32_t flags, struct mapped_device **result) > { > struct mapped_device *md; > > @@ -2497,6 +2499,9 @@ int dm_create(int minor, struct mapped_d > if (!md) > return -ENXIO; > > + if (flags & DM_OPEN_SHARED) > + set_bit(DMF_OPEN_SHARED, &md->flags); > + > dm_ima_reset_data(md); > > *result = md; > Index: linux-2.6/include/linux/device-mapper.h > =================================================================== > --- linux-2.6.orig/include/linux/device-mapper.h 2024-10-16 16:41:33.000000000 +0200 > +++ linux-2.6/include/linux/device-mapper.h 2024-11-11 17:31:32.000000000 +0100 > @@ -483,7 +483,7 @@ void dm_consume_args(struct dm_arg_set * > * DM_ANY_MINOR chooses the next available minor number. > */ > #define DM_ANY_MINOR (-1) > -int dm_create(int minor, struct mapped_device **md); > +int dm_create(int minor, uint32_t flags, struct mapped_device **md); > > /* > * Reference counting for md. > Index: linux-2.6/include/uapi/linux/dm-ioctl.h > =================================================================== > --- linux-2.6.orig/include/uapi/linux/dm-ioctl.h 2023-09-05 14:46:02.000000000 +0200 > +++ linux-2.6/include/uapi/linux/dm-ioctl.h 2024-11-11 17:33:33.000000000 +0100 > @@ -382,4 +382,10 @@ enum { > */ > #define DM_IMA_MEASUREMENT_FLAG (1 << 19) /* In */ > > +/* > + * Open underlying devices in the shareable mode, so that the user can mount > + * filesystems on them. > + */ > +#define DM_OPEN_SHARED (1 << 20) /* In */ > + > #endif /* _LINUX_DM_IOCTL_H */