@@ -153,9 +153,13 @@ axon_ram_direct_access(struct block_device *device, sector_t sector,
return bank->size - offset;
}
+static const struct dax_operations axon_ram_dax_ops = {
+ .direct_access = axon_ram_direct_access,
+};
+
static const struct block_device_operations axon_ram_devops = {
.owner = THIS_MODULE,
- .direct_access = axon_ram_direct_access
+ .dax_ops = &axon_ram_dax_ops,
};
/**
@@ -395,10 +395,14 @@ static long brd_direct_access(struct block_device *bdev, sector_t sector,
#define brd_direct_access NULL
#endif
+static const struct dax_operations brd_dax_ops = {
+ .direct_access = brd_direct_access,
+};
+
static const struct block_device_operations brd_fops = {
.owner = THIS_MODULE,
.rw_page = brd_rw_page,
- .direct_access = brd_direct_access,
+ .dax_ops = &brd_dax_ops,
};
/*
@@ -2725,13 +2725,17 @@ static const struct pr_ops dm_pr_ops = {
.pr_clear = dm_pr_clear,
};
+static const struct dax_operations dm_dax_ops = {
+ .direct_access = dm_blk_direct_access,
+};
+
static const struct block_device_operations dm_blk_dops = {
.open = dm_blk_open,
.release = dm_blk_close,
.ioctl = dm_blk_ioctl,
- .direct_access = dm_blk_direct_access,
.getgeo = dm_blk_getgeo,
.pr_ops = &dm_pr_ops,
+ .dax_ops = &dm_dax_ops,
.owner = THIS_MODULE
};
@@ -217,11 +217,15 @@ __weak long pmem_direct_access(struct block_device *bdev, sector_t sector,
return pmem->size - pmem->pfn_pad - offset;
}
+static const struct dax_operations pmem_dax_ops = {
+ .direct_access = pmem_direct_access,
+};
+
static const struct block_device_operations pmem_fops = {
.owner = THIS_MODULE,
.rw_page = pmem_rw_page,
- .direct_access = pmem_direct_access,
.revalidate_disk = nvdimm_revalidate_disk,
+ .dax_ops = &pmem_dax_ops,
};
static void pmem_release_queue(void *q)
@@ -36,11 +36,15 @@ static long dcssblk_direct_access(struct block_device *bdev, sector_t secnum,
static char dcssblk_segments[DCSSBLK_PARM_LEN] = "\0";
static int dcssblk_major;
+
+static const struct dax_operations dcssblk_dax_ops = {
+ .direct_access = dcssblk_direct_access,
+};
+
static const struct block_device_operations dcssblk_devops = {
.owner = THIS_MODULE,
.open = dcssblk_open,
.release = dcssblk_release,
- .direct_access = dcssblk_direct_access,
};
struct dcssblk_dev_info {
@@ -736,6 +736,7 @@ long bdev_direct_access(struct block_device *bdev, struct blk_dax_ctl *dax)
sector_t sector = dax->sector;
long avail, size = dax->size;
const struct block_device_operations *ops = bdev->bd_disk->fops;
+ const struct dax_operations *dax_ops = ops->dax_ops;
/*
* The device driver is allowed to sleep, in order to make the
@@ -745,7 +746,8 @@ long bdev_direct_access(struct block_device *bdev, struct blk_dax_ctl *dax)
if (size < 0)
return size;
- if (!blk_queue_dax(bdev_get_queue(bdev)) || !ops->direct_access)
+ if (!blk_queue_dax(bdev_get_queue(bdev)) || !dax_ops
+ || !dax_ops->direct_access)
return -EOPNOTSUPP;
if ((sector + DIV_ROUND_UP(size, 512)) >
part_nr_sects_read(bdev->bd_part))
@@ -753,7 +755,7 @@ long bdev_direct_access(struct block_device *bdev, struct blk_dax_ctl *dax)
sector += get_start_sect(bdev);
if (sector % (PAGE_SIZE / 512))
return -EINVAL;
- avail = ops->direct_access(bdev, sector, &dax->addr, &dax->pfn, size);
+ avail = dax_ops->direct_access(bdev, sector, &dax->addr, &dax->pfn, size);
if (!avail)
return -ERANGE;
if (avail > 0 && avail & ~PAGE_MASK)
@@ -1863,14 +1863,17 @@ struct blk_dax_ctl {
pfn_t pfn;
};
+struct dax_operations {
+ long (*direct_access)(struct block_device *, sector_t, void **, pfn_t *,
+ long);
+};
+
struct block_device_operations {
int (*open) (struct block_device *, fmode_t);
void (*release) (struct gendisk *, fmode_t);
int (*rw_page)(struct block_device *, sector_t, struct page *, bool);
int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
- long (*direct_access)(struct block_device *, sector_t, void **, pfn_t *,
- long);
unsigned int (*check_events) (struct gendisk *disk,
unsigned int clearing);
/* ->media_changed() is DEPRECATED, use ->check_events() instead */
@@ -1882,6 +1885,7 @@ struct block_device_operations {
void (*swap_slot_free_notify) (struct block_device *, unsigned long);
struct module *owner;
const struct pr_ops *pr_ops;
+ const struct dax_operations *dax_ops;
};
extern int __blkdev_driver_ioctl(struct block_device *, fmode_t, unsigned int,
Prepare for the removal of memcpy_to_pmem() and copy_from_iter_pmem() by introducing dax_ops. This allows for driver specific overrides for the routines that transfer data to a dax capable block device. Cc: <dm-devel@redhat.com> Cc: Jan Kara <jack@suse.cz> Cc: Jens Axboe <axboe@fb.com> Cc: Jeff Moyer <jmoyer@redhat.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Toshi Kani <toshi.kani@hpe.com> Cc: Mike Snitzer <snitzer@redhat.com> Cc: Matthew Wilcox <mawilcox@microsoft.com> Cc: Ross Zwisler <ross.zwisler@linux.intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> --- arch/powerpc/sysdev/axonram.c | 6 +++++- drivers/block/brd.c | 6 +++++- drivers/md/dm.c | 6 +++++- drivers/nvdimm/pmem.c | 6 +++++- drivers/s390/block/dcssblk.c | 6 +++++- fs/block_dev.c | 6 ++++-- include/linux/blkdev.h | 8 ++++++-- 7 files changed, 35 insertions(+), 9 deletions(-) -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel