diff mbox

[1/2] dax: fix O_DIRECT I/O to the last block of a blockdev

Message ID 1439583332-13754-2-git-send-email-jmoyer@redhat.com (mailing list archive)
State Superseded
Headers show

Commit Message

Jeff Moyer Aug. 14, 2015, 8:15 p.m. UTC
commit bbab37ddc20b (block: Add support for DAX reads/writes to
block devices) caused a regression in mkfs.xfs.  That utility
sets the block size of the device to the logical block size
using the BLKBSZSET ioctl, and then issues a single sector read
from the last sector of the device.  This results in the dax_io
code trying to do a page-sized read from 512 bytes from the end
of the device.  The result is -ERANGE being returned to userspace.

The fix is to align the block to the page size before calling
get_block.

Thanks to willy for simplifying my original patch.

Signed-off-by: Jeff Moyer <jmoyer@redhat.com>
---
 fs/dax.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Linda Knippers Aug. 14, 2015, 8:53 p.m. UTC | #1
On 8/14/2015 4:15 PM, Jeff Moyer wrote:
> commit bbab37ddc20b (block: Add support for DAX reads/writes to
> block devices) caused a regression in mkfs.xfs.  That utility
> sets the block size of the device to the logical block size
> using the BLKBSZSET ioctl, and then issues a single sector read
> from the last sector of the device.  This results in the dax_io
> code trying to do a page-sized read from 512 bytes from the end
> of the device.  The result is -ERANGE being returned to userspace.
> 
> The fix is to align the block to the page size before calling
> get_block.
> 
> Thanks to willy for simplifying my original patch.
> 
> Signed-off-by: Jeff Moyer <jmoyer@redhat.com>

Tested-by:  Linda Knippers <linda.knippers@hp.com>

> ---
>  fs/dax.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/dax.c b/fs/dax.c
> index a7f77e1..ef35a20 100644
> --- a/fs/dax.c
> +++ b/fs/dax.c
> @@ -116,7 +116,8 @@ static ssize_t dax_io(struct inode *inode, struct iov_iter *iter,
>  		unsigned len;
>  		if (pos == max) {
>  			unsigned blkbits = inode->i_blkbits;
> -			sector_t block = pos >> blkbits;
> +			long page = pos >> PAGE_SHIFT;
> +			sector_t block = page << (PAGE_SHIFT - blkbits);
>  			unsigned first = pos - (block << blkbits);
>  			long size;
>  
>
Linda Knippers Sept. 8, 2015, 4:10 p.m. UTC | #2
This patch and the 2/2 patch don't seem to have gone anywhere.
Willy?  or Ross?

-- ljk

On 8/14/2015 4:53 PM, Linda Knippers wrote:
> On 8/14/2015 4:15 PM, Jeff Moyer wrote:
>> commit bbab37ddc20b (block: Add support for DAX reads/writes to
>> block devices) caused a regression in mkfs.xfs.  That utility
>> sets the block size of the device to the logical block size
>> using the BLKBSZSET ioctl, and then issues a single sector read
>> from the last sector of the device.  This results in the dax_io
>> code trying to do a page-sized read from 512 bytes from the end
>> of the device.  The result is -ERANGE being returned to userspace.
>>
>> The fix is to align the block to the page size before calling
>> get_block.
>>
>> Thanks to willy for simplifying my original patch.
>>
>> Signed-off-by: Jeff Moyer <jmoyer@redhat.com>
> 
> Tested-by:  Linda Knippers <linda.knippers@hp.com>
> 
>> ---
>>  fs/dax.c | 3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/fs/dax.c b/fs/dax.c
>> index a7f77e1..ef35a20 100644
>> --- a/fs/dax.c
>> +++ b/fs/dax.c
>> @@ -116,7 +116,8 @@ static ssize_t dax_io(struct inode *inode, struct iov_iter *iter,
>>  		unsigned len;
>>  		if (pos == max) {
>>  			unsigned blkbits = inode->i_blkbits;
>> -			sector_t block = pos >> blkbits;
>> +			long page = pos >> PAGE_SHIFT;
>> +			sector_t block = page << (PAGE_SHIFT - blkbits);
>>  			unsigned first = pos - (block << blkbits);
>>  			long size;
>>  
>>
>
Dan Williams Sept. 8, 2015, 4:23 p.m. UTC | #3
On Tue, Sep 8, 2015 at 9:10 AM, Linda Knippers <linda.knippers@hpe.com> wrote:
> This patch and the 2/2 patch don't seem to have gone anywhere.
> Willy?  or Ross?
>

Yes, these should have gone into 4.2, The nvdimm.git tree will pick
them up after 4.3-rc1 and tag them for -stable.
diff mbox

Patch

diff --git a/fs/dax.c b/fs/dax.c
index a7f77e1..ef35a20 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -116,7 +116,8 @@  static ssize_t dax_io(struct inode *inode, struct iov_iter *iter,
 		unsigned len;
 		if (pos == max) {
 			unsigned blkbits = inode->i_blkbits;
-			sector_t block = pos >> blkbits;
+			long page = pos >> PAGE_SHIFT;
+			sector_t block = page << (PAGE_SHIFT - blkbits);
 			unsigned first = pos - (block << blkbits);
 			long size;