diff mbox

[v2,1/5] block, dax: pass blk_dax_ctl through to drivers

Message ID 1459303190-20072-2-git-send-email-vishal.l.verma@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Verma, Vishal L March 30, 2016, 1:59 a.m. UTC
From: Dan Williams <dan.j.williams@intel.com>

This is in preparation for doing badblocks checking against the
requested sector range in the driver.  Currently we opportunistically
return as much data that can be "dax'd" starting at the given sector.
When errors are present we want to limit that range to the first
encountered error, or fail the dax request if the range encompasses an
error.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 arch/powerpc/sysdev/axonram.c | 10 +++++-----
 drivers/block/brd.c           |  9 +++++----
 drivers/nvdimm/pmem.c         |  9 +++++----
 drivers/s390/block/dcssblk.c  | 12 ++++++------
 fs/block_dev.c                |  2 +-
 include/linux/blkdev.h        |  3 +--
 6 files changed, 23 insertions(+), 22 deletions(-)

Comments

kernel test robot March 30, 2016, 4:19 a.m. UTC | #1
Hi Dan,

[auto build test ERROR on linux-nvdimm/libnvdimm-for-next]
[also build test ERROR on v4.6-rc1 next-20160329]
[cannot apply to xfs/for-next]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]

url:    https://github.com/0day-ci/linux/commits/Vishal-Verma/dax-handling-of-media-errors/20160330-100409
base:   https://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm libnvdimm-for-next
config: s390-default_defconfig (attached as .config)
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=s390 

All error/warnings (new ones prefixed by >>):

   drivers/s390/block/dcssblk.c: In function 'dcssblk_direct_access':
>> drivers/s390/block/dcssblk.c:36:13: error: storage class specified for parameter 'dcssblk_segments'
    static char dcssblk_segments[DCSSBLK_PARM_LEN] = "\0";
                ^
>> drivers/s390/block/dcssblk.c:36:1: error: parameter 'dcssblk_segments' is initialized
    static char dcssblk_segments[DCSSBLK_PARM_LEN] = "\0";
    ^
>> drivers/s390/block/dcssblk.c:38:12: error: storage class specified for parameter 'dcssblk_major'
    static int dcssblk_major;
               ^
>> drivers/s390/block/dcssblk.c:39:45: error: storage class specified for parameter 'dcssblk_devops'
    static const struct block_device_operations dcssblk_devops = {
                                                ^
>> drivers/s390/block/dcssblk.c:39:21: error: parameter 'dcssblk_devops' is initialized
    static const struct block_device_operations dcssblk_devops = {
                        ^
>> drivers/s390/block/dcssblk.c:46:1: warning: empty declaration
    struct dcssblk_dev_info {
    ^
   drivers/s390/block/dcssblk.c:62:1: warning: empty declaration
    struct segment_info {
    ^
>> drivers/s390/block/dcssblk.c:70:16: error: storage class specified for parameter 'dcssblk_add_store'
    static ssize_t dcssblk_add_store(struct device * dev, struct device_attribute *attr, const char * buf,
                   ^
>> drivers/s390/block/dcssblk.c:72:16: error: storage class specified for parameter 'dcssblk_remove_store'
    static ssize_t dcssblk_remove_store(struct device * dev, struct device_attribute *attr, const char * buf,
                   ^
   In file included from include/linux/genhd.h:63:0,
                    from include/linux/blkdev.h:9,
                    from drivers/s390/block/dcssblk.c:16:
>> include/linux/device.h:575:26: error: storage class specified for parameter 'dev_attr_add'
     struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
                             ^
>> drivers/s390/block/dcssblk.c:75:8: note: in expansion of macro 'DEVICE_ATTR'
    static DEVICE_ATTR(add, S_IWUSR, NULL, dcssblk_add_store);
           ^
>> include/linux/device.h:575:9: error: parameter 'dev_attr_add' is initialized
     struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
            ^
>> drivers/s390/block/dcssblk.c:75:8: note: in expansion of macro 'DEVICE_ATTR'
    static DEVICE_ATTR(add, S_IWUSR, NULL, dcssblk_add_store);
           ^
>> include/linux/device.h:575:26: error: storage class specified for parameter 'dev_attr_remove'
     struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
                             ^
   drivers/s390/block/dcssblk.c:76:8: note: in expansion of macro 'DEVICE_ATTR'
    static DEVICE_ATTR(remove, S_IWUSR, NULL, dcssblk_remove_store);
           ^
>> include/linux/device.h:575:9: error: parameter 'dev_attr_remove' is initialized
     struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
            ^
   drivers/s390/block/dcssblk.c:76:8: note: in expansion of macro 'DEVICE_ATTR'
    static DEVICE_ATTR(remove, S_IWUSR, NULL, dcssblk_remove_store);
           ^
>> drivers/s390/block/dcssblk.c:78:23: error: storage class specified for parameter 'dcssblk_root_dev'
    static struct device *dcssblk_root_dev;
                          ^
   In file included from include/linux/module.h:9:0,
                    from drivers/s390/block/dcssblk.c:10:
>> drivers/s390/block/dcssblk.c:80:18: error: storage class specified for parameter 'dcssblk_devices'
    static LIST_HEAD(dcssblk_devices);
                     ^
   include/linux/list.h:23:19: note: in definition of macro 'LIST_HEAD'
     struct list_head name = LIST_HEAD_INIT(name)
                      ^
>> include/linux/list.h:23:9: error: parameter 'dcssblk_devices' is initialized
     struct list_head name = LIST_HEAD_INIT(name)
            ^
>> drivers/s390/block/dcssblk.c:80:8: note: in expansion of macro 'LIST_HEAD'
    static LIST_HEAD(dcssblk_devices);
           ^
>> drivers/s390/block/dcssblk.c:81:28: error: storage class specified for parameter 'dcssblk_devices_sem'
    static struct rw_semaphore dcssblk_devices_sem;
                               ^
>> drivers/s390/block/dcssblk.c:88:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   drivers/s390/block/dcssblk.c:109:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   drivers/s390/block/dcssblk.c:136:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   drivers/s390/block/dcssblk.c:154:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   drivers/s390/block/dcssblk.c:172:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   drivers/s390/block/dcssblk.c:189:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   drivers/s390/block/dcssblk.c:213:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   drivers/s390/block/dcssblk.c:279:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   drivers/s390/block/dcssblk.c:315:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   drivers/s390/block/dcssblk.c:324:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   In file included from include/linux/genhd.h:63:0,
                    from include/linux/blkdev.h:9,
                    from drivers/s390/block/dcssblk.c:16:

vim +/dcssblk_segments +36 drivers/s390/block/dcssblk.c

^1da177e Linus Torvalds  2005-04-16  23  
^1da177e Linus Torvalds  2005-04-16  24  #define DCSSBLK_NAME "dcssblk"
^1da177e Linus Torvalds  2005-04-16  25  #define DCSSBLK_MINORS_PER_DISK 1
^1da177e Linus Torvalds  2005-04-16  26  #define DCSSBLK_PARM_LEN 400
98df67b3 Kay Sievers     2008-12-25  27  #define DCSS_BUS_ID_SIZE 20
^1da177e Linus Torvalds  2005-04-16  28  
46d74326 Al Viro         2008-03-02 @29  static int dcssblk_open(struct block_device *bdev, fmode_t mode);
db2a144b Al Viro         2013-05-05 @30  static void dcssblk_release(struct gendisk *disk, fmode_t mode);
dece1635 Jens Axboe      2015-11-05  31  static blk_qc_t dcssblk_make_request(struct request_queue *q,
dece1635 Jens Axboe      2015-11-05  32  						struct bio *bio);
e3cb53fb Dan Williams    2016-03-29 @33  static long dcssblk_direct_access(struct block_device *bdev,
e3cb53fb Dan Williams    2016-03-29  34  		struct blk_dax_ctl *dax)
^1da177e Linus Torvalds  2005-04-16  35  
^1da177e Linus Torvalds  2005-04-16 @36  static char dcssblk_segments[DCSSBLK_PARM_LEN] = "\0";
^1da177e Linus Torvalds  2005-04-16  37  
^1da177e Linus Torvalds  2005-04-16 @38  static int dcssblk_major;
83d5cde4 Alexey Dobriyan 2009-09-21 @39  static const struct block_device_operations dcssblk_devops = {
^1da177e Linus Torvalds  2005-04-16  40  	.owner   	= THIS_MODULE,
46d74326 Al Viro         2008-03-02  41  	.open    	= dcssblk_open,
46d74326 Al Viro         2008-03-02  42  	.release 	= dcssblk_release,
420edbcc Carsten Otte    2005-06-23  43  	.direct_access 	= dcssblk_direct_access,
^1da177e Linus Torvalds  2005-04-16  44  };
^1da177e Linus Torvalds  2005-04-16  45  
b2300b9e Hongjie Yang    2008-10-10 @46  struct dcssblk_dev_info {
b2300b9e Hongjie Yang    2008-10-10  47  	struct list_head lh;
b2300b9e Hongjie Yang    2008-10-10  48  	struct device dev;
98df67b3 Kay Sievers     2008-12-25  49  	char segment_name[DCSS_BUS_ID_SIZE];
b2300b9e Hongjie Yang    2008-10-10  50  	atomic_t use_count;
b2300b9e Hongjie Yang    2008-10-10  51  	struct gendisk *gd;
b2300b9e Hongjie Yang    2008-10-10  52  	unsigned long start;
b2300b9e Hongjie Yang    2008-10-10  53  	unsigned long end;
b2300b9e Hongjie Yang    2008-10-10  54  	int segment_type;
b2300b9e Hongjie Yang    2008-10-10  55  	unsigned char save_pending;
b2300b9e Hongjie Yang    2008-10-10  56  	unsigned char is_shared;
b2300b9e Hongjie Yang    2008-10-10  57  	struct request_queue *dcssblk_queue;
b2300b9e Hongjie Yang    2008-10-10  58  	int num_of_segments;
b2300b9e Hongjie Yang    2008-10-10  59  	struct list_head seg_list;
b2300b9e Hongjie Yang    2008-10-10  60  };
b2300b9e Hongjie Yang    2008-10-10  61  
b2300b9e Hongjie Yang    2008-10-10  62  struct segment_info {
b2300b9e Hongjie Yang    2008-10-10  63  	struct list_head lh;
98df67b3 Kay Sievers     2008-12-25  64  	char segment_name[DCSS_BUS_ID_SIZE];
b2300b9e Hongjie Yang    2008-10-10  65  	unsigned long start;
b2300b9e Hongjie Yang    2008-10-10  66  	unsigned long end;
b2300b9e Hongjie Yang    2008-10-10  67  	int segment_type;
b2300b9e Hongjie Yang    2008-10-10  68  };
b2300b9e Hongjie Yang    2008-10-10  69  
e404e274 Yani Ioannou    2005-05-17 @70  static ssize_t dcssblk_add_store(struct device * dev, struct device_attribute *attr, const char * buf,
^1da177e Linus Torvalds  2005-04-16  71  				  size_t count);
e404e274 Yani Ioannou    2005-05-17 @72  static ssize_t dcssblk_remove_store(struct device * dev, struct device_attribute *attr, const char * buf,
^1da177e Linus Torvalds  2005-04-16  73  				  size_t count);
^1da177e Linus Torvalds  2005-04-16  74  
^1da177e Linus Torvalds  2005-04-16 @75  static DEVICE_ATTR(add, S_IWUSR, NULL, dcssblk_add_store);
^1da177e Linus Torvalds  2005-04-16 @76  static DEVICE_ATTR(remove, S_IWUSR, NULL, dcssblk_remove_store);
^1da177e Linus Torvalds  2005-04-16  77  
^1da177e Linus Torvalds  2005-04-16 @78  static struct device *dcssblk_root_dev;
^1da177e Linus Torvalds  2005-04-16  79  
c11ca97e Denis Cheng     2008-01-26 @80  static LIST_HEAD(dcssblk_devices);
^1da177e Linus Torvalds  2005-04-16 @81  static struct rw_semaphore dcssblk_devices_sem;
^1da177e Linus Torvalds  2005-04-16  82  
^1da177e Linus Torvalds  2005-04-16  83  /*
^1da177e Linus Torvalds  2005-04-16  84   * release function for segment device.
^1da177e Linus Torvalds  2005-04-16  85   */
^1da177e Linus Torvalds  2005-04-16  86  static void
^1da177e Linus Torvalds  2005-04-16  87  dcssblk_release_segment(struct device *dev)
^1da177e Linus Torvalds  2005-04-16 @88  {
b2300b9e Hongjie Yang    2008-10-10  89  	struct dcssblk_dev_info *dev_info;
b2300b9e Hongjie Yang    2008-10-10  90  	struct segment_info *entry, *temp;
b2300b9e Hongjie Yang    2008-10-10  91  

:::::: The code at line 36 was first introduced by commit
:::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2

:::::: TO: Linus Torvalds <torvalds@ppc970.osdl.org>
:::::: CC: Linus Torvalds <torvalds@ppc970.osdl.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Jeff Moyer April 15, 2016, 2:55 p.m. UTC | #2
Vishal Verma <vishal.l.verma@intel.com> writes:

> From: Dan Williams <dan.j.williams@intel.com>
>
> This is in preparation for doing badblocks checking against the
> requested sector range in the driver.  Currently we opportunistically
> return as much data that can be "dax'd" starting at the given sector.
> When errors are present we want to limit that range to the first
> encountered error, or fail the dax request if the range encompasses an
> error.

I'm not a fan of hiding arguments like this, but it looks fine.

Reviewed-by: Jeff Moyer <jmoyer@redhat.com>


> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> ---
>  arch/powerpc/sysdev/axonram.c | 10 +++++-----
>  drivers/block/brd.c           |  9 +++++----
>  drivers/nvdimm/pmem.c         |  9 +++++----
>  drivers/s390/block/dcssblk.c  | 12 ++++++------
>  fs/block_dev.c                |  2 +-
>  include/linux/blkdev.h        |  3 +--
>  6 files changed, 23 insertions(+), 22 deletions(-)
>
> diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c
> index 0d112b9..d85673f 100644
> --- a/arch/powerpc/sysdev/axonram.c
> +++ b/arch/powerpc/sysdev/axonram.c
> @@ -139,17 +139,17 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
>  
>  /**
>   * axon_ram_direct_access - direct_access() method for block device
> - * @device, @sector, @data: see block_device_operations method
> + * @dax: see block_device_operations method
>   */
>  static long
> -axon_ram_direct_access(struct block_device *device, sector_t sector,
> -		       void __pmem **kaddr, pfn_t *pfn)
> +axon_ram_direct_access(struct block_device *device, struct blk_dax_ctl *dax)
>  {
> +	sector_t sector = get_start_sect(device) + dax->sector;
>  	struct axon_ram_bank *bank = device->bd_disk->private_data;
>  	loff_t offset = (loff_t)sector << AXON_RAM_SECTOR_SHIFT;
>  
> -	*kaddr = (void __pmem __force *) bank->io_addr + offset;
> -	*pfn = phys_to_pfn_t(bank->ph_addr + offset, PFN_DEV);
> +	dax->addr = (void __pmem __force *) bank->io_addr + offset;
> +	dax->pfn = phys_to_pfn_t(bank->ph_addr + offset, PFN_DEV);
>  	return bank->size - offset;
>  }
>  
> diff --git a/drivers/block/brd.c b/drivers/block/brd.c
> index f7ecc28..e3e4780 100644
> --- a/drivers/block/brd.c
> +++ b/drivers/block/brd.c
> @@ -380,9 +380,10 @@ static int brd_rw_page(struct block_device *bdev, sector_t sector,
>  }
>  
>  #ifdef CONFIG_BLK_DEV_RAM_DAX
> -static long brd_direct_access(struct block_device *bdev, sector_t sector,
> -			void __pmem **kaddr, pfn_t *pfn)
> +static long brd_direct_access(struct block_device *bdev,
> +		struct blk_dax_ctl *dax)
>  {
> +	sector_t sector = get_start_sect(bdev) + dax->sector;
>  	struct brd_device *brd = bdev->bd_disk->private_data;
>  	struct page *page;
>  
> @@ -391,8 +392,8 @@ static long brd_direct_access(struct block_device *bdev, sector_t sector,
>  	page = brd_insert_page(brd, sector);
>  	if (!page)
>  		return -ENOSPC;
> -	*kaddr = (void __pmem *)page_address(page);
> -	*pfn = page_to_pfn_t(page);
> +	dax->addr = (void __pmem *)page_address(page);
> +	dax->pfn = page_to_pfn_t(page);
>  
>  	return PAGE_SIZE;
>  }
> diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
> index ca5721c..da10554 100644
> --- a/drivers/nvdimm/pmem.c
> +++ b/drivers/nvdimm/pmem.c
> @@ -167,14 +167,15 @@ static int pmem_rw_page(struct block_device *bdev, sector_t sector,
>  	return rc;
>  }
>  
> -static long pmem_direct_access(struct block_device *bdev, sector_t sector,
> -		      void __pmem **kaddr, pfn_t *pfn)
> +static long pmem_direct_access(struct block_device *bdev,
> +		struct blk_dax_ctl *dax)
>  {
> +	sector_t sector = get_start_sect(bdev) + dax->sector;
>  	struct pmem_device *pmem = bdev->bd_disk->private_data;
>  	resource_size_t offset = sector * 512 + pmem->data_offset;
>  
> -	*kaddr = pmem->virt_addr + offset;
> -	*pfn = phys_to_pfn_t(pmem->phys_addr + offset, pmem->pfn_flags);
> +	dax->addr = pmem->virt_addr + offset;
> +	dax->pfn = phys_to_pfn_t(pmem->phys_addr + offset, pmem->pfn_flags);
>  
>  	return pmem->size - pmem->pfn_pad - offset;
>  }
> diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
> index 1bce9cf..5719c30 100644
> --- a/drivers/s390/block/dcssblk.c
> +++ b/drivers/s390/block/dcssblk.c
> @@ -30,8 +30,8 @@ static int dcssblk_open(struct block_device *bdev, fmode_t mode);
>  static void dcssblk_release(struct gendisk *disk, fmode_t mode);
>  static blk_qc_t dcssblk_make_request(struct request_queue *q,
>  						struct bio *bio);
> -static long dcssblk_direct_access(struct block_device *bdev, sector_t secnum,
> -			 void __pmem **kaddr, pfn_t *pfn);
> +static long dcssblk_direct_access(struct block_device *bdev,
> +		struct blk_dax_ctl *dax)
>  
>  static char dcssblk_segments[DCSSBLK_PARM_LEN] = "\0";
>  
> @@ -882,9 +882,9 @@ fail:
>  }
>  
>  static long
> -dcssblk_direct_access (struct block_device *bdev, sector_t secnum,
> -			void __pmem **kaddr, pfn_t *pfn)
> +dcssblk_direct_access(struct block_device *bdev, struct blk_dax_ctl *dax)
>  {
> +	sector_t secnum = get_start_sect(bdev) + dax->sector;
>  	struct dcssblk_dev_info *dev_info;
>  	unsigned long offset, dev_sz;
>  
> @@ -893,8 +893,8 @@ dcssblk_direct_access (struct block_device *bdev, sector_t secnum,
>  		return -ENODEV;
>  	dev_sz = dev_info->end - dev_info->start;
>  	offset = secnum * 512;
> -	*kaddr = (void __pmem *) (dev_info->start + offset);
> -	*pfn = __pfn_to_pfn_t(PFN_DOWN(dev_info->start + offset), PFN_DEV);
> +	dax->addr = (void __pmem *) (dev_info->start + offset);
> +	dax->pfn = __pfn_to_pfn_t(PFN_DOWN(dev_info->start + offset), PFN_DEV);
>  
>  	return dev_sz - offset;
>  }
> diff --git a/fs/block_dev.c b/fs/block_dev.c
> index 3172c4e..c5837fa 100644
> --- a/fs/block_dev.c
> +++ b/fs/block_dev.c
> @@ -488,7 +488,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);
> +	avail = ops->direct_access(bdev, dax);
>  	if (!avail)
>  		return -ERANGE;
>  	if (avail > 0 && avail & ~PAGE_MASK)
> diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
> index 7e5d7e0..92f8a1f 100644
> --- a/include/linux/blkdev.h
> +++ b/include/linux/blkdev.h
> @@ -1656,8 +1656,7 @@ struct block_device_operations {
>  	int (*rw_page)(struct block_device *, sector_t, struct page *, int rw);
>  	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 __pmem **,
> -			pfn_t *);
> +	long (*direct_access)(struct block_device *, struct blk_dax_ctl *dax);
>  	unsigned int (*check_events) (struct gendisk *disk,
>  				      unsigned int clearing);
>  	/* ->media_changed() is DEPRECATED, use ->check_events() instead */
--
To unsubscribe from this list: send the line "unsubscribe linux-block" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c
index 0d112b9..d85673f 100644
--- a/arch/powerpc/sysdev/axonram.c
+++ b/arch/powerpc/sysdev/axonram.c
@@ -139,17 +139,17 @@  axon_ram_make_request(struct request_queue *queue, struct bio *bio)
 
 /**
  * axon_ram_direct_access - direct_access() method for block device
- * @device, @sector, @data: see block_device_operations method
+ * @dax: see block_device_operations method
  */
 static long
-axon_ram_direct_access(struct block_device *device, sector_t sector,
-		       void __pmem **kaddr, pfn_t *pfn)
+axon_ram_direct_access(struct block_device *device, struct blk_dax_ctl *dax)
 {
+	sector_t sector = get_start_sect(device) + dax->sector;
 	struct axon_ram_bank *bank = device->bd_disk->private_data;
 	loff_t offset = (loff_t)sector << AXON_RAM_SECTOR_SHIFT;
 
-	*kaddr = (void __pmem __force *) bank->io_addr + offset;
-	*pfn = phys_to_pfn_t(bank->ph_addr + offset, PFN_DEV);
+	dax->addr = (void __pmem __force *) bank->io_addr + offset;
+	dax->pfn = phys_to_pfn_t(bank->ph_addr + offset, PFN_DEV);
 	return bank->size - offset;
 }
 
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index f7ecc28..e3e4780 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -380,9 +380,10 @@  static int brd_rw_page(struct block_device *bdev, sector_t sector,
 }
 
 #ifdef CONFIG_BLK_DEV_RAM_DAX
-static long brd_direct_access(struct block_device *bdev, sector_t sector,
-			void __pmem **kaddr, pfn_t *pfn)
+static long brd_direct_access(struct block_device *bdev,
+		struct blk_dax_ctl *dax)
 {
+	sector_t sector = get_start_sect(bdev) + dax->sector;
 	struct brd_device *brd = bdev->bd_disk->private_data;
 	struct page *page;
 
@@ -391,8 +392,8 @@  static long brd_direct_access(struct block_device *bdev, sector_t sector,
 	page = brd_insert_page(brd, sector);
 	if (!page)
 		return -ENOSPC;
-	*kaddr = (void __pmem *)page_address(page);
-	*pfn = page_to_pfn_t(page);
+	dax->addr = (void __pmem *)page_address(page);
+	dax->pfn = page_to_pfn_t(page);
 
 	return PAGE_SIZE;
 }
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index ca5721c..da10554 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -167,14 +167,15 @@  static int pmem_rw_page(struct block_device *bdev, sector_t sector,
 	return rc;
 }
 
-static long pmem_direct_access(struct block_device *bdev, sector_t sector,
-		      void __pmem **kaddr, pfn_t *pfn)
+static long pmem_direct_access(struct block_device *bdev,
+		struct blk_dax_ctl *dax)
 {
+	sector_t sector = get_start_sect(bdev) + dax->sector;
 	struct pmem_device *pmem = bdev->bd_disk->private_data;
 	resource_size_t offset = sector * 512 + pmem->data_offset;
 
-	*kaddr = pmem->virt_addr + offset;
-	*pfn = phys_to_pfn_t(pmem->phys_addr + offset, pmem->pfn_flags);
+	dax->addr = pmem->virt_addr + offset;
+	dax->pfn = phys_to_pfn_t(pmem->phys_addr + offset, pmem->pfn_flags);
 
 	return pmem->size - pmem->pfn_pad - offset;
 }
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index 1bce9cf..5719c30 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -30,8 +30,8 @@  static int dcssblk_open(struct block_device *bdev, fmode_t mode);
 static void dcssblk_release(struct gendisk *disk, fmode_t mode);
 static blk_qc_t dcssblk_make_request(struct request_queue *q,
 						struct bio *bio);
-static long dcssblk_direct_access(struct block_device *bdev, sector_t secnum,
-			 void __pmem **kaddr, pfn_t *pfn);
+static long dcssblk_direct_access(struct block_device *bdev,
+		struct blk_dax_ctl *dax)
 
 static char dcssblk_segments[DCSSBLK_PARM_LEN] = "\0";
 
@@ -882,9 +882,9 @@  fail:
 }
 
 static long
-dcssblk_direct_access (struct block_device *bdev, sector_t secnum,
-			void __pmem **kaddr, pfn_t *pfn)
+dcssblk_direct_access(struct block_device *bdev, struct blk_dax_ctl *dax)
 {
+	sector_t secnum = get_start_sect(bdev) + dax->sector;
 	struct dcssblk_dev_info *dev_info;
 	unsigned long offset, dev_sz;
 
@@ -893,8 +893,8 @@  dcssblk_direct_access (struct block_device *bdev, sector_t secnum,
 		return -ENODEV;
 	dev_sz = dev_info->end - dev_info->start;
 	offset = secnum * 512;
-	*kaddr = (void __pmem *) (dev_info->start + offset);
-	*pfn = __pfn_to_pfn_t(PFN_DOWN(dev_info->start + offset), PFN_DEV);
+	dax->addr = (void __pmem *) (dev_info->start + offset);
+	dax->pfn = __pfn_to_pfn_t(PFN_DOWN(dev_info->start + offset), PFN_DEV);
 
 	return dev_sz - offset;
 }
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 3172c4e..c5837fa 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -488,7 +488,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);
+	avail = ops->direct_access(bdev, dax);
 	if (!avail)
 		return -ERANGE;
 	if (avail > 0 && avail & ~PAGE_MASK)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 7e5d7e0..92f8a1f 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1656,8 +1656,7 @@  struct block_device_operations {
 	int (*rw_page)(struct block_device *, sector_t, struct page *, int rw);
 	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 __pmem **,
-			pfn_t *);
+	long (*direct_access)(struct block_device *, struct blk_dax_ctl *dax);
 	unsigned int (*check_events) (struct gendisk *disk,
 				      unsigned int clearing);
 	/* ->media_changed() is DEPRECATED, use ->check_events() instead */