Blame view

drivers/target/target_core_iblock.c 21.2 KB
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1
2
3
4
5
6
  /*******************************************************************************
   * Filename:  target_core_iblock.c
   *
   * This file contains the Storage Engine  <-> Linux BlockIO transport
   * specific functions.
   *
4c76251e8   Nicholas Bellinger   target: Update co...
7
   * (c) Copyright 2003-2013 Datera, Inc.
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
   *
   * Nicholas A. Bellinger <nab@kernel.org>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   *
   ******************************************************************************/
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
26
27
28
29
30
31
32
  #include <linux/string.h>
  #include <linux/parser.h>
  #include <linux/timer.h>
  #include <linux/fs.h>
  #include <linux/blkdev.h>
  #include <linux/slab.h>
  #include <linux/spinlock.h>
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
33
34
35
  #include <linux/bio.h>
  #include <linux/genhd.h>
  #include <linux/file.h>
827509e38   Paul Gortmaker   drivers/target: A...
36
  #include <linux/module.h>
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
37
38
  #include <scsi/scsi.h>
  #include <scsi/scsi_host.h>
14150a6bb   Christoph Hellwig   target: move unma...
39
  #include <asm/unaligned.h>
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
40
41
  
  #include <target/target_core_base.h>
c4795fb20   Christoph Hellwig   target: header re...
42
  #include <target/target_core_backend.h>
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
43
44
  
  #include "target_core_iblock.h"
d5b4a21b3   Christoph Hellwig   target: increase ...
45
46
  #define IBLOCK_MAX_BIO_PER_TASK	 32	/* max # of bios to submit at a time */
  #define IBLOCK_BIO_POOL_SIZE	128
0fd97ccf4   Christoph Hellwig   target: kill stru...
47
48
49
50
  static inline struct iblock_dev *IBLOCK_DEV(struct se_device *dev)
  {
  	return container_of(dev, struct iblock_dev, dev);
  }
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
51
  static struct se_subsystem_api iblock_template;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
52
53
54
55
56
57
  /*	iblock_attach_hba(): (Part of se_subsystem_api_t template)
   *
   *
   */
  static int iblock_attach_hba(struct se_hba *hba, u32 host_id)
  {
6708bb27b   Andy Grover   target: Follow up...
58
  	pr_debug("CORE_HBA[%d] - TCM iBlock HBA Driver %s on"
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
59
60
61
  		" Generic Target Core Stack %s
  ", hba->hba_id,
  		IBLOCK_VERSION, TARGET_CORE_MOD_VERSION);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
62
63
64
65
66
  	return 0;
  }
  
  static void iblock_detach_hba(struct se_hba *hba)
  {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
67
  }
0fd97ccf4   Christoph Hellwig   target: kill stru...
68
  static struct se_device *iblock_alloc_device(struct se_hba *hba, const char *name)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
69
70
  {
  	struct iblock_dev *ib_dev = NULL;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
71
72
  
  	ib_dev = kzalloc(sizeof(struct iblock_dev), GFP_KERNEL);
6708bb27b   Andy Grover   target: Follow up...
73
74
75
  	if (!ib_dev) {
  		pr_err("Unable to allocate struct iblock_dev
  ");
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
76
77
  		return NULL;
  	}
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
78

6708bb27b   Andy Grover   target: Follow up...
79
80
  	pr_debug( "IBLOCK: Allocated ib_dev for %s
  ", name);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
81

0fd97ccf4   Christoph Hellwig   target: kill stru...
82
  	return &ib_dev->dev;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
83
  }
0fd97ccf4   Christoph Hellwig   target: kill stru...
84
  static int iblock_configure_device(struct se_device *dev)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
85
  {
0fd97ccf4   Christoph Hellwig   target: kill stru...
86
  	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
87
  	struct request_queue *q;
0fd97ccf4   Christoph Hellwig   target: kill stru...
88
  	struct block_device *bd = NULL;
ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
89
  	struct blk_integrity *bi;
44bfd0185   Andy Grover   target/iblock: Ad...
90
  	fmode_t mode;
0fd97ccf4   Christoph Hellwig   target: kill stru...
91
  	int ret = -ENOMEM;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
92

0fd97ccf4   Christoph Hellwig   target: kill stru...
93
94
95
96
  	if (!(ib_dev->ibd_flags & IBDF_HAS_UDEV_PATH)) {
  		pr_err("Missing udev_path= parameters for IBLOCK
  ");
  		return -EINVAL;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
97
  	}
d5b4a21b3   Christoph Hellwig   target: increase ...
98
99
  
  	ib_dev->ibd_bio_set = bioset_create(IBLOCK_BIO_POOL_SIZE, 0);
6708bb27b   Andy Grover   target: Follow up...
100
  	if (!ib_dev->ibd_bio_set) {
0fd97ccf4   Christoph Hellwig   target: kill stru...
101
102
103
  		pr_err("IBLOCK: Unable to create bioset
  ");
  		goto out;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
104
  	}
0fd97ccf4   Christoph Hellwig   target: kill stru...
105

6708bb27b   Andy Grover   target: Follow up...
106
107
  	pr_debug( "IBLOCK: Claiming struct block_device: %s
  ",
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
108
  			ib_dev->ibd_udev_path);
44bfd0185   Andy Grover   target/iblock: Ad...
109
110
111
112
113
  	mode = FMODE_READ|FMODE_EXCL;
  	if (!ib_dev->ibd_readonly)
  		mode |= FMODE_WRITE;
  
  	bd = blkdev_get_by_path(ib_dev->ibd_udev_path, mode, ib_dev);
613640e4e   Nicholas Bellinger   [SCSI] target: Co...
114
115
  	if (IS_ERR(bd)) {
  		ret = PTR_ERR(bd);
0fd97ccf4   Christoph Hellwig   target: kill stru...
116
  		goto out_free_bioset;
613640e4e   Nicholas Bellinger   [SCSI] target: Co...
117
  	}
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
118
  	ib_dev->ibd_bd = bd;
0fd97ccf4   Christoph Hellwig   target: kill stru...
119
120
121
  	q = bdev_get_queue(bd);
  
  	dev->dev_attrib.hw_block_size = bdev_logical_block_size(bd);
82bc9d04f   Nicholas Bellinger   target: Drop arbi...
122
  	dev->dev_attrib.hw_max_sectors = queue_max_hw_sectors(q);
0fd97ccf4   Christoph Hellwig   target: kill stru...
123
  	dev->dev_attrib.hw_queue_depth = q->nr_requests;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
124

c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
125
126
127
128
129
  	/*
  	 * Check if the underlying struct block_device request_queue supports
  	 * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM
  	 * in ATA and we need to set TPE=1
  	 */
613640e4e   Nicholas Bellinger   [SCSI] target: Co...
130
  	if (blk_queue_discard(q)) {
0fd97ccf4   Christoph Hellwig   target: kill stru...
131
  		dev->dev_attrib.max_unmap_lba_count =
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
132
  				q->limits.max_discard_sectors;
0fd97ccf4   Christoph Hellwig   target: kill stru...
133

c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
134
135
136
  		/*
  		 * Currently hardcoded to 1 in Linux/SCSI code..
  		 */
0fd97ccf4   Christoph Hellwig   target: kill stru...
137
138
  		dev->dev_attrib.max_unmap_block_desc_count = 1;
  		dev->dev_attrib.unmap_granularity =
7347b5ff7   Marco Sanvido   target: Fix ibloc...
139
  				q->limits.discard_granularity >> 9;
0fd97ccf4   Christoph Hellwig   target: kill stru...
140
  		dev->dev_attrib.unmap_granularity_alignment =
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
141
  				q->limits.discard_alignment;
6708bb27b   Andy Grover   target: Follow up...
142
  		pr_debug("IBLOCK: BLOCK Discard support available,"
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
143
144
145
  				" disabled by default
  ");
  	}
f6970ad31   Nicholas Bellinger   target/iblock: Ad...
146
147
148
149
150
  	/*
  	 * Enable write same emulation for IBLOCK and use 0xFFFF as
  	 * the smaller WRITE_SAME(10) only has a two-byte block count.
  	 */
  	dev->dev_attrib.max_write_same_len = 0xFFFF;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
151

e22a7f075   Roland Dreier   target: Implement...
152
  	if (blk_queue_nonrot(q))
0fd97ccf4   Christoph Hellwig   target: kill stru...
153
  		dev->dev_attrib.is_nonrot = 1;
d0c8b259f   Nicholas Bellinger   target/iblock: Us...
154

ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
  	bi = bdev_get_integrity(bd);
  	if (bi) {
  		struct bio_set *bs = ib_dev->ibd_bio_set;
  
  		if (!strcmp(bi->name, "T10-DIF-TYPE3-IP") ||
  		    !strcmp(bi->name, "T10-DIF-TYPE1-IP")) {
  			pr_err("IBLOCK export of blk_integrity: %s not"
  			       " supported
  ", bi->name);
  			ret = -ENOSYS;
  			goto out_blkdev_put;
  		}
  
  		if (!strcmp(bi->name, "T10-DIF-TYPE3-CRC")) {
  			dev->dev_attrib.pi_prot_type = TARGET_DIF_TYPE3_PROT;
  		} else if (!strcmp(bi->name, "T10-DIF-TYPE1-CRC")) {
  			dev->dev_attrib.pi_prot_type = TARGET_DIF_TYPE1_PROT;
  		}
  
  		if (dev->dev_attrib.pi_prot_type) {
  			if (bioset_integrity_create(bs, IBLOCK_BIO_POOL_SIZE) < 0) {
  				pr_err("Unable to allocate bioset for PI
  ");
  				ret = -ENOMEM;
  				goto out_blkdev_put;
  			}
  			pr_debug("IBLOCK setup BIP bs->bio_integrity_pool: %p
  ",
  				 bs->bio_integrity_pool);
  		}
  		dev->dev_attrib.hw_pi_prot_type = dev->dev_attrib.pi_prot_type;
  	}
0fd97ccf4   Christoph Hellwig   target: kill stru...
187
  	return 0;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
188

ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
189
190
  out_blkdev_put:
  	blkdev_put(ib_dev->ibd_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL);
0fd97ccf4   Christoph Hellwig   target: kill stru...
191
192
193
194
195
  out_free_bioset:
  	bioset_free(ib_dev->ibd_bio_set);
  	ib_dev->ibd_bio_set = NULL;
  out:
  	return ret;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
196
  }
0fd97ccf4   Christoph Hellwig   target: kill stru...
197
  static void iblock_free_device(struct se_device *dev)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
198
  {
0fd97ccf4   Christoph Hellwig   target: kill stru...
199
  	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
200

bc6655247   Nicholas Bellinger   [SCSI] target/ibl...
201
202
  	if (ib_dev->ibd_bd != NULL)
  		blkdev_put(ib_dev->ibd_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL);
d84287bcf   Nicholas Bellinger   target/iblock: Fi...
203
  	if (ib_dev->ibd_bio_set != NULL)
bc6655247   Nicholas Bellinger   [SCSI] target/ibl...
204
  		bioset_free(ib_dev->ibd_bio_set);
d84287bcf   Nicholas Bellinger   target/iblock: Fi...
205

c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
206
207
  	kfree(ib_dev);
  }
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
208
209
210
211
212
213
214
215
  static unsigned long long iblock_emulate_read_cap_with_block_size(
  	struct se_device *dev,
  	struct block_device *bd,
  	struct request_queue *q)
  {
  	unsigned long long blocks_long = (div_u64(i_size_read(bd->bd_inode),
  					bdev_logical_block_size(bd)) - 1);
  	u32 block_size = bdev_logical_block_size(bd);
0fd97ccf4   Christoph Hellwig   target: kill stru...
216
  	if (block_size == dev->dev_attrib.block_size)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
217
218
219
220
  		return blocks_long;
  
  	switch (block_size) {
  	case 4096:
0fd97ccf4   Christoph Hellwig   target: kill stru...
221
  		switch (dev->dev_attrib.block_size) {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
222
223
224
225
226
227
228
229
230
231
232
233
234
  		case 2048:
  			blocks_long <<= 1;
  			break;
  		case 1024:
  			blocks_long <<= 2;
  			break;
  		case 512:
  			blocks_long <<= 3;
  		default:
  			break;
  		}
  		break;
  	case 2048:
0fd97ccf4   Christoph Hellwig   target: kill stru...
235
  		switch (dev->dev_attrib.block_size) {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
236
237
238
239
240
241
242
243
244
245
246
247
248
249
  		case 4096:
  			blocks_long >>= 1;
  			break;
  		case 1024:
  			blocks_long <<= 1;
  			break;
  		case 512:
  			blocks_long <<= 2;
  			break;
  		default:
  			break;
  		}
  		break;
  	case 1024:
0fd97ccf4   Christoph Hellwig   target: kill stru...
250
  		switch (dev->dev_attrib.block_size) {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
251
252
253
254
255
256
257
258
259
260
261
262
263
264
  		case 4096:
  			blocks_long >>= 2;
  			break;
  		case 2048:
  			blocks_long >>= 1;
  			break;
  		case 512:
  			blocks_long <<= 1;
  			break;
  		default:
  			break;
  		}
  		break;
  	case 512:
0fd97ccf4   Christoph Hellwig   target: kill stru...
265
  		switch (dev->dev_attrib.block_size) {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
  		case 4096:
  			blocks_long >>= 3;
  			break;
  		case 2048:
  			blocks_long >>= 2;
  			break;
  		case 1024:
  			blocks_long >>= 1;
  			break;
  		default:
  			break;
  		}
  		break;
  	default:
  		break;
  	}
  
  	return blocks_long;
  }
3a41d85fe   Nicholas Bellinger   target/iblock: Fo...
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
  static void iblock_complete_cmd(struct se_cmd *cmd)
  {
  	struct iblock_req *ibr = cmd->priv;
  	u8 status;
  
  	if (!atomic_dec_and_test(&ibr->pending))
  		return;
  
  	if (atomic_read(&ibr->ib_bio_err_cnt))
  		status = SAM_STAT_CHECK_CONDITION;
  	else
  		status = SAM_STAT_GOOD;
  
  	target_complete_cmd(cmd, status);
  	kfree(ibr);
  }
  
  static void iblock_bio_done(struct bio *bio, int err)
  {
  	struct se_cmd *cmd = bio->bi_private;
  	struct iblock_req *ibr = cmd->priv;
  
  	/*
  	 * Set -EIO if !BIO_UPTODATE and the passed is still err=0
  	 */
  	if (!test_bit(BIO_UPTODATE, &bio->bi_flags) && !err)
  		err = -EIO;
  
  	if (err != 0) {
  		pr_err("test_bit(BIO_UPTODATE) failed for bio: %p,"
  			" err: %d
  ", bio, err);
  		/*
  		 * Bump the ib_bio_err_cnt and release bio.
  		 */
  		atomic_inc(&ibr->ib_bio_err_cnt);
4e857c58e   Peter Zijlstra   arch: Mass conver...
321
  		smp_mb__after_atomic();
3a41d85fe   Nicholas Bellinger   target/iblock: Fo...
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
  	}
  
  	bio_put(bio);
  
  	iblock_complete_cmd(cmd);
  }
  
  static struct bio *
  iblock_get_bio(struct se_cmd *cmd, sector_t lba, u32 sg_num)
  {
  	struct iblock_dev *ib_dev = IBLOCK_DEV(cmd->se_dev);
  	struct bio *bio;
  
  	/*
  	 * Only allocate as many vector entries as the bio code allows us to,
  	 * we'll loop later on until we have handled the whole request.
  	 */
  	if (sg_num > BIO_MAX_PAGES)
  		sg_num = BIO_MAX_PAGES;
  
  	bio = bio_alloc_bioset(GFP_NOIO, sg_num, ib_dev->ibd_bio_set);
  	if (!bio) {
  		pr_err("Unable to allocate memory for bio
  ");
  		return NULL;
  	}
  
  	bio->bi_bdev = ib_dev->ibd_bd;
  	bio->bi_private = cmd;
  	bio->bi_end_io = &iblock_bio_done;
4f024f379   Kent Overstreet   block: Abstract o...
352
  	bio->bi_iter.bi_sector = lba;
3a41d85fe   Nicholas Bellinger   target/iblock: Fo...
353
354
355
356
357
358
359
360
361
362
363
364
365
366
  
  	return bio;
  }
  
  static void iblock_submit_bios(struct bio_list *list, int rw)
  {
  	struct blk_plug plug;
  	struct bio *bio;
  
  	blk_start_plug(&plug);
  	while ((bio = bio_list_pop(list)))
  		submit_bio(rw, bio);
  	blk_finish_plug(&plug);
  }
df5fa691c   Christoph Hellwig   target: make iblo...
367
368
369
370
371
372
373
  static void iblock_end_io_flush(struct bio *bio, int err)
  {
  	struct se_cmd *cmd = bio->bi_private;
  
  	if (err)
  		pr_err("IBLOCK: cache flush failed: %d
  ", err);
5787cacd0   Christoph Hellwig   target: remove st...
374
  	if (cmd) {
de103c93a   Christoph Hellwig   target: pass sens...
375
  		if (err)
5787cacd0   Christoph Hellwig   target: remove st...
376
  			target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION);
de103c93a   Christoph Hellwig   target: pass sens...
377
  		else
5787cacd0   Christoph Hellwig   target: remove st...
378
  			target_complete_cmd(cmd, SAM_STAT_GOOD);
5787cacd0   Christoph Hellwig   target: remove st...
379
  	}
df5fa691c   Christoph Hellwig   target: make iblo...
380
381
  	bio_put(bio);
  }
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
382
  /*
df5fa691c   Christoph Hellwig   target: make iblo...
383
384
   * Implement SYCHRONIZE CACHE.  Note that we can't handle lba ranges and must
   * always flush the whole cache.
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
385
   */
de103c93a   Christoph Hellwig   target: pass sens...
386
387
  static sense_reason_t
  iblock_execute_sync_cache(struct se_cmd *cmd)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
388
  {
0fd97ccf4   Christoph Hellwig   target: kill stru...
389
  	struct iblock_dev *ib_dev = IBLOCK_DEV(cmd->se_dev);
a1d8b49ab   Andy Grover   target: Updates f...
390
  	int immed = (cmd->t_task_cdb[1] & 0x2);
df5fa691c   Christoph Hellwig   target: make iblo...
391
  	struct bio *bio;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
392
393
394
  
  	/*
  	 * If the Immediate bit is set, queue up the GOOD response
df5fa691c   Christoph Hellwig   target: make iblo...
395
  	 * for this SYNCHRONIZE_CACHE op.
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
396
397
  	 */
  	if (immed)
5787cacd0   Christoph Hellwig   target: remove st...
398
  		target_complete_cmd(cmd, SAM_STAT_GOOD);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
399

df5fa691c   Christoph Hellwig   target: make iblo...
400
401
402
  	bio = bio_alloc(GFP_KERNEL, 0);
  	bio->bi_end_io = iblock_end_io_flush;
  	bio->bi_bdev = ib_dev->ibd_bd;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
403
  	if (!immed)
df5fa691c   Christoph Hellwig   target: make iblo...
404
405
  		bio->bi_private = cmd;
  	submit_bio(WRITE_FLUSH, bio);
ad67f0d9e   Christoph Hellwig   target: move sync...
406
  	return 0;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
407
  }
de103c93a   Christoph Hellwig   target: pass sens...
408
  static sense_reason_t
86d718298   Asias He   target: Add sbc_e...
409
  iblock_do_unmap(struct se_cmd *cmd, void *priv,
dbc21c5ab   Asias He   target/iblock: Ad...
410
411
  		sector_t lba, sector_t nolb)
  {
86d718298   Asias He   target: Add sbc_e...
412
  	struct block_device *bdev = priv;
dbc21c5ab   Asias He   target/iblock: Ad...
413
414
415
416
417
418
419
420
421
422
423
424
425
  	int ret;
  
  	ret = blkdev_issue_discard(bdev, lba, nolb, GFP_KERNEL, 0);
  	if (ret < 0) {
  		pr_err("blkdev_issue_discard() failed: %d
  ", ret);
  		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
  	}
  
  	return 0;
  }
  
  static sense_reason_t
de103c93a   Christoph Hellwig   target: pass sens...
426
  iblock_execute_unmap(struct se_cmd *cmd)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
427
  {
86d718298   Asias He   target: Add sbc_e...
428
  	struct block_device *bdev = IBLOCK_DEV(cmd->se_dev)->ibd_bd;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
429

86d718298   Asias He   target: Add sbc_e...
430
  	return sbc_execute_unmap(cmd, iblock_do_unmap, bdev);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
431
  }
de103c93a   Christoph Hellwig   target: pass sens...
432
  static sense_reason_t
f6970ad31   Nicholas Bellinger   target/iblock: Ad...
433
  iblock_execute_write_same_unmap(struct se_cmd *cmd)
6f974e8ce   Christoph Hellwig   target: move writ...
434
  {
dbc21c5ab   Asias He   target/iblock: Ad...
435
436
437
438
439
440
441
442
  	struct block_device *bdev = IBLOCK_DEV(cmd->se_dev)->ibd_bd;
  	sector_t lba = cmd->t_task_lba;
  	sector_t nolb = sbc_get_write_same_sectors(cmd);
  	int ret;
  
  	ret = iblock_do_unmap(cmd, bdev, lba, nolb);
  	if (ret)
  		return ret;
6f974e8ce   Christoph Hellwig   target: move writ...
443
444
445
446
  
  	target_complete_cmd(cmd, GOOD);
  	return 0;
  }
f6970ad31   Nicholas Bellinger   target/iblock: Ad...
447
448
449
450
451
452
453
454
  static sense_reason_t
  iblock_execute_write_same(struct se_cmd *cmd)
  {
  	struct iblock_req *ibr;
  	struct scatterlist *sg;
  	struct bio *bio;
  	struct bio_list list;
  	sector_t block_lba = cmd->t_task_lba;
972b29c8f   Roland Dreier   target: Rename sp...
455
  	sector_t sectors = sbc_get_write_same_sectors(cmd);
f6970ad31   Nicholas Bellinger   target/iblock: Ad...
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
  
  	sg = &cmd->t_data_sg[0];
  
  	if (cmd->t_data_nents > 1 ||
  	    sg->length != cmd->se_dev->dev_attrib.block_size) {
  		pr_err("WRITE_SAME: Illegal SGL t_data_nents: %u length: %u"
  			" block_size: %u
  ", cmd->t_data_nents, sg->length,
  			cmd->se_dev->dev_attrib.block_size);
  		return TCM_INVALID_CDB_FIELD;
  	}
  
  	ibr = kzalloc(sizeof(struct iblock_req), GFP_KERNEL);
  	if (!ibr)
  		goto fail;
  	cmd->priv = ibr;
  
  	bio = iblock_get_bio(cmd, block_lba, 1);
  	if (!bio)
  		goto fail_free_ibr;
  
  	bio_list_init(&list);
  	bio_list_add(&list, bio);
  
  	atomic_set(&ibr->pending, 1);
  
  	while (sectors) {
  		while (bio_add_page(bio, sg_page(sg), sg->length, sg->offset)
  				!= sg->length) {
  
  			bio = iblock_get_bio(cmd, block_lba, 1);
  			if (!bio)
  				goto fail_put_bios;
  
  			atomic_inc(&ibr->pending);
  			bio_list_add(&list, bio);
  		}
  
  		/* Always in 512 byte units for Linux/Block */
  		block_lba += sg->length >> IBLOCK_LBA_SHIFT;
  		sectors -= 1;
  	}
  
  	iblock_submit_bios(&list, WRITE);
  	return 0;
  
  fail_put_bios:
  	while ((bio = bio_list_pop(&list)))
  		bio_put(bio);
  fail_free_ibr:
  	kfree(ibr);
  fail:
  	return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
  }
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
510
  enum {
44bfd0185   Andy Grover   target/iblock: Ad...
511
  	Opt_udev_path, Opt_readonly, Opt_force, Opt_err
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
512
513
514
515
  };
  
  static match_table_t tokens = {
  	{Opt_udev_path, "udev_path=%s"},
44bfd0185   Andy Grover   target/iblock: Ad...
516
  	{Opt_readonly, "readonly=%d"},
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
517
518
519
  	{Opt_force, "force=%d"},
  	{Opt_err, NULL}
  };
0fd97ccf4   Christoph Hellwig   target: kill stru...
520
521
  static ssize_t iblock_set_configfs_dev_params(struct se_device *dev,
  		const char *page, ssize_t count)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
522
  {
0fd97ccf4   Christoph Hellwig   target: kill stru...
523
  	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
6d1802539   Jesper Juhl   [SCSI] target: Fi...
524
  	char *orig, *ptr, *arg_p, *opts;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
525
  	substring_t args[MAX_OPT_ARGS];
21bca31c9   Roland Dreier   target/iblock: Re...
526
  	int ret = 0, token;
44bfd0185   Andy Grover   target/iblock: Ad...
527
  	unsigned long tmp_readonly;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
528
529
530
531
532
533
  
  	opts = kstrdup(page, GFP_KERNEL);
  	if (!opts)
  		return -ENOMEM;
  
  	orig = opts;
90c161b64   Sebastian Andrzej Siewior   target: use \n as...
534
535
  	while ((ptr = strsep(&opts, ",
  ")) != NULL) {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
536
537
538
539
540
541
542
  		if (!*ptr)
  			continue;
  
  		token = match_token(ptr, tokens, args);
  		switch (token) {
  		case Opt_udev_path:
  			if (ib_dev->ibd_bd) {
6708bb27b   Andy Grover   target: Follow up...
543
  				pr_err("Unable to set udev_path= while"
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
544
545
546
547
548
  					" ib_dev->ibd_bd exists
  ");
  				ret = -EEXIST;
  				goto out;
  			}
852b6ed11   Nicholas Bellinger   target/iblock: Us...
549
550
551
  			if (match_strlcpy(ib_dev->ibd_udev_path, &args[0],
  				SE_UDEV_PATH_LEN) == 0) {
  				ret = -EINVAL;
6d1802539   Jesper Juhl   [SCSI] target: Fi...
552
553
  				break;
  			}
6708bb27b   Andy Grover   target: Follow up...
554
555
  			pr_debug("IBLOCK: Referencing UDEV path: %s
  ",
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
556
557
558
  					ib_dev->ibd_udev_path);
  			ib_dev->ibd_flags |= IBDF_HAS_UDEV_PATH;
  			break;
44bfd0185   Andy Grover   target/iblock: Ad...
559
560
561
562
563
564
  		case Opt_readonly:
  			arg_p = match_strdup(&args[0]);
  			if (!arg_p) {
  				ret = -ENOMEM;
  				break;
  			}
57103d7fe   Jingoo Han   target: replace s...
565
  			ret = kstrtoul(arg_p, 0, &tmp_readonly);
44bfd0185   Andy Grover   target/iblock: Ad...
566
567
  			kfree(arg_p);
  			if (ret < 0) {
57103d7fe   Jingoo Han   target: replace s...
568
  				pr_err("kstrtoul() failed for"
44bfd0185   Andy Grover   target/iblock: Ad...
569
570
571
572
573
574
575
576
  						" readonly=
  ");
  				goto out;
  			}
  			ib_dev->ibd_readonly = tmp_readonly;
  			pr_debug("IBLOCK: readonly: %d
  ", ib_dev->ibd_readonly);
  			break;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
577
  		case Opt_force:
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
578
579
580
581
582
583
584
585
586
587
  			break;
  		default:
  			break;
  		}
  	}
  
  out:
  	kfree(orig);
  	return (!ret) ? count : ret;
  }
0fd97ccf4   Christoph Hellwig   target: kill stru...
588
  static ssize_t iblock_show_configfs_dev_params(struct se_device *dev, char *b)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
589
  {
0fd97ccf4   Christoph Hellwig   target: kill stru...
590
591
  	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
  	struct block_device *bd = ib_dev->ibd_bd;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
592
593
594
595
596
597
  	char buf[BDEVNAME_SIZE];
  	ssize_t bl = 0;
  
  	if (bd)
  		bl += sprintf(b + bl, "iBlock device: %s",
  				bdevname(bd, buf));
0fd97ccf4   Christoph Hellwig   target: kill stru...
598
  	if (ib_dev->ibd_flags & IBDF_HAS_UDEV_PATH)
44bfd0185   Andy Grover   target/iblock: Ad...
599
  		bl += sprintf(b + bl, "  UDEV PATH: %s",
0fd97ccf4   Christoph Hellwig   target: kill stru...
600
601
602
  				ib_dev->ibd_udev_path);
  	bl += sprintf(b + bl, "  readonly: %d
  ", ib_dev->ibd_readonly);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
603
604
605
606
607
  
  	bl += sprintf(b + bl, "        ");
  	if (bd) {
  		bl += sprintf(b + bl, "Major: %d Minor: %d  %s
  ",
21bca31c9   Roland Dreier   target/iblock: Re...
608
  			MAJOR(bd->bd_dev), MINOR(bd->bd_dev), (!bd->bd_contains) ?
0fd97ccf4   Christoph Hellwig   target: kill stru...
609
  			"" : (bd->bd_holder == ib_dev) ?
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
610
611
  			"CLAIMED: IBLOCK" : "CLAIMED: OS");
  	} else {
21bca31c9   Roland Dreier   target/iblock: Re...
612
613
  		bl += sprintf(b + bl, "Major: 0 Minor: 0
  ");
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
614
615
616
617
  	}
  
  	return bl;
  }
ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
  static int
  iblock_alloc_bip(struct se_cmd *cmd, struct bio *bio)
  {
  	struct se_device *dev = cmd->se_dev;
  	struct blk_integrity *bi;
  	struct bio_integrity_payload *bip;
  	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
  	struct scatterlist *sg;
  	int i, rc;
  
  	bi = bdev_get_integrity(ib_dev->ibd_bd);
  	if (!bi) {
  		pr_err("Unable to locate bio_integrity
  ");
  		return -ENODEV;
  	}
  
  	bip = bio_integrity_alloc(bio, GFP_NOIO, cmd->t_prot_nents);
  	if (!bip) {
  		pr_err("Unable to allocate bio_integrity_payload
  ");
  		return -ENOMEM;
  	}
4e13c5d02   Linus Torvalds   Merge branch 'for...
641
  	bip->bip_iter.bi_size = (cmd->data_length / dev->dev_attrib.block_size) *
ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
642
  			 dev->prot_length;
4e13c5d02   Linus Torvalds   Merge branch 'for...
643
  	bip->bip_iter.bi_sector = bio->bi_iter.bi_sector;
ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
644

4e13c5d02   Linus Torvalds   Merge branch 'for...
645
646
647
  	pr_debug("IBLOCK BIP Size: %u Sector: %llu
  ", bip->bip_iter.bi_size,
  		 (unsigned long long)bip->bip_iter.bi_sector);
ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
  
  	for_each_sg(cmd->t_prot_sg, sg, cmd->t_prot_nents, i) {
  
  		rc = bio_integrity_add_page(bio, sg_page(sg), sg->length,
  					    sg->offset);
  		if (rc != sg->length) {
  			pr_err("bio_integrity_add_page() failed; %d
  ", rc);
  			return -ENOMEM;
  		}
  
  		pr_debug("Added bio integrity page: %p length: %d offset; %d
  ",
  			 sg_page(sg), sg->length, sg->offset);
  	}
  
  	return 0;
  }
de103c93a   Christoph Hellwig   target: pass sens...
666
  static sense_reason_t
a82a9538d   Nicholas Bellinger   target: Allow sbc...
667
668
  iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
  		  enum dma_data_direction data_direction)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
669
  {
5951146de   Andy Grover   target: More core...
670
  	struct se_device *dev = cmd->se_dev;
5787cacd0   Christoph Hellwig   target: remove st...
671
  	struct iblock_req *ibr;
ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
672
  	struct bio *bio, *bio_start;
dbbf3e94c   Christoph Hellwig   target: cleanup i...
673
  	struct bio_list list;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
674
  	struct scatterlist *sg;
5787cacd0   Christoph Hellwig   target: remove st...
675
  	u32 sg_num = sgl_nents;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
676
  	sector_t block_lba;
d5b4a21b3   Christoph Hellwig   target: increase ...
677
  	unsigned bio_cnt;
d0c8b259f   Nicholas Bellinger   target/iblock: Us...
678
  	int rw = 0;
5787cacd0   Christoph Hellwig   target: remove st...
679
  	int i;
dbbf3e94c   Christoph Hellwig   target: cleanup i...
680

5787cacd0   Christoph Hellwig   target: remove st...
681
  	if (data_direction == DMA_TO_DEVICE) {
d0c8b259f   Nicholas Bellinger   target/iblock: Us...
682
683
  		struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
  		struct request_queue *q = bdev_get_queue(ib_dev->ibd_bd);
dbbf3e94c   Christoph Hellwig   target: cleanup i...
684
  		/*
d0c8b259f   Nicholas Bellinger   target/iblock: Us...
685
686
  		 * Force writethrough using WRITE_FUA if a volatile write cache
  		 * is not enabled, or if initiator set the Force Unit Access bit.
dbbf3e94c   Christoph Hellwig   target: cleanup i...
687
  		 */
d0c8b259f   Nicholas Bellinger   target/iblock: Us...
688
689
690
691
692
  		if (q->flush_flags & REQ_FUA) {
  			if (cmd->se_cmd_flags & SCF_FUA)
  				rw = WRITE_FUA;
  			else if (!(q->flush_flags & REQ_FLUSH))
  				rw = WRITE_FUA;
d2bdbee0d   Nicholas Bellinger   target/iblock: Fi...
693
694
  			else
  				rw = WRITE;
d0c8b259f   Nicholas Bellinger   target/iblock: Us...
695
  		} else {
dbbf3e94c   Christoph Hellwig   target: cleanup i...
696
  			rw = WRITE;
d0c8b259f   Nicholas Bellinger   target/iblock: Us...
697
  		}
dbbf3e94c   Christoph Hellwig   target: cleanup i...
698
699
700
  	} else {
  		rw = READ;
  	}
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
701
  	/*
5787cacd0   Christoph Hellwig   target: remove st...
702
703
  	 * Convert the blocksize advertised to the initiator to the 512 byte
  	 * units unconditionally used by the Linux block layer.
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
704
  	 */
0fd97ccf4   Christoph Hellwig   target: kill stru...
705
  	if (dev->dev_attrib.block_size == 4096)
72a0e5e2e   Christoph Hellwig   target: remove th...
706
  		block_lba = (cmd->t_task_lba << 3);
0fd97ccf4   Christoph Hellwig   target: kill stru...
707
  	else if (dev->dev_attrib.block_size == 2048)
72a0e5e2e   Christoph Hellwig   target: remove th...
708
  		block_lba = (cmd->t_task_lba << 2);
0fd97ccf4   Christoph Hellwig   target: kill stru...
709
  	else if (dev->dev_attrib.block_size == 1024)
72a0e5e2e   Christoph Hellwig   target: remove th...
710
  		block_lba = (cmd->t_task_lba << 1);
0fd97ccf4   Christoph Hellwig   target: kill stru...
711
  	else if (dev->dev_attrib.block_size == 512)
72a0e5e2e   Christoph Hellwig   target: remove th...
712
  		block_lba = cmd->t_task_lba;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
713
  	else {
6708bb27b   Andy Grover   target: Follow up...
714
  		pr_err("Unsupported SCSI -> BLOCK LBA conversion:"
0fd97ccf4   Christoph Hellwig   target: kill stru...
715
716
  				" %u
  ", dev->dev_attrib.block_size);
de103c93a   Christoph Hellwig   target: pass sens...
717
  		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
718
  	}
5787cacd0   Christoph Hellwig   target: remove st...
719
720
721
722
  	ibr = kzalloc(sizeof(struct iblock_req), GFP_KERNEL);
  	if (!ibr)
  		goto fail;
  	cmd->priv = ibr;
e0de44573   Paolo Bonzini   target: do not su...
723
724
725
726
727
  	if (!sgl_nents) {
  		atomic_set(&ibr->pending, 1);
  		iblock_complete_cmd(cmd);
  		return 0;
  	}
5787cacd0   Christoph Hellwig   target: remove st...
728
729
730
  	bio = iblock_get_bio(cmd, block_lba, sgl_nents);
  	if (!bio)
  		goto fail_free_ibr;
dbbf3e94c   Christoph Hellwig   target: cleanup i...
731

ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
732
  	bio_start = bio;
dbbf3e94c   Christoph Hellwig   target: cleanup i...
733
734
  	bio_list_init(&list);
  	bio_list_add(&list, bio);
5787cacd0   Christoph Hellwig   target: remove st...
735
736
  
  	atomic_set(&ibr->pending, 2);
d5b4a21b3   Christoph Hellwig   target: increase ...
737
  	bio_cnt = 1;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
738

5787cacd0   Christoph Hellwig   target: remove st...
739
  	for_each_sg(sgl, sg, sgl_nents, i) {
dbbf3e94c   Christoph Hellwig   target: cleanup i...
740
741
742
743
744
745
746
  		/*
  		 * XXX: if the length the device accepts is shorter than the
  		 *	length of the S/G list entry this will cause and
  		 *	endless loop.  Better hope no driver uses huge pages.
  		 */
  		while (bio_add_page(bio, sg_page(sg), sg->length, sg->offset)
  				!= sg->length) {
d5b4a21b3   Christoph Hellwig   target: increase ...
747
748
749
750
  			if (bio_cnt >= IBLOCK_MAX_BIO_PER_TASK) {
  				iblock_submit_bios(&list, rw);
  				bio_cnt = 0;
  			}
5787cacd0   Christoph Hellwig   target: remove st...
751
  			bio = iblock_get_bio(cmd, block_lba, sg_num);
6708bb27b   Andy Grover   target: Follow up...
752
  			if (!bio)
5787cacd0   Christoph Hellwig   target: remove st...
753
754
755
  				goto fail_put_bios;
  
  			atomic_inc(&ibr->pending);
dbbf3e94c   Christoph Hellwig   target: cleanup i...
756
  			bio_list_add(&list, bio);
d5b4a21b3   Christoph Hellwig   target: increase ...
757
  			bio_cnt++;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
758
  		}
dbbf3e94c   Christoph Hellwig   target: cleanup i...
759

c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
760
761
762
  		/* Always in 512 byte units for Linux/Block */
  		block_lba += sg->length >> IBLOCK_LBA_SHIFT;
  		sg_num--;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
763
  	}
ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
764
765
766
767
768
  	if (cmd->prot_type) {
  		int rc = iblock_alloc_bip(cmd, bio_start);
  		if (rc)
  			goto fail_put_bios;
  	}
d5b4a21b3   Christoph Hellwig   target: increase ...
769
  	iblock_submit_bios(&list, rw);
5787cacd0   Christoph Hellwig   target: remove st...
770
  	iblock_complete_cmd(cmd);
03e98c9eb   Nicholas Bellinger   target: Address l...
771
  	return 0;
dbbf3e94c   Christoph Hellwig   target: cleanup i...
772

5787cacd0   Christoph Hellwig   target: remove st...
773
  fail_put_bios:
dbbf3e94c   Christoph Hellwig   target: cleanup i...
774
  	while ((bio = bio_list_pop(&list)))
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
775
  		bio_put(bio);
5787cacd0   Christoph Hellwig   target: remove st...
776
777
  fail_free_ibr:
  	kfree(ibr);
5787cacd0   Christoph Hellwig   target: remove st...
778
  fail:
de103c93a   Christoph Hellwig   target: pass sens...
779
  	return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
780
  }
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
781
782
  static sector_t iblock_get_blocks(struct se_device *dev)
  {
0fd97ccf4   Christoph Hellwig   target: kill stru...
783
784
  	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
  	struct block_device *bd = ib_dev->ibd_bd;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
785
786
787
788
  	struct request_queue *q = bdev_get_queue(bd);
  
  	return iblock_emulate_read_cap_with_block_size(dev, bd, q);
  }
7f7caf6aa   Andy Grover   target: Pass thro...
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
  static sector_t iblock_get_alignment_offset_lbas(struct se_device *dev)
  {
  	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
  	struct block_device *bd = ib_dev->ibd_bd;
  	int ret;
  
  	ret = bdev_alignment_offset(bd);
  	if (ret == -1)
  		return 0;
  
  	/* convert offset-bytes to offset-lbas */
  	return ret / bdev_logical_block_size(bd);
  }
  
  static unsigned int iblock_get_lbppbe(struct se_device *dev)
  {
  	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
  	struct block_device *bd = ib_dev->ibd_bd;
  	int logs_per_phys = bdev_physical_block_size(bd) / bdev_logical_block_size(bd);
  
  	return ilog2(logs_per_phys);
  }
  
  static unsigned int iblock_get_io_min(struct se_device *dev)
  {
  	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
  	struct block_device *bd = ib_dev->ibd_bd;
  
  	return bdev_io_min(bd);
  }
  
  static unsigned int iblock_get_io_opt(struct se_device *dev)
  {
  	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
  	struct block_device *bd = ib_dev->ibd_bd;
  
  	return bdev_io_opt(bd);
  }
9e999a6c5   Christoph Hellwig   target: rename sp...
827
  static struct sbc_ops iblock_sbc_ops = {
0c2ad7d11   Christoph Hellwig   target: add struc...
828
  	.execute_rw		= iblock_execute_rw,
ad67f0d9e   Christoph Hellwig   target: move sync...
829
  	.execute_sync_cache	= iblock_execute_sync_cache,
6f974e8ce   Christoph Hellwig   target: move writ...
830
  	.execute_write_same	= iblock_execute_write_same,
f6970ad31   Nicholas Bellinger   target/iblock: Ad...
831
  	.execute_write_same_unmap = iblock_execute_write_same_unmap,
14150a6bb   Christoph Hellwig   target: move unma...
832
  	.execute_unmap		= iblock_execute_unmap,
0c2ad7d11   Christoph Hellwig   target: add struc...
833
  };
de103c93a   Christoph Hellwig   target: pass sens...
834
835
  static sense_reason_t
  iblock_parse_cdb(struct se_cmd *cmd)
0c2ad7d11   Christoph Hellwig   target: add struc...
836
  {
9e999a6c5   Christoph Hellwig   target: rename sp...
837
  	return sbc_parse_cdb(cmd, &iblock_sbc_ops);
0c2ad7d11   Christoph Hellwig   target: add struc...
838
  }
452e20106   Rashika Kheria   drivers: target: ...
839
  static bool iblock_get_write_cache(struct se_device *dev)
d0c8b259f   Nicholas Bellinger   target/iblock: Us...
840
841
842
843
844
845
846
  {
  	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
  	struct block_device *bd = ib_dev->ibd_bd;
  	struct request_queue *q = bdev_get_queue(bd);
  
  	return q->flush_flags & REQ_FLUSH;
  }
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
847
848
  static struct se_subsystem_api iblock_template = {
  	.name			= "iblock",
0fd97ccf4   Christoph Hellwig   target: kill stru...
849
850
  	.inquiry_prod		= "IBLOCK",
  	.inquiry_rev		= IBLOCK_VERSION,
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
851
852
  	.owner			= THIS_MODULE,
  	.transport_type		= TRANSPORT_PLUGIN_VHBA_PDEV,
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
853
854
  	.attach_hba		= iblock_attach_hba,
  	.detach_hba		= iblock_detach_hba,
0fd97ccf4   Christoph Hellwig   target: kill stru...
855
856
  	.alloc_device		= iblock_alloc_device,
  	.configure_device	= iblock_configure_device,
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
857
  	.free_device		= iblock_free_device,
0c2ad7d11   Christoph Hellwig   target: add struc...
858
  	.parse_cdb		= iblock_parse_cdb,
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
859
860
  	.set_configfs_dev_params = iblock_set_configfs_dev_params,
  	.show_configfs_dev_params = iblock_show_configfs_dev_params,
6f23ac8a3   Christoph Hellwig   target: provide g...
861
  	.get_device_type	= sbc_get_device_type,
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
862
  	.get_blocks		= iblock_get_blocks,
7f7caf6aa   Andy Grover   target: Pass thro...
863
864
865
866
  	.get_alignment_offset_lbas = iblock_get_alignment_offset_lbas,
  	.get_lbppbe		= iblock_get_lbppbe,
  	.get_io_min		= iblock_get_io_min,
  	.get_io_opt		= iblock_get_io_opt,
d0c8b259f   Nicholas Bellinger   target/iblock: Us...
867
  	.get_write_cache	= iblock_get_write_cache,
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
868
869
870
871
872
873
  };
  
  static int __init iblock_module_init(void)
  {
  	return transport_subsystem_register(&iblock_template);
  }
63b91d5a4   Asias He   target: Add __exi...
874
  static void __exit iblock_module_exit(void)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
875
876
877
878
879
880
881
882
883
884
  {
  	transport_subsystem_release(&iblock_template);
  }
  
  MODULE_DESCRIPTION("TCM IBLOCK subsystem plugin");
  MODULE_AUTHOR("nab@Linux-iSCSI.org");
  MODULE_LICENSE("GPL");
  
  module_init(iblock_module_init);
  module_exit(iblock_module_exit);