On Thu, 3 Jul 2025 13:50:16 -0500 John Groves <John@xxxxxxxxxx> wrote: > This function should be called by fs-dax file systems after opening the > devdax device. This adds holder_operations, which effects exclusivity > between callers of fs_dax_get(). > > This function serves the same role as fs_dax_get_by_bdev(), which dax > file systems call after opening the pmem block device. > > This also adds the CONFIG_DEV_DAX_IOMAP Kconfig parameter > > Signed-off-by: John Groves <john@xxxxxxxxxx> Trivial stuff inline. > --- > drivers/dax/Kconfig | 6 ++++++ > drivers/dax/super.c | 30 ++++++++++++++++++++++++++++++ > include/linux/dax.h | 5 +++++ > 3 files changed, 41 insertions(+) > > diff --git a/drivers/dax/Kconfig b/drivers/dax/Kconfig > index d656e4c0eb84..ad19fa966b8b 100644 > --- a/drivers/dax/Kconfig > +++ b/drivers/dax/Kconfig > @@ -78,4 +78,10 @@ config DEV_DAX_KMEM > > Say N if unsure. > > +config DEV_DAX_IOMAP > + depends on DEV_DAX && DAX > + def_bool y > + help > + Support iomap mapping of devdax devices (for FS-DAX file > + systems that reside on character /dev/dax devices) > endif > diff --git a/drivers/dax/super.c b/drivers/dax/super.c > index e16d1d40d773..48bab9b5f341 100644 > --- a/drivers/dax/super.c > +++ b/drivers/dax/super.c > @@ -122,6 +122,36 @@ void fs_put_dax(struct dax_device *dax_dev, void *holder) > EXPORT_SYMBOL_GPL(fs_put_dax); > #endif /* CONFIG_BLOCK && CONFIG_FS_DAX */ > > +#if IS_ENABLED(CONFIG_DEV_DAX_IOMAP) > +/** > + * fs_dax_get() Trivial but from what I recall kernel-doc isn't going to like this. Needs a short description. > + * > + * fs-dax file systems call this function to prepare to use a devdax device for > + * fsdax. This is like fs_dax_get_by_bdev(), but the caller already has struct > + * dev_dax (and there * is no bdev). The holder makes this exclusive. there is no *bdev? So * in wrong place. > + * > + * @dax_dev: dev to be prepared for fs-dax usage > + * @holder: filesystem or mapped device inside the dax_device > + * @hops: operations for the inner holder > + * > + * Returns: 0 on success, <0 on failure > + */ > +int fs_dax_get(struct dax_device *dax_dev, void *holder, > + const struct dax_holder_operations *hops) > +{ > + if (!dax_dev || !dax_alive(dax_dev) || !igrab(&dax_dev->inode)) > + return -ENODEV; > + > + if (cmpxchg(&dax_dev->holder_data, NULL, holder)) > + return -EBUSY; > + > + dax_dev->holder_ops = hops; > + > + return 0; > +} > +EXPORT_SYMBOL_GPL(fs_dax_get); > +#endif /* DEV_DAX_IOMAP */ > + > enum dax_device_flags { > /* !alive + rcu grace period == no new operations / mappings */ > DAXDEV_ALIVE, > diff --git a/include/linux/dax.h b/include/linux/dax.h > index df41a0017b31..86bf5922f1b0 100644 > --- a/include/linux/dax.h > +++ b/include/linux/dax.h > @@ -51,6 +51,11 @@ struct dax_holder_operations { > > #if IS_ENABLED(CONFIG_DAX) > struct dax_device *alloc_dax(void *private, const struct dax_operations *ops); > + > +#if IS_ENABLED(CONFIG_DEV_DAX_IOMAP) > +int fs_dax_get(struct dax_device *dax_dev, void *holder, const struct dax_holder_operations *hops); > +struct dax_device *inode_dax(struct inode *inode); > +#endif > void *dax_holder(struct dax_device *dax_dev); > void put_dax(struct dax_device *dax_dev); > void kill_dax(struct dax_device *dax_dev);