From: Jan Kara <jack@suse.cz>
Subject: dax: Make extension of dax_operations transparent
Patch-mainline: Never, kabi
References: bsc#1098782
Provide new alloc_dax_to_iter() function for use by drivers which are aware
that struct dax_operations has a new member and use it.
Signed-off-by: Jan Kara <jack@suse.cz>
---
drivers/dax/super.c | 16 ++++++++++++++++
drivers/md/dm.c | 2 +-
drivers/nvdimm/pmem.c | 2 +-
drivers/s390/block/dcssblk.c | 2 +-
include/linux/dax.h | 4 ++++
5 files changed, 23 insertions(+), 3 deletions(-)
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -133,6 +133,8 @@ enum dax_device_flags {
DAXDEV_ALIVE,
/* gate whether dax_flush() calls the low level flush routine */
DAXDEV_WRITE_CACHE,
+ /* set if dax device supports copy_to_iter operation */
+ DAXDEV_TO_ITER,
};
/**
@@ -274,6 +276,8 @@ size_t dax_copy_to_iter(struct dax_devic
{
if (!dax_alive(dax_dev))
return 0;
+ if (!test_bit(DAXDEV_TO_ITER, &dax_dev->flags))
+ return copy_to_iter(addr, bytes, i);
return dax_dev->ops->copy_to_iter(dax_dev, pgoff, addr, bytes, i);
}
@@ -499,6 +503,18 @@ struct dax_device *alloc_dax(void *priva
}
EXPORT_SYMBOL_GPL(alloc_dax);
+struct dax_device *alloc_dax_to_iter(void *private, const char *__host,
+ const struct dax_operations *ops)
+{
+ struct dax_device *dax_dev = alloc_dax(private, __host, ops);
+
+ if (!dax_dev)
+ return NULL;
+ set_bit(DAXDEV_TO_ITER, &dax_dev->flags);
+ return dax_dev;
+}
+EXPORT_SYMBOL_GPL(alloc_dax_to_iter);
+
void put_dax(struct dax_device *dax_dev)
{
if (!dax_dev)
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1763,7 +1763,7 @@ static struct mapped_device *alloc_dev(i
md->disk->private_data = md;
sprintf(md->disk->disk_name, "dm-%d", minor);
- dax_dev = alloc_dax(md, md->disk->disk_name, &dm_dax_ops);
+ dax_dev = alloc_dax_to_iter(md, md->disk->disk_name, &dm_dax_ops);
if (!dax_dev)
goto bad;
md->dax_dev = dax_dev;
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -391,7 +391,7 @@ static int pmem_attach_disk(struct devic
nvdimm_badblocks_populate(nd_region, &pmem->bb, res);
disk->bb = &pmem->bb;
- dax_dev = alloc_dax(pmem, disk->disk_name, &pmem_dax_ops);
+ dax_dev = alloc_dax_to_iter(pmem, disk->disk_name, &pmem_dax_ops);
if (!dax_dev) {
put_disk(disk);
return -ENOMEM;
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -676,7 +676,7 @@ dcssblk_add_store(struct device *dev, st
if (rc)
goto put_dev;
- dev_info->dax_dev = alloc_dax(dev_info, dev_info->gd->disk_name,
+ dev_info->dax_dev = alloc_dax_to_iter(dev_info, dev_info->gd->disk_name,
&dcssblk_dax_ops);
if (!dev_info->dax_dev) {
rc = -ENOMEM;
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -19,9 +19,11 @@ struct dax_operations {
/* copy_from_iter: required operation for fs-dax direct-i/o */
size_t (*copy_from_iter)(struct dax_device *, pgoff_t, void *, size_t,
struct iov_iter *);
+#ifndef __GENKSYMS__
/* copy_to_iter: required operation for fs-dax direct-i/o */
size_t (*copy_to_iter)(struct dax_device *, pgoff_t, void *, size_t,
struct iov_iter *);
+#endif
};
extern struct attribute_group dax_attribute_group;
@@ -85,6 +87,8 @@ int dax_read_lock(void);
void dax_read_unlock(int id);
struct dax_device *alloc_dax(void *private, const char *host,
const struct dax_operations *ops);
+struct dax_device *alloc_dax_to_iter(void *private, const char *host,
+ const struct dax_operations *ops);
bool dax_alive(struct dax_device *dax_dev);
void kill_dax(struct dax_device *dax_dev);
void *dax_get_private(struct dax_device *dax_dev);