1c66ac9dbSNicholas Bellinger /******************************************************************************* 2c66ac9dbSNicholas Bellinger * Filename: target_core_iblock.c 3c66ac9dbSNicholas Bellinger * 4c66ac9dbSNicholas Bellinger * This file contains the Storage Engine <-> Linux BlockIO transport 5c66ac9dbSNicholas Bellinger * specific functions. 6c66ac9dbSNicholas Bellinger * 74c76251eSNicholas Bellinger * (c) Copyright 2003-2013 Datera, Inc. 8c66ac9dbSNicholas Bellinger * 9c66ac9dbSNicholas Bellinger * Nicholas A. Bellinger <nab@kernel.org> 10c66ac9dbSNicholas Bellinger * 11c66ac9dbSNicholas Bellinger * This program is free software; you can redistribute it and/or modify 12c66ac9dbSNicholas Bellinger * it under the terms of the GNU General Public License as published by 13c66ac9dbSNicholas Bellinger * the Free Software Foundation; either version 2 of the License, or 14c66ac9dbSNicholas Bellinger * (at your option) any later version. 15c66ac9dbSNicholas Bellinger * 16c66ac9dbSNicholas Bellinger * This program is distributed in the hope that it will be useful, 17c66ac9dbSNicholas Bellinger * but WITHOUT ANY WARRANTY; without even the implied warranty of 18c66ac9dbSNicholas Bellinger * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19c66ac9dbSNicholas Bellinger * GNU General Public License for more details. 20c66ac9dbSNicholas Bellinger * 21c66ac9dbSNicholas Bellinger * You should have received a copy of the GNU General Public License 22c66ac9dbSNicholas Bellinger * along with this program; if not, write to the Free Software 23c66ac9dbSNicholas Bellinger * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 24c66ac9dbSNicholas Bellinger * 25c66ac9dbSNicholas Bellinger ******************************************************************************/ 26c66ac9dbSNicholas Bellinger 27c66ac9dbSNicholas Bellinger #include <linux/string.h> 28c66ac9dbSNicholas Bellinger #include <linux/parser.h> 29c66ac9dbSNicholas Bellinger #include <linux/timer.h> 30c66ac9dbSNicholas Bellinger #include <linux/fs.h> 31c66ac9dbSNicholas Bellinger #include <linux/blkdev.h> 32c66ac9dbSNicholas Bellinger #include <linux/slab.h> 33c66ac9dbSNicholas Bellinger #include <linux/spinlock.h> 34c66ac9dbSNicholas Bellinger #include <linux/bio.h> 35c66ac9dbSNicholas Bellinger #include <linux/genhd.h> 36c66ac9dbSNicholas Bellinger #include <linux/file.h> 37827509e3SPaul Gortmaker #include <linux/module.h> 38c66ac9dbSNicholas Bellinger #include <scsi/scsi.h> 39c66ac9dbSNicholas Bellinger #include <scsi/scsi_host.h> 4014150a6bSChristoph Hellwig #include <asm/unaligned.h> 41c66ac9dbSNicholas Bellinger 42c66ac9dbSNicholas Bellinger #include <target/target_core_base.h> 43c4795fb2SChristoph Hellwig #include <target/target_core_backend.h> 44c66ac9dbSNicholas Bellinger 45c66ac9dbSNicholas Bellinger #include "target_core_iblock.h" 46c66ac9dbSNicholas Bellinger 47d5b4a21bSChristoph Hellwig #define IBLOCK_MAX_BIO_PER_TASK 32 /* max # of bios to submit at a time */ 48d5b4a21bSChristoph Hellwig #define IBLOCK_BIO_POOL_SIZE 128 49d5b4a21bSChristoph Hellwig 500fd97ccfSChristoph Hellwig static inline struct iblock_dev *IBLOCK_DEV(struct se_device *dev) 510fd97ccfSChristoph Hellwig { 520fd97ccfSChristoph Hellwig return container_of(dev, struct iblock_dev, dev); 530fd97ccfSChristoph Hellwig } 540fd97ccfSChristoph Hellwig 550fd97ccfSChristoph Hellwig 56c66ac9dbSNicholas Bellinger static struct se_subsystem_api iblock_template; 57c66ac9dbSNicholas Bellinger 58c66ac9dbSNicholas Bellinger /* iblock_attach_hba(): (Part of se_subsystem_api_t template) 59c66ac9dbSNicholas Bellinger * 60c66ac9dbSNicholas Bellinger * 61c66ac9dbSNicholas Bellinger */ 62c66ac9dbSNicholas Bellinger static int iblock_attach_hba(struct se_hba *hba, u32 host_id) 63c66ac9dbSNicholas Bellinger { 646708bb27SAndy Grover pr_debug("CORE_HBA[%d] - TCM iBlock HBA Driver %s on" 65c66ac9dbSNicholas Bellinger " Generic Target Core Stack %s\n", hba->hba_id, 66c66ac9dbSNicholas Bellinger IBLOCK_VERSION, TARGET_CORE_MOD_VERSION); 67c66ac9dbSNicholas Bellinger return 0; 68c66ac9dbSNicholas Bellinger } 69c66ac9dbSNicholas Bellinger 70c66ac9dbSNicholas Bellinger static void iblock_detach_hba(struct se_hba *hba) 71c66ac9dbSNicholas Bellinger { 72c66ac9dbSNicholas Bellinger } 73c66ac9dbSNicholas Bellinger 740fd97ccfSChristoph Hellwig static struct se_device *iblock_alloc_device(struct se_hba *hba, const char *name) 75c66ac9dbSNicholas Bellinger { 76c66ac9dbSNicholas Bellinger struct iblock_dev *ib_dev = NULL; 77c66ac9dbSNicholas Bellinger 78c66ac9dbSNicholas Bellinger ib_dev = kzalloc(sizeof(struct iblock_dev), GFP_KERNEL); 796708bb27SAndy Grover if (!ib_dev) { 806708bb27SAndy Grover pr_err("Unable to allocate struct iblock_dev\n"); 81c66ac9dbSNicholas Bellinger return NULL; 82c66ac9dbSNicholas Bellinger } 83c66ac9dbSNicholas Bellinger 846708bb27SAndy Grover pr_debug( "IBLOCK: Allocated ib_dev for %s\n", name); 85c66ac9dbSNicholas Bellinger 860fd97ccfSChristoph Hellwig return &ib_dev->dev; 87c66ac9dbSNicholas Bellinger } 88c66ac9dbSNicholas Bellinger 890fd97ccfSChristoph Hellwig static int iblock_configure_device(struct se_device *dev) 90c66ac9dbSNicholas Bellinger { 910fd97ccfSChristoph Hellwig struct iblock_dev *ib_dev = IBLOCK_DEV(dev); 92c66ac9dbSNicholas Bellinger struct request_queue *q; 930fd97ccfSChristoph Hellwig struct block_device *bd = NULL; 9444bfd018SAndy Grover fmode_t mode; 950fd97ccfSChristoph Hellwig int ret = -ENOMEM; 96c66ac9dbSNicholas Bellinger 970fd97ccfSChristoph Hellwig if (!(ib_dev->ibd_flags & IBDF_HAS_UDEV_PATH)) { 980fd97ccfSChristoph Hellwig pr_err("Missing udev_path= parameters for IBLOCK\n"); 990fd97ccfSChristoph Hellwig return -EINVAL; 100c66ac9dbSNicholas Bellinger } 101d5b4a21bSChristoph Hellwig 102d5b4a21bSChristoph Hellwig ib_dev->ibd_bio_set = bioset_create(IBLOCK_BIO_POOL_SIZE, 0); 1036708bb27SAndy Grover if (!ib_dev->ibd_bio_set) { 1040fd97ccfSChristoph Hellwig pr_err("IBLOCK: Unable to create bioset\n"); 1050fd97ccfSChristoph Hellwig goto out; 106c66ac9dbSNicholas Bellinger } 1070fd97ccfSChristoph Hellwig 1086708bb27SAndy Grover pr_debug( "IBLOCK: Claiming struct block_device: %s\n", 109c66ac9dbSNicholas Bellinger ib_dev->ibd_udev_path); 110c66ac9dbSNicholas Bellinger 11144bfd018SAndy Grover mode = FMODE_READ|FMODE_EXCL; 11244bfd018SAndy Grover if (!ib_dev->ibd_readonly) 11344bfd018SAndy Grover mode |= FMODE_WRITE; 11444bfd018SAndy Grover 11544bfd018SAndy Grover bd = blkdev_get_by_path(ib_dev->ibd_udev_path, mode, ib_dev); 116613640e4SNicholas Bellinger if (IS_ERR(bd)) { 117613640e4SNicholas Bellinger ret = PTR_ERR(bd); 1180fd97ccfSChristoph Hellwig goto out_free_bioset; 119613640e4SNicholas Bellinger } 120c66ac9dbSNicholas Bellinger ib_dev->ibd_bd = bd; 121c66ac9dbSNicholas Bellinger 1220fd97ccfSChristoph Hellwig q = bdev_get_queue(bd); 1230fd97ccfSChristoph Hellwig 1240fd97ccfSChristoph Hellwig dev->dev_attrib.hw_block_size = bdev_logical_block_size(bd); 1250fd97ccfSChristoph Hellwig dev->dev_attrib.hw_max_sectors = UINT_MAX; 1260fd97ccfSChristoph Hellwig dev->dev_attrib.hw_queue_depth = q->nr_requests; 127c66ac9dbSNicholas Bellinger 128c66ac9dbSNicholas Bellinger /* 129c66ac9dbSNicholas Bellinger * Check if the underlying struct block_device request_queue supports 130c66ac9dbSNicholas Bellinger * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM 131c66ac9dbSNicholas Bellinger * in ATA and we need to set TPE=1 132c66ac9dbSNicholas Bellinger */ 133613640e4SNicholas Bellinger if (blk_queue_discard(q)) { 1340fd97ccfSChristoph Hellwig dev->dev_attrib.max_unmap_lba_count = 135c66ac9dbSNicholas Bellinger q->limits.max_discard_sectors; 1360fd97ccfSChristoph Hellwig 137c66ac9dbSNicholas Bellinger /* 138c66ac9dbSNicholas Bellinger * Currently hardcoded to 1 in Linux/SCSI code.. 139c66ac9dbSNicholas Bellinger */ 1400fd97ccfSChristoph Hellwig dev->dev_attrib.max_unmap_block_desc_count = 1; 1410fd97ccfSChristoph Hellwig dev->dev_attrib.unmap_granularity = 1427347b5ffSMarco Sanvido q->limits.discard_granularity >> 9; 1430fd97ccfSChristoph Hellwig dev->dev_attrib.unmap_granularity_alignment = 144c66ac9dbSNicholas Bellinger q->limits.discard_alignment; 145c66ac9dbSNicholas Bellinger 1466708bb27SAndy Grover pr_debug("IBLOCK: BLOCK Discard support available," 147c66ac9dbSNicholas Bellinger " disabled by default\n"); 148c66ac9dbSNicholas Bellinger } 149f6970ad3SNicholas Bellinger /* 150f6970ad3SNicholas Bellinger * Enable write same emulation for IBLOCK and use 0xFFFF as 151f6970ad3SNicholas Bellinger * the smaller WRITE_SAME(10) only has a two-byte block count. 152f6970ad3SNicholas Bellinger */ 153f6970ad3SNicholas Bellinger dev->dev_attrib.max_write_same_len = 0xFFFF; 154c66ac9dbSNicholas Bellinger 155e22a7f07SRoland Dreier if (blk_queue_nonrot(q)) 1560fd97ccfSChristoph Hellwig dev->dev_attrib.is_nonrot = 1; 157d0c8b259SNicholas Bellinger 1580fd97ccfSChristoph Hellwig return 0; 159e22a7f07SRoland Dreier 1600fd97ccfSChristoph Hellwig out_free_bioset: 161c66ac9dbSNicholas Bellinger bioset_free(ib_dev->ibd_bio_set); 162c66ac9dbSNicholas Bellinger ib_dev->ibd_bio_set = NULL; 1630fd97ccfSChristoph Hellwig out: 1640fd97ccfSChristoph Hellwig return ret; 165c66ac9dbSNicholas Bellinger } 166c66ac9dbSNicholas Bellinger 1670fd97ccfSChristoph Hellwig static void iblock_free_device(struct se_device *dev) 168c66ac9dbSNicholas Bellinger { 1690fd97ccfSChristoph Hellwig struct iblock_dev *ib_dev = IBLOCK_DEV(dev); 170c66ac9dbSNicholas Bellinger 171bc665524SNicholas Bellinger if (ib_dev->ibd_bd != NULL) 172c66ac9dbSNicholas Bellinger blkdev_put(ib_dev->ibd_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL); 173bc665524SNicholas Bellinger if (ib_dev->ibd_bio_set != NULL) 174c66ac9dbSNicholas Bellinger bioset_free(ib_dev->ibd_bio_set); 175c66ac9dbSNicholas Bellinger kfree(ib_dev); 176c66ac9dbSNicholas Bellinger } 177c66ac9dbSNicholas Bellinger 178c66ac9dbSNicholas Bellinger static unsigned long long iblock_emulate_read_cap_with_block_size( 179c66ac9dbSNicholas Bellinger struct se_device *dev, 180c66ac9dbSNicholas Bellinger struct block_device *bd, 181c66ac9dbSNicholas Bellinger struct request_queue *q) 182c66ac9dbSNicholas Bellinger { 183c66ac9dbSNicholas Bellinger unsigned long long blocks_long = (div_u64(i_size_read(bd->bd_inode), 184c66ac9dbSNicholas Bellinger bdev_logical_block_size(bd)) - 1); 185c66ac9dbSNicholas Bellinger u32 block_size = bdev_logical_block_size(bd); 186c66ac9dbSNicholas Bellinger 1870fd97ccfSChristoph Hellwig if (block_size == dev->dev_attrib.block_size) 188c66ac9dbSNicholas Bellinger return blocks_long; 189c66ac9dbSNicholas Bellinger 190c66ac9dbSNicholas Bellinger switch (block_size) { 191c66ac9dbSNicholas Bellinger case 4096: 1920fd97ccfSChristoph Hellwig switch (dev->dev_attrib.block_size) { 193c66ac9dbSNicholas Bellinger case 2048: 194c66ac9dbSNicholas Bellinger blocks_long <<= 1; 195c66ac9dbSNicholas Bellinger break; 196c66ac9dbSNicholas Bellinger case 1024: 197c66ac9dbSNicholas Bellinger blocks_long <<= 2; 198c66ac9dbSNicholas Bellinger break; 199c66ac9dbSNicholas Bellinger case 512: 200c66ac9dbSNicholas Bellinger blocks_long <<= 3; 201c66ac9dbSNicholas Bellinger default: 202c66ac9dbSNicholas Bellinger break; 203c66ac9dbSNicholas Bellinger } 204c66ac9dbSNicholas Bellinger break; 205c66ac9dbSNicholas Bellinger case 2048: 2060fd97ccfSChristoph Hellwig switch (dev->dev_attrib.block_size) { 207c66ac9dbSNicholas Bellinger case 4096: 208c66ac9dbSNicholas Bellinger blocks_long >>= 1; 209c66ac9dbSNicholas Bellinger break; 210c66ac9dbSNicholas Bellinger case 1024: 211c66ac9dbSNicholas Bellinger blocks_long <<= 1; 212c66ac9dbSNicholas Bellinger break; 213c66ac9dbSNicholas Bellinger case 512: 214c66ac9dbSNicholas Bellinger blocks_long <<= 2; 215c66ac9dbSNicholas Bellinger break; 216c66ac9dbSNicholas Bellinger default: 217c66ac9dbSNicholas Bellinger break; 218c66ac9dbSNicholas Bellinger } 219c66ac9dbSNicholas Bellinger break; 220c66ac9dbSNicholas Bellinger case 1024: 2210fd97ccfSChristoph Hellwig switch (dev->dev_attrib.block_size) { 222c66ac9dbSNicholas Bellinger case 4096: 223c66ac9dbSNicholas Bellinger blocks_long >>= 2; 224c66ac9dbSNicholas Bellinger break; 225c66ac9dbSNicholas Bellinger case 2048: 226c66ac9dbSNicholas Bellinger blocks_long >>= 1; 227c66ac9dbSNicholas Bellinger break; 228c66ac9dbSNicholas Bellinger case 512: 229c66ac9dbSNicholas Bellinger blocks_long <<= 1; 230c66ac9dbSNicholas Bellinger break; 231c66ac9dbSNicholas Bellinger default: 232c66ac9dbSNicholas Bellinger break; 233c66ac9dbSNicholas Bellinger } 234c66ac9dbSNicholas Bellinger break; 235c66ac9dbSNicholas Bellinger case 512: 2360fd97ccfSChristoph Hellwig switch (dev->dev_attrib.block_size) { 237c66ac9dbSNicholas Bellinger case 4096: 238c66ac9dbSNicholas Bellinger blocks_long >>= 3; 239c66ac9dbSNicholas Bellinger break; 240c66ac9dbSNicholas Bellinger case 2048: 241c66ac9dbSNicholas Bellinger blocks_long >>= 2; 242c66ac9dbSNicholas Bellinger break; 243c66ac9dbSNicholas Bellinger case 1024: 244c66ac9dbSNicholas Bellinger blocks_long >>= 1; 245c66ac9dbSNicholas Bellinger break; 246c66ac9dbSNicholas Bellinger default: 247c66ac9dbSNicholas Bellinger break; 248c66ac9dbSNicholas Bellinger } 249c66ac9dbSNicholas Bellinger break; 250c66ac9dbSNicholas Bellinger default: 251c66ac9dbSNicholas Bellinger break; 252c66ac9dbSNicholas Bellinger } 253c66ac9dbSNicholas Bellinger 254c66ac9dbSNicholas Bellinger return blocks_long; 255c66ac9dbSNicholas Bellinger } 256c66ac9dbSNicholas Bellinger 2573a41d85fSNicholas Bellinger static void iblock_complete_cmd(struct se_cmd *cmd) 2583a41d85fSNicholas Bellinger { 2593a41d85fSNicholas Bellinger struct iblock_req *ibr = cmd->priv; 2603a41d85fSNicholas Bellinger u8 status; 2613a41d85fSNicholas Bellinger 2623a41d85fSNicholas Bellinger if (!atomic_dec_and_test(&ibr->pending)) 2633a41d85fSNicholas Bellinger return; 2643a41d85fSNicholas Bellinger 2653a41d85fSNicholas Bellinger if (atomic_read(&ibr->ib_bio_err_cnt)) 2663a41d85fSNicholas Bellinger status = SAM_STAT_CHECK_CONDITION; 2673a41d85fSNicholas Bellinger else 2683a41d85fSNicholas Bellinger status = SAM_STAT_GOOD; 2693a41d85fSNicholas Bellinger 2703a41d85fSNicholas Bellinger target_complete_cmd(cmd, status); 2713a41d85fSNicholas Bellinger kfree(ibr); 2723a41d85fSNicholas Bellinger } 2733a41d85fSNicholas Bellinger 2743a41d85fSNicholas Bellinger static void iblock_bio_done(struct bio *bio, int err) 2753a41d85fSNicholas Bellinger { 2763a41d85fSNicholas Bellinger struct se_cmd *cmd = bio->bi_private; 2773a41d85fSNicholas Bellinger struct iblock_req *ibr = cmd->priv; 2783a41d85fSNicholas Bellinger 2793a41d85fSNicholas Bellinger /* 2803a41d85fSNicholas Bellinger * Set -EIO if !BIO_UPTODATE and the passed is still err=0 2813a41d85fSNicholas Bellinger */ 2823a41d85fSNicholas Bellinger if (!test_bit(BIO_UPTODATE, &bio->bi_flags) && !err) 2833a41d85fSNicholas Bellinger err = -EIO; 2843a41d85fSNicholas Bellinger 2853a41d85fSNicholas Bellinger if (err != 0) { 2863a41d85fSNicholas Bellinger pr_err("test_bit(BIO_UPTODATE) failed for bio: %p," 2873a41d85fSNicholas Bellinger " err: %d\n", bio, err); 2883a41d85fSNicholas Bellinger /* 2893a41d85fSNicholas Bellinger * Bump the ib_bio_err_cnt and release bio. 2903a41d85fSNicholas Bellinger */ 2913a41d85fSNicholas Bellinger atomic_inc(&ibr->ib_bio_err_cnt); 2923a41d85fSNicholas Bellinger smp_mb__after_atomic_inc(); 2933a41d85fSNicholas Bellinger } 2943a41d85fSNicholas Bellinger 2953a41d85fSNicholas Bellinger bio_put(bio); 2963a41d85fSNicholas Bellinger 2973a41d85fSNicholas Bellinger iblock_complete_cmd(cmd); 2983a41d85fSNicholas Bellinger } 2993a41d85fSNicholas Bellinger 3003a41d85fSNicholas Bellinger static struct bio * 3013a41d85fSNicholas Bellinger iblock_get_bio(struct se_cmd *cmd, sector_t lba, u32 sg_num) 3023a41d85fSNicholas Bellinger { 3033a41d85fSNicholas Bellinger struct iblock_dev *ib_dev = IBLOCK_DEV(cmd->se_dev); 3043a41d85fSNicholas Bellinger struct bio *bio; 3053a41d85fSNicholas Bellinger 3063a41d85fSNicholas Bellinger /* 3073a41d85fSNicholas Bellinger * Only allocate as many vector entries as the bio code allows us to, 3083a41d85fSNicholas Bellinger * we'll loop later on until we have handled the whole request. 3093a41d85fSNicholas Bellinger */ 3103a41d85fSNicholas Bellinger if (sg_num > BIO_MAX_PAGES) 3113a41d85fSNicholas Bellinger sg_num = BIO_MAX_PAGES; 3123a41d85fSNicholas Bellinger 3133a41d85fSNicholas Bellinger bio = bio_alloc_bioset(GFP_NOIO, sg_num, ib_dev->ibd_bio_set); 3143a41d85fSNicholas Bellinger if (!bio) { 3153a41d85fSNicholas Bellinger pr_err("Unable to allocate memory for bio\n"); 3163a41d85fSNicholas Bellinger return NULL; 3173a41d85fSNicholas Bellinger } 3183a41d85fSNicholas Bellinger 3193a41d85fSNicholas Bellinger bio->bi_bdev = ib_dev->ibd_bd; 3203a41d85fSNicholas Bellinger bio->bi_private = cmd; 3213a41d85fSNicholas Bellinger bio->bi_end_io = &iblock_bio_done; 3223a41d85fSNicholas Bellinger bio->bi_sector = lba; 3233a41d85fSNicholas Bellinger 3243a41d85fSNicholas Bellinger return bio; 3253a41d85fSNicholas Bellinger } 3263a41d85fSNicholas Bellinger 3273a41d85fSNicholas Bellinger static void iblock_submit_bios(struct bio_list *list, int rw) 3283a41d85fSNicholas Bellinger { 3293a41d85fSNicholas Bellinger struct blk_plug plug; 3303a41d85fSNicholas Bellinger struct bio *bio; 3313a41d85fSNicholas Bellinger 3323a41d85fSNicholas Bellinger blk_start_plug(&plug); 3333a41d85fSNicholas Bellinger while ((bio = bio_list_pop(list))) 3343a41d85fSNicholas Bellinger submit_bio(rw, bio); 3353a41d85fSNicholas Bellinger blk_finish_plug(&plug); 3363a41d85fSNicholas Bellinger } 3373a41d85fSNicholas Bellinger 338df5fa691SChristoph Hellwig static void iblock_end_io_flush(struct bio *bio, int err) 339df5fa691SChristoph Hellwig { 340df5fa691SChristoph Hellwig struct se_cmd *cmd = bio->bi_private; 341df5fa691SChristoph Hellwig 342df5fa691SChristoph Hellwig if (err) 343df5fa691SChristoph Hellwig pr_err("IBLOCK: cache flush failed: %d\n", err); 344df5fa691SChristoph Hellwig 3455787cacdSChristoph Hellwig if (cmd) { 346de103c93SChristoph Hellwig if (err) 3475787cacdSChristoph Hellwig target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION); 348de103c93SChristoph Hellwig else 3495787cacdSChristoph Hellwig target_complete_cmd(cmd, SAM_STAT_GOOD); 3505787cacdSChristoph Hellwig } 3515787cacdSChristoph Hellwig 352df5fa691SChristoph Hellwig bio_put(bio); 353df5fa691SChristoph Hellwig } 354df5fa691SChristoph Hellwig 355c66ac9dbSNicholas Bellinger /* 356df5fa691SChristoph Hellwig * Implement SYCHRONIZE CACHE. Note that we can't handle lba ranges and must 357df5fa691SChristoph Hellwig * always flush the whole cache. 358c66ac9dbSNicholas Bellinger */ 359de103c93SChristoph Hellwig static sense_reason_t 360de103c93SChristoph Hellwig iblock_execute_sync_cache(struct se_cmd *cmd) 361c66ac9dbSNicholas Bellinger { 3620fd97ccfSChristoph Hellwig struct iblock_dev *ib_dev = IBLOCK_DEV(cmd->se_dev); 363a1d8b49aSAndy Grover int immed = (cmd->t_task_cdb[1] & 0x2); 364df5fa691SChristoph Hellwig struct bio *bio; 365c66ac9dbSNicholas Bellinger 366c66ac9dbSNicholas Bellinger /* 367c66ac9dbSNicholas Bellinger * If the Immediate bit is set, queue up the GOOD response 368df5fa691SChristoph Hellwig * for this SYNCHRONIZE_CACHE op. 369c66ac9dbSNicholas Bellinger */ 370c66ac9dbSNicholas Bellinger if (immed) 3715787cacdSChristoph Hellwig target_complete_cmd(cmd, SAM_STAT_GOOD); 372c66ac9dbSNicholas Bellinger 373df5fa691SChristoph Hellwig bio = bio_alloc(GFP_KERNEL, 0); 374df5fa691SChristoph Hellwig bio->bi_end_io = iblock_end_io_flush; 375df5fa691SChristoph Hellwig bio->bi_bdev = ib_dev->ibd_bd; 376c66ac9dbSNicholas Bellinger if (!immed) 377df5fa691SChristoph Hellwig bio->bi_private = cmd; 378df5fa691SChristoph Hellwig submit_bio(WRITE_FLUSH, bio); 379ad67f0d9SChristoph Hellwig return 0; 380c66ac9dbSNicholas Bellinger } 381c66ac9dbSNicholas Bellinger 382de103c93SChristoph Hellwig static sense_reason_t 38386d71829SAsias He iblock_do_unmap(struct se_cmd *cmd, void *priv, 384dbc21c5aSAsias He sector_t lba, sector_t nolb) 385dbc21c5aSAsias He { 38686d71829SAsias He struct block_device *bdev = priv; 387dbc21c5aSAsias He int ret; 388dbc21c5aSAsias He 389dbc21c5aSAsias He ret = blkdev_issue_discard(bdev, lba, nolb, GFP_KERNEL, 0); 390dbc21c5aSAsias He if (ret < 0) { 391dbc21c5aSAsias He pr_err("blkdev_issue_discard() failed: %d\n", ret); 392dbc21c5aSAsias He return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 393dbc21c5aSAsias He } 394dbc21c5aSAsias He 395dbc21c5aSAsias He return 0; 396dbc21c5aSAsias He } 397dbc21c5aSAsias He 398dbc21c5aSAsias He static sense_reason_t 399de103c93SChristoph Hellwig iblock_execute_unmap(struct se_cmd *cmd) 400c66ac9dbSNicholas Bellinger { 40186d71829SAsias He struct block_device *bdev = IBLOCK_DEV(cmd->se_dev)->ibd_bd; 40214150a6bSChristoph Hellwig 40386d71829SAsias He return sbc_execute_unmap(cmd, iblock_do_unmap, bdev); 404c66ac9dbSNicholas Bellinger } 405c66ac9dbSNicholas Bellinger 406de103c93SChristoph Hellwig static sense_reason_t 407f6970ad3SNicholas Bellinger iblock_execute_write_same_unmap(struct se_cmd *cmd) 4086f974e8cSChristoph Hellwig { 409dbc21c5aSAsias He struct block_device *bdev = IBLOCK_DEV(cmd->se_dev)->ibd_bd; 410dbc21c5aSAsias He sector_t lba = cmd->t_task_lba; 411dbc21c5aSAsias He sector_t nolb = sbc_get_write_same_sectors(cmd); 412dbc21c5aSAsias He int ret; 4136f974e8cSChristoph Hellwig 414dbc21c5aSAsias He ret = iblock_do_unmap(cmd, bdev, lba, nolb); 415dbc21c5aSAsias He if (ret) 416dbc21c5aSAsias He return ret; 4176f974e8cSChristoph Hellwig 4186f974e8cSChristoph Hellwig target_complete_cmd(cmd, GOOD); 4196f974e8cSChristoph Hellwig return 0; 4206f974e8cSChristoph Hellwig } 4216f974e8cSChristoph Hellwig 422f6970ad3SNicholas Bellinger static sense_reason_t 423f6970ad3SNicholas Bellinger iblock_execute_write_same(struct se_cmd *cmd) 424f6970ad3SNicholas Bellinger { 425f6970ad3SNicholas Bellinger struct iblock_req *ibr; 426f6970ad3SNicholas Bellinger struct scatterlist *sg; 427f6970ad3SNicholas Bellinger struct bio *bio; 428f6970ad3SNicholas Bellinger struct bio_list list; 429f6970ad3SNicholas Bellinger sector_t block_lba = cmd->t_task_lba; 430972b29c8SRoland Dreier sector_t sectors = sbc_get_write_same_sectors(cmd); 431f6970ad3SNicholas Bellinger 432f6970ad3SNicholas Bellinger sg = &cmd->t_data_sg[0]; 433f6970ad3SNicholas Bellinger 434f6970ad3SNicholas Bellinger if (cmd->t_data_nents > 1 || 435f6970ad3SNicholas Bellinger sg->length != cmd->se_dev->dev_attrib.block_size) { 436f6970ad3SNicholas Bellinger pr_err("WRITE_SAME: Illegal SGL t_data_nents: %u length: %u" 437f6970ad3SNicholas Bellinger " block_size: %u\n", cmd->t_data_nents, sg->length, 438f6970ad3SNicholas Bellinger cmd->se_dev->dev_attrib.block_size); 439f6970ad3SNicholas Bellinger return TCM_INVALID_CDB_FIELD; 440f6970ad3SNicholas Bellinger } 441f6970ad3SNicholas Bellinger 442f6970ad3SNicholas Bellinger ibr = kzalloc(sizeof(struct iblock_req), GFP_KERNEL); 443f6970ad3SNicholas Bellinger if (!ibr) 444f6970ad3SNicholas Bellinger goto fail; 445f6970ad3SNicholas Bellinger cmd->priv = ibr; 446f6970ad3SNicholas Bellinger 447f6970ad3SNicholas Bellinger bio = iblock_get_bio(cmd, block_lba, 1); 448f6970ad3SNicholas Bellinger if (!bio) 449f6970ad3SNicholas Bellinger goto fail_free_ibr; 450f6970ad3SNicholas Bellinger 451f6970ad3SNicholas Bellinger bio_list_init(&list); 452f6970ad3SNicholas Bellinger bio_list_add(&list, bio); 453f6970ad3SNicholas Bellinger 454f6970ad3SNicholas Bellinger atomic_set(&ibr->pending, 1); 455f6970ad3SNicholas Bellinger 456f6970ad3SNicholas Bellinger while (sectors) { 457f6970ad3SNicholas Bellinger while (bio_add_page(bio, sg_page(sg), sg->length, sg->offset) 458f6970ad3SNicholas Bellinger != sg->length) { 459f6970ad3SNicholas Bellinger 460f6970ad3SNicholas Bellinger bio = iblock_get_bio(cmd, block_lba, 1); 461f6970ad3SNicholas Bellinger if (!bio) 462f6970ad3SNicholas Bellinger goto fail_put_bios; 463f6970ad3SNicholas Bellinger 464f6970ad3SNicholas Bellinger atomic_inc(&ibr->pending); 465f6970ad3SNicholas Bellinger bio_list_add(&list, bio); 466f6970ad3SNicholas Bellinger } 467f6970ad3SNicholas Bellinger 468f6970ad3SNicholas Bellinger /* Always in 512 byte units for Linux/Block */ 469f6970ad3SNicholas Bellinger block_lba += sg->length >> IBLOCK_LBA_SHIFT; 470f6970ad3SNicholas Bellinger sectors -= 1; 471f6970ad3SNicholas Bellinger } 472f6970ad3SNicholas Bellinger 473f6970ad3SNicholas Bellinger iblock_submit_bios(&list, WRITE); 474f6970ad3SNicholas Bellinger return 0; 475f6970ad3SNicholas Bellinger 476f6970ad3SNicholas Bellinger fail_put_bios: 477f6970ad3SNicholas Bellinger while ((bio = bio_list_pop(&list))) 478f6970ad3SNicholas Bellinger bio_put(bio); 479f6970ad3SNicholas Bellinger fail_free_ibr: 480f6970ad3SNicholas Bellinger kfree(ibr); 481f6970ad3SNicholas Bellinger fail: 482f6970ad3SNicholas Bellinger return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 483f6970ad3SNicholas Bellinger } 484f6970ad3SNicholas Bellinger 485c66ac9dbSNicholas Bellinger enum { 48644bfd018SAndy Grover Opt_udev_path, Opt_readonly, Opt_force, Opt_err 487c66ac9dbSNicholas Bellinger }; 488c66ac9dbSNicholas Bellinger 489c66ac9dbSNicholas Bellinger static match_table_t tokens = { 490c66ac9dbSNicholas Bellinger {Opt_udev_path, "udev_path=%s"}, 49144bfd018SAndy Grover {Opt_readonly, "readonly=%d"}, 492c66ac9dbSNicholas Bellinger {Opt_force, "force=%d"}, 493c66ac9dbSNicholas Bellinger {Opt_err, NULL} 494c66ac9dbSNicholas Bellinger }; 495c66ac9dbSNicholas Bellinger 4960fd97ccfSChristoph Hellwig static ssize_t iblock_set_configfs_dev_params(struct se_device *dev, 497c66ac9dbSNicholas Bellinger const char *page, ssize_t count) 498c66ac9dbSNicholas Bellinger { 4990fd97ccfSChristoph Hellwig struct iblock_dev *ib_dev = IBLOCK_DEV(dev); 5006d180253SJesper Juhl char *orig, *ptr, *arg_p, *opts; 501c66ac9dbSNicholas Bellinger substring_t args[MAX_OPT_ARGS]; 50221bca31cSRoland Dreier int ret = 0, token; 50344bfd018SAndy Grover unsigned long tmp_readonly; 504c66ac9dbSNicholas Bellinger 505c66ac9dbSNicholas Bellinger opts = kstrdup(page, GFP_KERNEL); 506c66ac9dbSNicholas Bellinger if (!opts) 507c66ac9dbSNicholas Bellinger return -ENOMEM; 508c66ac9dbSNicholas Bellinger 509c66ac9dbSNicholas Bellinger orig = opts; 510c66ac9dbSNicholas Bellinger 51190c161b6SSebastian Andrzej Siewior while ((ptr = strsep(&opts, ",\n")) != NULL) { 512c66ac9dbSNicholas Bellinger if (!*ptr) 513c66ac9dbSNicholas Bellinger continue; 514c66ac9dbSNicholas Bellinger 515c66ac9dbSNicholas Bellinger token = match_token(ptr, tokens, args); 516c66ac9dbSNicholas Bellinger switch (token) { 517c66ac9dbSNicholas Bellinger case Opt_udev_path: 518c66ac9dbSNicholas Bellinger if (ib_dev->ibd_bd) { 5196708bb27SAndy Grover pr_err("Unable to set udev_path= while" 520c66ac9dbSNicholas Bellinger " ib_dev->ibd_bd exists\n"); 521c66ac9dbSNicholas Bellinger ret = -EEXIST; 522c66ac9dbSNicholas Bellinger goto out; 523c66ac9dbSNicholas Bellinger } 524852b6ed1SNicholas Bellinger if (match_strlcpy(ib_dev->ibd_udev_path, &args[0], 525852b6ed1SNicholas Bellinger SE_UDEV_PATH_LEN) == 0) { 526852b6ed1SNicholas Bellinger ret = -EINVAL; 5276d180253SJesper Juhl break; 5286d180253SJesper Juhl } 5296708bb27SAndy Grover pr_debug("IBLOCK: Referencing UDEV path: %s\n", 530c66ac9dbSNicholas Bellinger ib_dev->ibd_udev_path); 531c66ac9dbSNicholas Bellinger ib_dev->ibd_flags |= IBDF_HAS_UDEV_PATH; 532c66ac9dbSNicholas Bellinger break; 53344bfd018SAndy Grover case Opt_readonly: 53444bfd018SAndy Grover arg_p = match_strdup(&args[0]); 53544bfd018SAndy Grover if (!arg_p) { 53644bfd018SAndy Grover ret = -ENOMEM; 53744bfd018SAndy Grover break; 53844bfd018SAndy Grover } 53957103d7fSJingoo Han ret = kstrtoul(arg_p, 0, &tmp_readonly); 54044bfd018SAndy Grover kfree(arg_p); 54144bfd018SAndy Grover if (ret < 0) { 54257103d7fSJingoo Han pr_err("kstrtoul() failed for" 54344bfd018SAndy Grover " readonly=\n"); 54444bfd018SAndy Grover goto out; 54544bfd018SAndy Grover } 54644bfd018SAndy Grover ib_dev->ibd_readonly = tmp_readonly; 54744bfd018SAndy Grover pr_debug("IBLOCK: readonly: %d\n", ib_dev->ibd_readonly); 54844bfd018SAndy Grover break; 549c66ac9dbSNicholas Bellinger case Opt_force: 550c66ac9dbSNicholas Bellinger break; 551c66ac9dbSNicholas Bellinger default: 552c66ac9dbSNicholas Bellinger break; 553c66ac9dbSNicholas Bellinger } 554c66ac9dbSNicholas Bellinger } 555c66ac9dbSNicholas Bellinger 556c66ac9dbSNicholas Bellinger out: 557c66ac9dbSNicholas Bellinger kfree(orig); 558c66ac9dbSNicholas Bellinger return (!ret) ? count : ret; 559c66ac9dbSNicholas Bellinger } 560c66ac9dbSNicholas Bellinger 5610fd97ccfSChristoph Hellwig static ssize_t iblock_show_configfs_dev_params(struct se_device *dev, char *b) 562c66ac9dbSNicholas Bellinger { 5630fd97ccfSChristoph Hellwig struct iblock_dev *ib_dev = IBLOCK_DEV(dev); 5640fd97ccfSChristoph Hellwig struct block_device *bd = ib_dev->ibd_bd; 565c66ac9dbSNicholas Bellinger char buf[BDEVNAME_SIZE]; 566c66ac9dbSNicholas Bellinger ssize_t bl = 0; 567c66ac9dbSNicholas Bellinger 568c66ac9dbSNicholas Bellinger if (bd) 569c66ac9dbSNicholas Bellinger bl += sprintf(b + bl, "iBlock device: %s", 570c66ac9dbSNicholas Bellinger bdevname(bd, buf)); 5710fd97ccfSChristoph Hellwig if (ib_dev->ibd_flags & IBDF_HAS_UDEV_PATH) 57244bfd018SAndy Grover bl += sprintf(b + bl, " UDEV PATH: %s", 5730fd97ccfSChristoph Hellwig ib_dev->ibd_udev_path); 5740fd97ccfSChristoph Hellwig bl += sprintf(b + bl, " readonly: %d\n", ib_dev->ibd_readonly); 575c66ac9dbSNicholas Bellinger 576c66ac9dbSNicholas Bellinger bl += sprintf(b + bl, " "); 577c66ac9dbSNicholas Bellinger if (bd) { 578c66ac9dbSNicholas Bellinger bl += sprintf(b + bl, "Major: %d Minor: %d %s\n", 57921bca31cSRoland Dreier MAJOR(bd->bd_dev), MINOR(bd->bd_dev), (!bd->bd_contains) ? 5800fd97ccfSChristoph Hellwig "" : (bd->bd_holder == ib_dev) ? 581c66ac9dbSNicholas Bellinger "CLAIMED: IBLOCK" : "CLAIMED: OS"); 582c66ac9dbSNicholas Bellinger } else { 58321bca31cSRoland Dreier bl += sprintf(b + bl, "Major: 0 Minor: 0\n"); 584c66ac9dbSNicholas Bellinger } 585c66ac9dbSNicholas Bellinger 586c66ac9dbSNicholas Bellinger return bl; 587c66ac9dbSNicholas Bellinger } 588c66ac9dbSNicholas Bellinger 589de103c93SChristoph Hellwig static sense_reason_t 590a82a9538SNicholas Bellinger iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, 591a82a9538SNicholas Bellinger enum dma_data_direction data_direction) 592c66ac9dbSNicholas Bellinger { 5935951146dSAndy Grover struct se_device *dev = cmd->se_dev; 5945787cacdSChristoph Hellwig struct iblock_req *ibr; 595dbbf3e94SChristoph Hellwig struct bio *bio; 596dbbf3e94SChristoph Hellwig struct bio_list list; 597c66ac9dbSNicholas Bellinger struct scatterlist *sg; 5985787cacdSChristoph Hellwig u32 sg_num = sgl_nents; 599c66ac9dbSNicholas Bellinger sector_t block_lba; 600d5b4a21bSChristoph Hellwig unsigned bio_cnt; 601d0c8b259SNicholas Bellinger int rw = 0; 6025787cacdSChristoph Hellwig int i; 603dbbf3e94SChristoph Hellwig 6045787cacdSChristoph Hellwig if (data_direction == DMA_TO_DEVICE) { 605d0c8b259SNicholas Bellinger struct iblock_dev *ib_dev = IBLOCK_DEV(dev); 606d0c8b259SNicholas Bellinger struct request_queue *q = bdev_get_queue(ib_dev->ibd_bd); 607dbbf3e94SChristoph Hellwig /* 608d0c8b259SNicholas Bellinger * Force writethrough using WRITE_FUA if a volatile write cache 609d0c8b259SNicholas Bellinger * is not enabled, or if initiator set the Force Unit Access bit. 610dbbf3e94SChristoph Hellwig */ 611d0c8b259SNicholas Bellinger if (q->flush_flags & REQ_FUA) { 612d0c8b259SNicholas Bellinger if (cmd->se_cmd_flags & SCF_FUA) 613dbbf3e94SChristoph Hellwig rw = WRITE_FUA; 614d0c8b259SNicholas Bellinger else if (!(q->flush_flags & REQ_FLUSH)) 615d0c8b259SNicholas Bellinger rw = WRITE_FUA; 616d2bdbee0SNicholas Bellinger else 617d2bdbee0SNicholas Bellinger rw = WRITE; 618d0c8b259SNicholas Bellinger } else { 619dbbf3e94SChristoph Hellwig rw = WRITE; 620d0c8b259SNicholas Bellinger } 621dbbf3e94SChristoph Hellwig } else { 622dbbf3e94SChristoph Hellwig rw = READ; 623dbbf3e94SChristoph Hellwig } 624dbbf3e94SChristoph Hellwig 625c66ac9dbSNicholas Bellinger /* 6265787cacdSChristoph Hellwig * Convert the blocksize advertised to the initiator to the 512 byte 6275787cacdSChristoph Hellwig * units unconditionally used by the Linux block layer. 628c66ac9dbSNicholas Bellinger */ 6290fd97ccfSChristoph Hellwig if (dev->dev_attrib.block_size == 4096) 63072a0e5e2SChristoph Hellwig block_lba = (cmd->t_task_lba << 3); 6310fd97ccfSChristoph Hellwig else if (dev->dev_attrib.block_size == 2048) 63272a0e5e2SChristoph Hellwig block_lba = (cmd->t_task_lba << 2); 6330fd97ccfSChristoph Hellwig else if (dev->dev_attrib.block_size == 1024) 63472a0e5e2SChristoph Hellwig block_lba = (cmd->t_task_lba << 1); 6350fd97ccfSChristoph Hellwig else if (dev->dev_attrib.block_size == 512) 63672a0e5e2SChristoph Hellwig block_lba = cmd->t_task_lba; 637c66ac9dbSNicholas Bellinger else { 6386708bb27SAndy Grover pr_err("Unsupported SCSI -> BLOCK LBA conversion:" 6390fd97ccfSChristoph Hellwig " %u\n", dev->dev_attrib.block_size); 640de103c93SChristoph Hellwig return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 641c66ac9dbSNicholas Bellinger } 642c66ac9dbSNicholas Bellinger 6435787cacdSChristoph Hellwig ibr = kzalloc(sizeof(struct iblock_req), GFP_KERNEL); 6445787cacdSChristoph Hellwig if (!ibr) 6455787cacdSChristoph Hellwig goto fail; 6465787cacdSChristoph Hellwig cmd->priv = ibr; 6475787cacdSChristoph Hellwig 648e0de4457SPaolo Bonzini if (!sgl_nents) { 649e0de4457SPaolo Bonzini atomic_set(&ibr->pending, 1); 650e0de4457SPaolo Bonzini iblock_complete_cmd(cmd); 651e0de4457SPaolo Bonzini return 0; 652e0de4457SPaolo Bonzini } 653e0de4457SPaolo Bonzini 6545787cacdSChristoph Hellwig bio = iblock_get_bio(cmd, block_lba, sgl_nents); 6555787cacdSChristoph Hellwig if (!bio) 6565787cacdSChristoph Hellwig goto fail_free_ibr; 657c66ac9dbSNicholas Bellinger 658dbbf3e94SChristoph Hellwig bio_list_init(&list); 659dbbf3e94SChristoph Hellwig bio_list_add(&list, bio); 6605787cacdSChristoph Hellwig 6615787cacdSChristoph Hellwig atomic_set(&ibr->pending, 2); 662d5b4a21bSChristoph Hellwig bio_cnt = 1; 663dbbf3e94SChristoph Hellwig 6645787cacdSChristoph Hellwig for_each_sg(sgl, sg, sgl_nents, i) { 665dbbf3e94SChristoph Hellwig /* 666dbbf3e94SChristoph Hellwig * XXX: if the length the device accepts is shorter than the 667dbbf3e94SChristoph Hellwig * length of the S/G list entry this will cause and 668dbbf3e94SChristoph Hellwig * endless loop. Better hope no driver uses huge pages. 669dbbf3e94SChristoph Hellwig */ 670dbbf3e94SChristoph Hellwig while (bio_add_page(bio, sg_page(sg), sg->length, sg->offset) 671dbbf3e94SChristoph Hellwig != sg->length) { 672d5b4a21bSChristoph Hellwig if (bio_cnt >= IBLOCK_MAX_BIO_PER_TASK) { 673d5b4a21bSChristoph Hellwig iblock_submit_bios(&list, rw); 674d5b4a21bSChristoph Hellwig bio_cnt = 0; 675d5b4a21bSChristoph Hellwig } 676d5b4a21bSChristoph Hellwig 6775787cacdSChristoph Hellwig bio = iblock_get_bio(cmd, block_lba, sg_num); 6786708bb27SAndy Grover if (!bio) 6795787cacdSChristoph Hellwig goto fail_put_bios; 6805787cacdSChristoph Hellwig 6815787cacdSChristoph Hellwig atomic_inc(&ibr->pending); 682dbbf3e94SChristoph Hellwig bio_list_add(&list, bio); 683d5b4a21bSChristoph Hellwig bio_cnt++; 684c66ac9dbSNicholas Bellinger } 685dbbf3e94SChristoph Hellwig 686c66ac9dbSNicholas Bellinger /* Always in 512 byte units for Linux/Block */ 687c66ac9dbSNicholas Bellinger block_lba += sg->length >> IBLOCK_LBA_SHIFT; 688c66ac9dbSNicholas Bellinger sg_num--; 689c66ac9dbSNicholas Bellinger } 690c66ac9dbSNicholas Bellinger 691d5b4a21bSChristoph Hellwig iblock_submit_bios(&list, rw); 6925787cacdSChristoph Hellwig iblock_complete_cmd(cmd); 69303e98c9eSNicholas Bellinger return 0; 694dbbf3e94SChristoph Hellwig 6955787cacdSChristoph Hellwig fail_put_bios: 696dbbf3e94SChristoph Hellwig while ((bio = bio_list_pop(&list))) 697c66ac9dbSNicholas Bellinger bio_put(bio); 6985787cacdSChristoph Hellwig fail_free_ibr: 6995787cacdSChristoph Hellwig kfree(ibr); 7005787cacdSChristoph Hellwig fail: 701de103c93SChristoph Hellwig return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 702c66ac9dbSNicholas Bellinger } 703c66ac9dbSNicholas Bellinger 704c66ac9dbSNicholas Bellinger static sector_t iblock_get_blocks(struct se_device *dev) 705c66ac9dbSNicholas Bellinger { 7060fd97ccfSChristoph Hellwig struct iblock_dev *ib_dev = IBLOCK_DEV(dev); 7070fd97ccfSChristoph Hellwig struct block_device *bd = ib_dev->ibd_bd; 708c66ac9dbSNicholas Bellinger struct request_queue *q = bdev_get_queue(bd); 709c66ac9dbSNicholas Bellinger 710c66ac9dbSNicholas Bellinger return iblock_emulate_read_cap_with_block_size(dev, bd, q); 711c66ac9dbSNicholas Bellinger } 712c66ac9dbSNicholas Bellinger 7137f7caf6aSAndy Grover static sector_t iblock_get_alignment_offset_lbas(struct se_device *dev) 7147f7caf6aSAndy Grover { 7157f7caf6aSAndy Grover struct iblock_dev *ib_dev = IBLOCK_DEV(dev); 7167f7caf6aSAndy Grover struct block_device *bd = ib_dev->ibd_bd; 7177f7caf6aSAndy Grover int ret; 7187f7caf6aSAndy Grover 7197f7caf6aSAndy Grover ret = bdev_alignment_offset(bd); 7207f7caf6aSAndy Grover if (ret == -1) 7217f7caf6aSAndy Grover return 0; 7227f7caf6aSAndy Grover 7237f7caf6aSAndy Grover /* convert offset-bytes to offset-lbas */ 7247f7caf6aSAndy Grover return ret / bdev_logical_block_size(bd); 7257f7caf6aSAndy Grover } 7267f7caf6aSAndy Grover 7277f7caf6aSAndy Grover static unsigned int iblock_get_lbppbe(struct se_device *dev) 7287f7caf6aSAndy Grover { 7297f7caf6aSAndy Grover struct iblock_dev *ib_dev = IBLOCK_DEV(dev); 7307f7caf6aSAndy Grover struct block_device *bd = ib_dev->ibd_bd; 7317f7caf6aSAndy Grover int logs_per_phys = bdev_physical_block_size(bd) / bdev_logical_block_size(bd); 7327f7caf6aSAndy Grover 7337f7caf6aSAndy Grover return ilog2(logs_per_phys); 7347f7caf6aSAndy Grover } 7357f7caf6aSAndy Grover 7367f7caf6aSAndy Grover static unsigned int iblock_get_io_min(struct se_device *dev) 7377f7caf6aSAndy Grover { 7387f7caf6aSAndy Grover struct iblock_dev *ib_dev = IBLOCK_DEV(dev); 7397f7caf6aSAndy Grover struct block_device *bd = ib_dev->ibd_bd; 7407f7caf6aSAndy Grover 7417f7caf6aSAndy Grover return bdev_io_min(bd); 7427f7caf6aSAndy Grover } 7437f7caf6aSAndy Grover 7447f7caf6aSAndy Grover static unsigned int iblock_get_io_opt(struct se_device *dev) 7457f7caf6aSAndy Grover { 7467f7caf6aSAndy Grover struct iblock_dev *ib_dev = IBLOCK_DEV(dev); 7477f7caf6aSAndy Grover struct block_device *bd = ib_dev->ibd_bd; 7487f7caf6aSAndy Grover 7497f7caf6aSAndy Grover return bdev_io_opt(bd); 7507f7caf6aSAndy Grover } 7517f7caf6aSAndy Grover 7529e999a6cSChristoph Hellwig static struct sbc_ops iblock_sbc_ops = { 7530c2ad7d1SChristoph Hellwig .execute_rw = iblock_execute_rw, 754ad67f0d9SChristoph Hellwig .execute_sync_cache = iblock_execute_sync_cache, 7556f974e8cSChristoph Hellwig .execute_write_same = iblock_execute_write_same, 756f6970ad3SNicholas Bellinger .execute_write_same_unmap = iblock_execute_write_same_unmap, 75714150a6bSChristoph Hellwig .execute_unmap = iblock_execute_unmap, 7580c2ad7d1SChristoph Hellwig }; 7590c2ad7d1SChristoph Hellwig 760de103c93SChristoph Hellwig static sense_reason_t 761de103c93SChristoph Hellwig iblock_parse_cdb(struct se_cmd *cmd) 7620c2ad7d1SChristoph Hellwig { 7639e999a6cSChristoph Hellwig return sbc_parse_cdb(cmd, &iblock_sbc_ops); 7640c2ad7d1SChristoph Hellwig } 7650c2ad7d1SChristoph Hellwig 766452e2010SRashika Kheria static bool iblock_get_write_cache(struct se_device *dev) 767d0c8b259SNicholas Bellinger { 768d0c8b259SNicholas Bellinger struct iblock_dev *ib_dev = IBLOCK_DEV(dev); 769d0c8b259SNicholas Bellinger struct block_device *bd = ib_dev->ibd_bd; 770d0c8b259SNicholas Bellinger struct request_queue *q = bdev_get_queue(bd); 771d0c8b259SNicholas Bellinger 772d0c8b259SNicholas Bellinger return q->flush_flags & REQ_FLUSH; 773d0c8b259SNicholas Bellinger } 774d0c8b259SNicholas Bellinger 775c66ac9dbSNicholas Bellinger static struct se_subsystem_api iblock_template = { 776c66ac9dbSNicholas Bellinger .name = "iblock", 7770fd97ccfSChristoph Hellwig .inquiry_prod = "IBLOCK", 7780fd97ccfSChristoph Hellwig .inquiry_rev = IBLOCK_VERSION, 779c66ac9dbSNicholas Bellinger .owner = THIS_MODULE, 780c66ac9dbSNicholas Bellinger .transport_type = TRANSPORT_PLUGIN_VHBA_PDEV, 781c66ac9dbSNicholas Bellinger .attach_hba = iblock_attach_hba, 782c66ac9dbSNicholas Bellinger .detach_hba = iblock_detach_hba, 7830fd97ccfSChristoph Hellwig .alloc_device = iblock_alloc_device, 7840fd97ccfSChristoph Hellwig .configure_device = iblock_configure_device, 785c66ac9dbSNicholas Bellinger .free_device = iblock_free_device, 7860c2ad7d1SChristoph Hellwig .parse_cdb = iblock_parse_cdb, 787c66ac9dbSNicholas Bellinger .set_configfs_dev_params = iblock_set_configfs_dev_params, 788c66ac9dbSNicholas Bellinger .show_configfs_dev_params = iblock_show_configfs_dev_params, 7896f23ac8aSChristoph Hellwig .get_device_type = sbc_get_device_type, 790c66ac9dbSNicholas Bellinger .get_blocks = iblock_get_blocks, 7917f7caf6aSAndy Grover .get_alignment_offset_lbas = iblock_get_alignment_offset_lbas, 7927f7caf6aSAndy Grover .get_lbppbe = iblock_get_lbppbe, 7937f7caf6aSAndy Grover .get_io_min = iblock_get_io_min, 7947f7caf6aSAndy Grover .get_io_opt = iblock_get_io_opt, 795d0c8b259SNicholas Bellinger .get_write_cache = iblock_get_write_cache, 796c66ac9dbSNicholas Bellinger }; 797c66ac9dbSNicholas Bellinger 798c66ac9dbSNicholas Bellinger static int __init iblock_module_init(void) 799c66ac9dbSNicholas Bellinger { 800c66ac9dbSNicholas Bellinger return transport_subsystem_register(&iblock_template); 801c66ac9dbSNicholas Bellinger } 802c66ac9dbSNicholas Bellinger 80363b91d5aSAsias He static void __exit iblock_module_exit(void) 804c66ac9dbSNicholas Bellinger { 805c66ac9dbSNicholas Bellinger transport_subsystem_release(&iblock_template); 806c66ac9dbSNicholas Bellinger } 807c66ac9dbSNicholas Bellinger 808c66ac9dbSNicholas Bellinger MODULE_DESCRIPTION("TCM IBLOCK subsystem plugin"); 809c66ac9dbSNicholas Bellinger MODULE_AUTHOR("nab@Linux-iSCSI.org"); 810c66ac9dbSNicholas Bellinger MODULE_LICENSE("GPL"); 811c66ac9dbSNicholas Bellinger 812c66ac9dbSNicholas Bellinger module_init(iblock_module_init); 813c66ac9dbSNicholas Bellinger module_exit(iblock_module_exit); 814