aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target/target_core_iblock.c
diff options
context:
space:
mode:
authorAndy Grover <agrover@redhat.com>2013-11-11 11:59:17 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2013-11-12 16:44:54 -0500
commit7f7caf6aa74a4f4ad21ebe08bf23b594fce45ca7 (patch)
tree058c55e859712486b9f6a8a20f3ea46add3a30eb /drivers/target/target_core_iblock.c
parentf01b9f73392b48c6cda7c2c66594c73137c776da (diff)
target: Pass through I/O topology for block backstores
In addition to block size (already implemented), passing through alignment offset, logical-to-phys block exponent, I/O granularity and optimal I/O length will allow initiators to properly handle layout on LUNs with 4K block sizes. Tested with various weird values via scsi_debug module. One thing to look at with this patch is the new block limits values -- instead of granularity 1 optimal 8192, Lio will now be returning whatever the block device says, which may affect performance. Signed-off-by: Andy Grover <agrover@redhat.com> Acked-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/target_core_iblock.c')
-rw-r--r--drivers/target/target_core_iblock.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index b9a3394fe479..c87959f12760 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -710,6 +710,45 @@ static sector_t iblock_get_blocks(struct se_device *dev)
710 return iblock_emulate_read_cap_with_block_size(dev, bd, q); 710 return iblock_emulate_read_cap_with_block_size(dev, bd, q);
711} 711}
712 712
713static sector_t iblock_get_alignment_offset_lbas(struct se_device *dev)
714{
715 struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
716 struct block_device *bd = ib_dev->ibd_bd;
717 int ret;
718
719 ret = bdev_alignment_offset(bd);
720 if (ret == -1)
721 return 0;
722
723 /* convert offset-bytes to offset-lbas */
724 return ret / bdev_logical_block_size(bd);
725}
726
727static unsigned int iblock_get_lbppbe(struct se_device *dev)
728{
729 struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
730 struct block_device *bd = ib_dev->ibd_bd;
731 int logs_per_phys = bdev_physical_block_size(bd) / bdev_logical_block_size(bd);
732
733 return ilog2(logs_per_phys);
734}
735
736static unsigned int iblock_get_io_min(struct se_device *dev)
737{
738 struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
739 struct block_device *bd = ib_dev->ibd_bd;
740
741 return bdev_io_min(bd);
742}
743
744static unsigned int iblock_get_io_opt(struct se_device *dev)
745{
746 struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
747 struct block_device *bd = ib_dev->ibd_bd;
748
749 return bdev_io_opt(bd);
750}
751
713static struct sbc_ops iblock_sbc_ops = { 752static struct sbc_ops iblock_sbc_ops = {
714 .execute_rw = iblock_execute_rw, 753 .execute_rw = iblock_execute_rw,
715 .execute_sync_cache = iblock_execute_sync_cache, 754 .execute_sync_cache = iblock_execute_sync_cache,
@@ -749,6 +788,10 @@ static struct se_subsystem_api iblock_template = {
749 .show_configfs_dev_params = iblock_show_configfs_dev_params, 788 .show_configfs_dev_params = iblock_show_configfs_dev_params,
750 .get_device_type = sbc_get_device_type, 789 .get_device_type = sbc_get_device_type,
751 .get_blocks = iblock_get_blocks, 790 .get_blocks = iblock_get_blocks,
791 .get_alignment_offset_lbas = iblock_get_alignment_offset_lbas,
792 .get_lbppbe = iblock_get_lbppbe,
793 .get_io_min = iblock_get_io_min,
794 .get_io_opt = iblock_get_io_opt,
752 .get_write_cache = iblock_get_write_cache, 795 .get_write_cache = iblock_get_write_cache,
753}; 796};
754 797