Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

target: Fix WRITE_SAME/DISCARD conversion to linux 512b sectors

In a couple places we are not converting to/from the Linux
block layer 512 bytes sectors.

1.

The request queue values and what we do are a mismatch of
things:

max_discard_sectors - This is in linux block layer 512 byte
sectors. We are just copying this to max_unmap_lba_count.

discard_granularity - This is in bytes. We are converting it
to Linux block layer 512 byte sectors.

discard_alignment - This is in bytes. We are just copying
this over.

The problem is that the core LIO code exports these values in
spc_emulate_evpd_b0 and we use them to test request arguments
in sbc_execute_unmap, but we never convert to the block size
we export to the initiator. If we are not using 512 byte sectors
then we are exporting the wrong values or are checks are off.
And, for the discard_alignment/bytes case we are just plain messed
up.

2.

blkdev_issue_discard's start and number of sector arguments
are supposed to be in linux block layer 512 byte sectors. We are
currently passing in the values we get from the initiator which
might be based on some other sector size.

There is a similar problem in iblock_execute_write_same where
the bio functions want values in 512 byte sectors but we are
passing in what we got from the initiator.

Signed-off-by: Mike Christie <mchristi@redhat.com>
Cc: stable@vger.kernel.org # 3.10+
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>

authored by

Mike Christie and committed by
Nicholas Bellinger
8a9ebe71 92e963f5

+70 -64
+44
drivers/target/target_core_device.c
··· 828 828 return dev; 829 829 } 830 830 831 + /* 832 + * Check if the underlying struct block_device request_queue supports 833 + * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM 834 + * in ATA and we need to set TPE=1 835 + */ 836 + bool target_configure_unmap_from_queue(struct se_dev_attrib *attrib, 837 + struct request_queue *q, int block_size) 838 + { 839 + if (!blk_queue_discard(q)) 840 + return false; 841 + 842 + attrib->max_unmap_lba_count = (q->limits.max_discard_sectors << 9) / 843 + block_size; 844 + /* 845 + * Currently hardcoded to 1 in Linux/SCSI code.. 846 + */ 847 + attrib->max_unmap_block_desc_count = 1; 848 + attrib->unmap_granularity = q->limits.discard_granularity / block_size; 849 + attrib->unmap_granularity_alignment = q->limits.discard_alignment / 850 + block_size; 851 + attrib->unmap_zeroes_data = q->limits.discard_zeroes_data; 852 + return true; 853 + } 854 + EXPORT_SYMBOL(target_configure_unmap_from_queue); 855 + 856 + /* 857 + * Convert from blocksize advertised to the initiator to the 512 byte 858 + * units unconditionally used by the Linux block layer. 859 + */ 860 + sector_t target_to_linux_sector(struct se_device *dev, sector_t lb) 861 + { 862 + switch (dev->dev_attrib.block_size) { 863 + case 4096: 864 + return lb << 3; 865 + case 2048: 866 + return lb << 2; 867 + case 1024: 868 + return lb << 1; 869 + default: 870 + return lb; 871 + } 872 + } 873 + EXPORT_SYMBOL(target_to_linux_sector); 874 + 831 875 int target_configure_device(struct se_device *dev) 832 876 { 833 877 struct se_hba *hba = dev->se_hba;
+9 -20
drivers/target/target_core_file.c
··· 160 160 " block_device blocks: %llu logical_block_size: %d\n", 161 161 dev_size, div_u64(dev_size, fd_dev->fd_block_size), 162 162 fd_dev->fd_block_size); 163 - /* 164 - * Check if the underlying struct block_device request_queue supports 165 - * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM 166 - * in ATA and we need to set TPE=1 167 - */ 168 - if (blk_queue_discard(q)) { 169 - dev->dev_attrib.max_unmap_lba_count = 170 - q->limits.max_discard_sectors; 171 - /* 172 - * Currently hardcoded to 1 in Linux/SCSI code.. 173 - */ 174 - dev->dev_attrib.max_unmap_block_desc_count = 1; 175 - dev->dev_attrib.unmap_granularity = 176 - q->limits.discard_granularity >> 9; 177 - dev->dev_attrib.unmap_granularity_alignment = 178 - q->limits.discard_alignment; 163 + 164 + if (target_configure_unmap_from_queue(&dev->dev_attrib, q, 165 + fd_dev->fd_block_size)) 179 166 pr_debug("IFILE: BLOCK Discard support available," 180 - " disabled by default\n"); 181 - } 167 + " disabled by default\n"); 182 168 /* 183 169 * Enable write same emulation for IBLOCK and use 0xFFFF as 184 170 * the smaller WRITE_SAME(10) only has a two-byte block count. ··· 476 490 if (S_ISBLK(inode->i_mode)) { 477 491 /* The backend is block device, use discard */ 478 492 struct block_device *bdev = inode->i_bdev; 493 + struct se_device *dev = cmd->se_dev; 479 494 480 - ret = blkdev_issue_discard(bdev, lba, 481 - nolb, GFP_KERNEL, 0); 495 + ret = blkdev_issue_discard(bdev, 496 + target_to_linux_sector(dev, lba), 497 + target_to_linux_sector(dev, nolb), 498 + GFP_KERNEL, 0); 482 499 if (ret < 0) { 483 500 pr_warn("FILEIO: blkdev_issue_discard() failed: %d\n", 484 501 ret);
+14 -44
drivers/target/target_core_iblock.c
··· 121 121 dev->dev_attrib.hw_max_sectors = queue_max_hw_sectors(q); 122 122 dev->dev_attrib.hw_queue_depth = q->nr_requests; 123 123 124 - /* 125 - * Check if the underlying struct block_device request_queue supports 126 - * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM 127 - * in ATA and we need to set TPE=1 128 - */ 129 - if (blk_queue_discard(q)) { 130 - dev->dev_attrib.max_unmap_lba_count = 131 - q->limits.max_discard_sectors; 132 - 133 - /* 134 - * Currently hardcoded to 1 in Linux/SCSI code.. 135 - */ 136 - dev->dev_attrib.max_unmap_block_desc_count = 1; 137 - dev->dev_attrib.unmap_granularity = 138 - q->limits.discard_granularity >> 9; 139 - dev->dev_attrib.unmap_granularity_alignment = 140 - q->limits.discard_alignment; 141 - dev->dev_attrib.unmap_zeroes_data = 142 - q->limits.discard_zeroes_data; 143 - 124 + if (target_configure_unmap_from_queue(&dev->dev_attrib, q, 125 + dev->dev_attrib.hw_block_size)) 144 126 pr_debug("IBLOCK: BLOCK Discard support available," 145 - " disabled by default\n"); 146 - } 127 + " disabled by default\n"); 128 + 147 129 /* 148 130 * Enable write same emulation for IBLOCK and use 0xFFFF as 149 131 * the smaller WRITE_SAME(10) only has a two-byte block count. ··· 397 415 iblock_execute_unmap(struct se_cmd *cmd, sector_t lba, sector_t nolb) 398 416 { 399 417 struct block_device *bdev = IBLOCK_DEV(cmd->se_dev)->ibd_bd; 418 + struct se_device *dev = cmd->se_dev; 400 419 int ret; 401 420 402 - ret = blkdev_issue_discard(bdev, lba, nolb, GFP_KERNEL, 0); 421 + ret = blkdev_issue_discard(bdev, 422 + target_to_linux_sector(dev, lba), 423 + target_to_linux_sector(dev, nolb), 424 + GFP_KERNEL, 0); 403 425 if (ret < 0) { 404 426 pr_err("blkdev_issue_discard() failed: %d\n", ret); 405 427 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; ··· 419 433 struct scatterlist *sg; 420 434 struct bio *bio; 421 435 struct bio_list list; 422 - sector_t block_lba = cmd->t_task_lba; 423 - sector_t sectors = sbc_get_write_same_sectors(cmd); 436 + struct se_device *dev = cmd->se_dev; 437 + sector_t block_lba = target_to_linux_sector(dev, cmd->t_task_lba); 438 + sector_t sectors = target_to_linux_sector(dev, 439 + sbc_get_write_same_sectors(cmd)); 424 440 425 441 if (cmd->prot_op) { 426 442 pr_err("WRITE_SAME: Protection information with IBLOCK" ··· 636 648 enum dma_data_direction data_direction) 637 649 { 638 650 struct se_device *dev = cmd->se_dev; 651 + sector_t block_lba = target_to_linux_sector(dev, cmd->t_task_lba); 639 652 struct iblock_req *ibr; 640 653 struct bio *bio, *bio_start; 641 654 struct bio_list list; 642 655 struct scatterlist *sg; 643 656 u32 sg_num = sgl_nents; 644 - sector_t block_lba; 645 657 unsigned bio_cnt; 646 658 int rw = 0; 647 659 int i; ··· 665 677 } 666 678 } else { 667 679 rw = READ; 668 - } 669 - 670 - /* 671 - * Convert the blocksize advertised to the initiator to the 512 byte 672 - * units unconditionally used by the Linux block layer. 673 - */ 674 - if (dev->dev_attrib.block_size == 4096) 675 - block_lba = (cmd->t_task_lba << 3); 676 - else if (dev->dev_attrib.block_size == 2048) 677 - block_lba = (cmd->t_task_lba << 2); 678 - else if (dev->dev_attrib.block_size == 1024) 679 - block_lba = (cmd->t_task_lba << 1); 680 - else if (dev->dev_attrib.block_size == 512) 681 - block_lba = cmd->t_task_lba; 682 - else { 683 - pr_err("Unsupported SCSI -> BLOCK LBA conversion:" 684 - " %u\n", dev->dev_attrib.block_size); 685 - return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 686 680 } 687 681 688 682 ibr = kzalloc(sizeof(struct iblock_req), GFP_KERNEL);
+3
include/target/target_core_backend.h
··· 94 94 sense_reason_t (*exec_cmd)(struct se_cmd *cmd)); 95 95 96 96 bool target_sense_desc_format(struct se_device *dev); 97 + sector_t target_to_linux_sector(struct se_device *dev, sector_t lb); 98 + bool target_configure_unmap_from_queue(struct se_dev_attrib *attrib, 99 + struct request_queue *q, int block_size); 97 100 98 101 #endif /* TARGET_CORE_BACKEND_H */