diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-05-29 21:35:23 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-06-07 12:53:36 -0700 |
commit | 0813b7c39d5d046feb9e7a632abd09aaafae056e (patch) | |
tree | aa9f7a9cb03ef26357bd3647c4d14004815f0ea6 | |
parent | befb0ab8d1a9f51fb1682aaec9f0ab0eb23228e8 (diff) |
target/file: Fix off-by-one READ_CAPACITY bug for !S_ISBLK export
commit 21363ca873334391992f2f424856aa864345bb61 upstream.
This patch fixes a bug where FILEIO was incorrectly reporting the number
of logical blocks (+ 1) when using non struct block_device export mode.
It changes fd_get_blocks() to follow all other backend ->get_blocks() cases,
and reduces the calculated dev_size by one dev->dev_attrib.block_size
number of bytes, and also fixes initial fd_block_size assignment at
fd_configure_device() time introduced in commit 0fd97ccf4.
Reported-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
Reported-by: Badari Pulavarty <pbadari@us.ibm.com>
Tested-by: Badari Pulavarty <pbadari@us.ibm.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Signed-off-by: Lingzhu Xiang <lxiang@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/target/target_core_file.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index ca4b2193e05c..12191d825d78 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -150,6 +150,7 @@ static int fd_configure_device(struct se_device *dev) if (S_ISBLK(inode->i_mode)) { unsigned long long dev_size; + fd_dev->fd_block_size = bdev_logical_block_size(inode->i_bdev); /* * Determine the number of bytes from i_size_read() minus * one (1) logical sector from underlying struct block_device @@ -168,11 +169,11 @@ static int fd_configure_device(struct se_device *dev) " block_device\n"); goto fail; } - } - fd_dev->fd_block_size = dev->dev_attrib.hw_block_size; + fd_dev->fd_block_size = FD_BLOCKSIZE; + } - dev->dev_attrib.hw_block_size = FD_BLOCKSIZE; + dev->dev_attrib.hw_block_size = fd_dev->fd_block_size; dev->dev_attrib.hw_max_sectors = FD_MAX_SECTORS; dev->dev_attrib.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH; @@ -583,11 +584,12 @@ static sector_t fd_get_blocks(struct se_device *dev) * to handle underlying block_device resize operations. */ if (S_ISBLK(i->i_mode)) - dev_size = (i_size_read(i) - fd_dev->fd_block_size); + dev_size = i_size_read(i); else dev_size = fd_dev->fd_dev_size; - return div_u64(dev_size, dev->dev_attrib.block_size); + return div_u64(dev_size - dev->dev_attrib.block_size, + dev->dev_attrib.block_size); } static struct sbc_ops fd_sbc_ops = { |