Blame view

drivers/target/target_core_iblock.c 20.9 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>
ba9299925   Bart Van Assche   target: Minimize ...
37
  #include <scsi/scsi_proto.h>
14150a6bb   Christoph Hellwig   target: move unma...
38
  #include <asm/unaligned.h>
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
39
40
  
  #include <target/target_core_base.h>
c4795fb20   Christoph Hellwig   target: header re...
41
  #include <target/target_core_backend.h>
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
42
43
  
  #include "target_core_iblock.h"
d5b4a21b3   Christoph Hellwig   target: increase ...
44
45
  #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...
46
47
48
49
  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...
50
51
  static int iblock_attach_hba(struct se_hba *hba, u32 host_id)
  {
6708bb27b   Andy Grover   target: Follow up...
52
  	pr_debug("CORE_HBA[%d] - TCM iBlock HBA Driver %s on"
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
53
54
  		" Generic Target Core Stack %s
  ", hba->hba_id,
ce8dd25d0   Christoph Hellwig   target: consolida...
55
  		IBLOCK_VERSION, TARGET_CORE_VERSION);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
56
57
58
59
60
  	return 0;
  }
  
  static void iblock_detach_hba(struct se_hba *hba)
  {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
61
  }
0fd97ccf4   Christoph Hellwig   target: kill stru...
62
  static struct se_device *iblock_alloc_device(struct se_hba *hba, const char *name)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
63
64
  {
  	struct iblock_dev *ib_dev = NULL;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
65
66
  
  	ib_dev = kzalloc(sizeof(struct iblock_dev), GFP_KERNEL);
6708bb27b   Andy Grover   target: Follow up...
67
68
69
  	if (!ib_dev) {
  		pr_err("Unable to allocate struct iblock_dev
  ");
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
70
71
  		return NULL;
  	}
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
72

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

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

0fd97ccf4   Christoph Hellwig   target: kill stru...
87
88
89
90
  	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...
91
  	}
d5b4a21b3   Christoph Hellwig   target: increase ...
92
93
  
  	ib_dev->ibd_bio_set = bioset_create(IBLOCK_BIO_POOL_SIZE, 0);
6708bb27b   Andy Grover   target: Follow up...
94
  	if (!ib_dev->ibd_bio_set) {
0fd97ccf4   Christoph Hellwig   target: kill stru...
95
96
97
  		pr_err("IBLOCK: Unable to create bioset
  ");
  		goto out;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
98
  	}
0fd97ccf4   Christoph Hellwig   target: kill stru...
99

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

8a9ebe717   Mike Christie   target: Fix WRITE...
121
122
  	if (target_configure_unmap_from_queue(&dev->dev_attrib, q,
  					      dev->dev_attrib.hw_block_size))
6708bb27b   Andy Grover   target: Follow up...
123
  		pr_debug("IBLOCK: BLOCK Discard support available,"
8a9ebe717   Mike Christie   target: Fix WRITE...
124
125
  			 " disabled by default
  ");
f6970ad31   Nicholas Bellinger   target/iblock: Ad...
126
127
128
129
130
  	/*
  	 * 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...
131

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

ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
135
136
137
  	bi = bdev_get_integrity(bd);
  	if (bi) {
  		struct bio_set *bs = ib_dev->ibd_bio_set;
0f8087ecd   Martin K. Petersen   block: Consolidat...
138
139
  		if (!strcmp(bi->profile->name, "T10-DIF-TYPE3-IP") ||
  		    !strcmp(bi->profile->name, "T10-DIF-TYPE1-IP")) {
ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
140
  			pr_err("IBLOCK export of blk_integrity: %s not"
0f8087ecd   Martin K. Petersen   block: Consolidat...
141
142
  			       " supported
  ", bi->profile->name);
ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
143
144
145
  			ret = -ENOSYS;
  			goto out_blkdev_put;
  		}
0f8087ecd   Martin K. Petersen   block: Consolidat...
146
  		if (!strcmp(bi->profile->name, "T10-DIF-TYPE3-CRC")) {
ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
147
  			dev->dev_attrib.pi_prot_type = TARGET_DIF_TYPE3_PROT;
0f8087ecd   Martin K. Petersen   block: Consolidat...
148
  		} else if (!strcmp(bi->profile->name, "T10-DIF-TYPE1-CRC")) {
ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
  			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...
165
  	return 0;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
166

ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
167
168
  out_blkdev_put:
  	blkdev_put(ib_dev->ibd_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL);
0fd97ccf4   Christoph Hellwig   target: kill stru...
169
170
171
172
173
  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...
174
  }
4cc987eaf   Nicholas Bellinger   target: Drop lun_...
175
176
177
178
179
180
181
  static void iblock_dev_call_rcu(struct rcu_head *p)
  {
  	struct se_device *dev = container_of(p, struct se_device, rcu_head);
  	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
  
  	kfree(ib_dev);
  }
0fd97ccf4   Christoph Hellwig   target: kill stru...
182
  static void iblock_free_device(struct se_device *dev)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
183
  {
0fd97ccf4   Christoph Hellwig   target: kill stru...
184
  	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
185

bc6655247   Nicholas Bellinger   [SCSI] target/ibl...
186
187
  	if (ib_dev->ibd_bd != NULL)
  		blkdev_put(ib_dev->ibd_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL);
d84287bcf   Nicholas Bellinger   target/iblock: Fi...
188
  	if (ib_dev->ibd_bio_set != NULL)
bc6655247   Nicholas Bellinger   [SCSI] target/ibl...
189
  		bioset_free(ib_dev->ibd_bio_set);
d84287bcf   Nicholas Bellinger   target/iblock: Fi...
190

4cc987eaf   Nicholas Bellinger   target: Drop lun_...
191
  	call_rcu(&dev->rcu_head, iblock_dev_call_rcu);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
192
  }
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
193
194
195
196
197
198
199
200
  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...
201
  	if (block_size == dev->dev_attrib.block_size)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
202
203
204
205
  		return blocks_long;
  
  	switch (block_size) {
  	case 4096:
0fd97ccf4   Christoph Hellwig   target: kill stru...
206
  		switch (dev->dev_attrib.block_size) {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
207
208
209
210
211
212
213
214
215
216
217
218
219
  		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...
220
  		switch (dev->dev_attrib.block_size) {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
221
222
223
224
225
226
227
228
229
230
231
232
233
234
  		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...
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 >>= 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...
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
265
266
267
268
269
  		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...
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
  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);
  }
4246a0b63   Christoph Hellwig   block: add a bi_e...
286
  static void iblock_bio_done(struct bio *bio)
3a41d85fe   Nicholas Bellinger   target/iblock: Fo...
287
288
289
  {
  	struct se_cmd *cmd = bio->bi_private;
  	struct iblock_req *ibr = cmd->priv;
4246a0b63   Christoph Hellwig   block: add a bi_e...
290
291
292
  	if (bio->bi_error) {
  		pr_err("bio error: %p,  err: %d
  ", bio, bio->bi_error);
3a41d85fe   Nicholas Bellinger   target/iblock: Fo...
293
294
295
296
  		/*
  		 * Bump the ib_bio_err_cnt and release bio.
  		 */
  		atomic_inc(&ibr->ib_bio_err_cnt);
4e857c58e   Peter Zijlstra   arch: Mass conver...
297
  		smp_mb__after_atomic();
3a41d85fe   Nicholas Bellinger   target/iblock: Fo...
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
  	}
  
  	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...
328
  	bio->bi_iter.bi_sector = lba;
3a41d85fe   Nicholas Bellinger   target/iblock: Fo...
329
330
331
332
333
334
335
336
337
338
339
340
341
342
  
  	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);
  }
4246a0b63   Christoph Hellwig   block: add a bi_e...
343
  static void iblock_end_io_flush(struct bio *bio)
df5fa691c   Christoph Hellwig   target: make iblo...
344
345
  {
  	struct se_cmd *cmd = bio->bi_private;
4246a0b63   Christoph Hellwig   block: add a bi_e...
346
347
348
  	if (bio->bi_error)
  		pr_err("IBLOCK: cache flush failed: %d
  ", bio->bi_error);
df5fa691c   Christoph Hellwig   target: make iblo...
349

5787cacd0   Christoph Hellwig   target: remove st...
350
  	if (cmd) {
4246a0b63   Christoph Hellwig   block: add a bi_e...
351
  		if (bio->bi_error)
5787cacd0   Christoph Hellwig   target: remove st...
352
  			target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION);
de103c93a   Christoph Hellwig   target: pass sens...
353
  		else
5787cacd0   Christoph Hellwig   target: remove st...
354
  			target_complete_cmd(cmd, SAM_STAT_GOOD);
5787cacd0   Christoph Hellwig   target: remove st...
355
  	}
df5fa691c   Christoph Hellwig   target: make iblo...
356
357
  	bio_put(bio);
  }
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
358
  /*
df5fa691c   Christoph Hellwig   target: make iblo...
359
360
   * Implement SYCHRONIZE CACHE.  Note that we can't handle lba ranges and must
   * always flush the whole cache.
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
361
   */
de103c93a   Christoph Hellwig   target: pass sens...
362
363
  static sense_reason_t
  iblock_execute_sync_cache(struct se_cmd *cmd)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
364
  {
0fd97ccf4   Christoph Hellwig   target: kill stru...
365
  	struct iblock_dev *ib_dev = IBLOCK_DEV(cmd->se_dev);
a1d8b49ab   Andy Grover   target: Updates f...
366
  	int immed = (cmd->t_task_cdb[1] & 0x2);
df5fa691c   Christoph Hellwig   target: make iblo...
367
  	struct bio *bio;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
368
369
370
  
  	/*
  	 * If the Immediate bit is set, queue up the GOOD response
df5fa691c   Christoph Hellwig   target: make iblo...
371
  	 * for this SYNCHRONIZE_CACHE op.
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
372
373
  	 */
  	if (immed)
5787cacd0   Christoph Hellwig   target: remove st...
374
  		target_complete_cmd(cmd, SAM_STAT_GOOD);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
375

df5fa691c   Christoph Hellwig   target: make iblo...
376
377
378
  	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...
379
  	if (!immed)
df5fa691c   Christoph Hellwig   target: make iblo...
380
381
  		bio->bi_private = cmd;
  	submit_bio(WRITE_FLUSH, bio);
ad67f0d9e   Christoph Hellwig   target: move sync...
382
  	return 0;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
383
  }
de103c93a   Christoph Hellwig   target: pass sens...
384
  static sense_reason_t
62e469425   Christoph Hellwig   target: simplify ...
385
  iblock_execute_unmap(struct se_cmd *cmd, sector_t lba, sector_t nolb)
dbc21c5ab   Asias He   target/iblock: Ad...
386
  {
62e469425   Christoph Hellwig   target: simplify ...
387
  	struct block_device *bdev = IBLOCK_DEV(cmd->se_dev)->ibd_bd;
8a9ebe717   Mike Christie   target: Fix WRITE...
388
  	struct se_device *dev = cmd->se_dev;
dbc21c5ab   Asias He   target/iblock: Ad...
389
  	int ret;
8a9ebe717   Mike Christie   target: Fix WRITE...
390
391
392
393
  	ret = blkdev_issue_discard(bdev,
  				   target_to_linux_sector(dev, lba),
  				   target_to_linux_sector(dev,  nolb),
  				   GFP_KERNEL, 0);
dbc21c5ab   Asias He   target/iblock: Ad...
394
395
396
397
398
399
400
401
402
403
  	if (ret < 0) {
  		pr_err("blkdev_issue_discard() failed: %d
  ", ret);
  		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
  	}
  
  	return 0;
  }
  
  static sense_reason_t
07b631968   Mike Christie   target/iblock: pa...
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
  iblock_execute_write_same_direct(struct block_device *bdev, struct se_cmd *cmd)
  {
  	struct se_device *dev = cmd->se_dev;
  	struct scatterlist *sg = &cmd->t_data_sg[0];
  	struct page *page = NULL;
  	int ret;
  
  	if (sg->offset) {
  		page = alloc_page(GFP_KERNEL);
  		if (!page)
  			return TCM_OUT_OF_RESOURCES;
  		sg_copy_to_buffer(sg, cmd->t_data_nents, page_address(page),
  				  dev->dev_attrib.block_size);
  	}
  
  	ret = blkdev_issue_write_same(bdev,
  				target_to_linux_sector(dev, cmd->t_task_lba),
  				target_to_linux_sector(dev,
  					sbc_get_write_same_sectors(cmd)),
  				GFP_KERNEL, page ? page : sg_page(sg));
  	if (page)
  		__free_page(page);
  	if (ret)
  		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
  
  	target_complete_cmd(cmd, GOOD);
  	return 0;
  }
  
  static sense_reason_t
f6970ad31   Nicholas Bellinger   target/iblock: Ad...
434
435
  iblock_execute_write_same(struct se_cmd *cmd)
  {
07b631968   Mike Christie   target/iblock: pa...
436
  	struct block_device *bdev = IBLOCK_DEV(cmd->se_dev)->ibd_bd;
f6970ad31   Nicholas Bellinger   target/iblock: Ad...
437
438
439
440
  	struct iblock_req *ibr;
  	struct scatterlist *sg;
  	struct bio *bio;
  	struct bio_list list;
8a9ebe717   Mike Christie   target: Fix WRITE...
441
442
443
444
  	struct se_device *dev = cmd->se_dev;
  	sector_t block_lba = target_to_linux_sector(dev, cmd->t_task_lba);
  	sector_t sectors = target_to_linux_sector(dev,
  					sbc_get_write_same_sectors(cmd));
f6970ad31   Nicholas Bellinger   target/iblock: Ad...
445

afd73f1b6   Nicholas Bellinger   target: Perform P...
446
447
448
449
450
451
  	if (cmd->prot_op) {
  		pr_err("WRITE_SAME: Protection information with IBLOCK"
  		       " backends not supported
  ");
  		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
  	}
f6970ad31   Nicholas Bellinger   target/iblock: Ad...
452
453
454
455
456
457
458
459
460
461
  	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;
  	}
07b631968   Mike Christie   target/iblock: pa...
462
463
  	if (bdev_write_same(bdev))
  		return iblock_execute_write_same_direct(bdev, cmd);
f6970ad31   Nicholas Bellinger   target/iblock: Ad...
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
  	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...
506
  enum {
44bfd0185   Andy Grover   target/iblock: Ad...
507
  	Opt_udev_path, Opt_readonly, Opt_force, Opt_err
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
508
509
510
511
  };
  
  static match_table_t tokens = {
  	{Opt_udev_path, "udev_path=%s"},
44bfd0185   Andy Grover   target/iblock: Ad...
512
  	{Opt_readonly, "readonly=%d"},
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
513
514
515
  	{Opt_force, "force=%d"},
  	{Opt_err, NULL}
  };
0fd97ccf4   Christoph Hellwig   target: kill stru...
516
517
  static ssize_t iblock_set_configfs_dev_params(struct se_device *dev,
  		const char *page, ssize_t count)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
518
  {
0fd97ccf4   Christoph Hellwig   target: kill stru...
519
  	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
6d1802539   Jesper Juhl   [SCSI] target: Fi...
520
  	char *orig, *ptr, *arg_p, *opts;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
521
  	substring_t args[MAX_OPT_ARGS];
21bca31c9   Roland Dreier   target/iblock: Re...
522
  	int ret = 0, token;
44bfd0185   Andy Grover   target/iblock: Ad...
523
  	unsigned long tmp_readonly;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
524
525
526
527
528
529
  
  	opts = kstrdup(page, GFP_KERNEL);
  	if (!opts)
  		return -ENOMEM;
  
  	orig = opts;
90c161b64   Sebastian Andrzej Siewior   target: use \n as...
530
531
  	while ((ptr = strsep(&opts, ",
  ")) != NULL) {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
532
533
534
535
536
537
538
  		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...
539
  				pr_err("Unable to set udev_path= while"
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
540
541
542
543
544
  					" ib_dev->ibd_bd exists
  ");
  				ret = -EEXIST;
  				goto out;
  			}
852b6ed11   Nicholas Bellinger   target/iblock: Us...
545
546
547
  			if (match_strlcpy(ib_dev->ibd_udev_path, &args[0],
  				SE_UDEV_PATH_LEN) == 0) {
  				ret = -EINVAL;
6d1802539   Jesper Juhl   [SCSI] target: Fi...
548
549
  				break;
  			}
6708bb27b   Andy Grover   target: Follow up...
550
551
  			pr_debug("IBLOCK: Referencing UDEV path: %s
  ",
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
552
553
554
  					ib_dev->ibd_udev_path);
  			ib_dev->ibd_flags |= IBDF_HAS_UDEV_PATH;
  			break;
44bfd0185   Andy Grover   target/iblock: Ad...
555
556
557
558
559
560
  		case Opt_readonly:
  			arg_p = match_strdup(&args[0]);
  			if (!arg_p) {
  				ret = -ENOMEM;
  				break;
  			}
57103d7fe   Jingoo Han   target: replace s...
561
  			ret = kstrtoul(arg_p, 0, &tmp_readonly);
44bfd0185   Andy Grover   target/iblock: Ad...
562
563
  			kfree(arg_p);
  			if (ret < 0) {
57103d7fe   Jingoo Han   target: replace s...
564
  				pr_err("kstrtoul() failed for"
44bfd0185   Andy Grover   target/iblock: Ad...
565
566
567
568
569
570
571
572
  						" 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...
573
  		case Opt_force:
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
574
575
576
577
578
579
580
581
582
583
  			break;
  		default:
  			break;
  		}
  	}
  
  out:
  	kfree(orig);
  	return (!ret) ? count : ret;
  }
0fd97ccf4   Christoph Hellwig   target: kill stru...
584
  static ssize_t iblock_show_configfs_dev_params(struct se_device *dev, char *b)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
585
  {
0fd97ccf4   Christoph Hellwig   target: kill stru...
586
587
  	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
  	struct block_device *bd = ib_dev->ibd_bd;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
588
589
590
591
592
593
  	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...
594
  	if (ib_dev->ibd_flags & IBDF_HAS_UDEV_PATH)
44bfd0185   Andy Grover   target/iblock: Ad...
595
  		bl += sprintf(b + bl, "  UDEV PATH: %s",
0fd97ccf4   Christoph Hellwig   target: kill stru...
596
597
598
  				ib_dev->ibd_udev_path);
  	bl += sprintf(b + bl, "  readonly: %d
  ", ib_dev->ibd_readonly);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
599
600
601
602
603
  
  	bl += sprintf(b + bl, "        ");
  	if (bd) {
  		bl += sprintf(b + bl, "Major: %d Minor: %d  %s
  ",
21bca31c9   Roland Dreier   target/iblock: Re...
604
  			MAJOR(bd->bd_dev), MINOR(bd->bd_dev), (!bd->bd_contains) ?
0fd97ccf4   Christoph Hellwig   target: kill stru...
605
  			"" : (bd->bd_holder == ib_dev) ?
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
606
607
  			"CLAIMED: IBLOCK" : "CLAIMED: OS");
  	} else {
21bca31c9   Roland Dreier   target/iblock: Re...
608
609
  		bl += sprintf(b + bl, "Major: 0 Minor: 0
  ");
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
610
611
612
613
  	}
  
  	return bl;
  }
ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
  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);
06c1e3902   Keith Busch   blk-integrity: em...
632
  	if (IS_ERR(bip)) {
ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
633
634
  		pr_err("Unable to allocate bio_integrity_payload
  ");
06c1e3902   Keith Busch   blk-integrity: em...
635
  		return PTR_ERR(bip);
ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
636
  	}
4e13c5d02   Linus Torvalds   Merge branch 'for...
637
  	bip->bip_iter.bi_size = (cmd->data_length / dev->dev_attrib.block_size) *
ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
638
  			 dev->prot_length;
4e13c5d02   Linus Torvalds   Merge branch 'for...
639
  	bip->bip_iter.bi_sector = bio->bi_iter.bi_sector;
ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
640

4e13c5d02   Linus Torvalds   Merge branch 'for...
641
642
643
  	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...
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
  
  	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...
662
  static sense_reason_t
a82a9538d   Nicholas Bellinger   target: Allow sbc...
663
664
  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...
665
  {
5951146de   Andy Grover   target: More core...
666
  	struct se_device *dev = cmd->se_dev;
8a9ebe717   Mike Christie   target: Fix WRITE...
667
  	sector_t block_lba = target_to_linux_sector(dev, cmd->t_task_lba);
5787cacd0   Christoph Hellwig   target: remove st...
668
  	struct iblock_req *ibr;
ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
669
  	struct bio *bio, *bio_start;
dbbf3e94c   Christoph Hellwig   target: cleanup i...
670
  	struct bio_list list;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
671
  	struct scatterlist *sg;
5787cacd0   Christoph Hellwig   target: remove st...
672
  	u32 sg_num = sgl_nents;
d5b4a21b3   Christoph Hellwig   target: increase ...
673
  	unsigned bio_cnt;
d0c8b259f   Nicholas Bellinger   target/iblock: Us...
674
  	int rw = 0;
5787cacd0   Christoph Hellwig   target: remove st...
675
  	int i;
dbbf3e94c   Christoph Hellwig   target: cleanup i...
676

5787cacd0   Christoph Hellwig   target: remove st...
677
  	if (data_direction == DMA_TO_DEVICE) {
d0c8b259f   Nicholas Bellinger   target/iblock: Us...
678
679
  		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...
680
  		/*
d0c8b259f   Nicholas Bellinger   target/iblock: Us...
681
682
  		 * 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...
683
  		 */
d0c8b259f   Nicholas Bellinger   target/iblock: Us...
684
685
686
687
688
  		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...
689
690
  			else
  				rw = WRITE;
d0c8b259f   Nicholas Bellinger   target/iblock: Us...
691
  		} else {
dbbf3e94c   Christoph Hellwig   target: cleanup i...
692
  			rw = WRITE;
d0c8b259f   Nicholas Bellinger   target/iblock: Us...
693
  		}
dbbf3e94c   Christoph Hellwig   target: cleanup i...
694
695
696
  	} else {
  		rw = READ;
  	}
5787cacd0   Christoph Hellwig   target: remove st...
697
698
699
700
  	ibr = kzalloc(sizeof(struct iblock_req), GFP_KERNEL);
  	if (!ibr)
  		goto fail;
  	cmd->priv = ibr;
e0de44573   Paolo Bonzini   target: do not su...
701
702
703
704
705
  	if (!sgl_nents) {
  		atomic_set(&ibr->pending, 1);
  		iblock_complete_cmd(cmd);
  		return 0;
  	}
5787cacd0   Christoph Hellwig   target: remove st...
706
707
708
  	bio = iblock_get_bio(cmd, block_lba, sgl_nents);
  	if (!bio)
  		goto fail_free_ibr;
dbbf3e94c   Christoph Hellwig   target: cleanup i...
709

ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
710
  	bio_start = bio;
dbbf3e94c   Christoph Hellwig   target: cleanup i...
711
712
  	bio_list_init(&list);
  	bio_list_add(&list, bio);
5787cacd0   Christoph Hellwig   target: remove st...
713
714
  
  	atomic_set(&ibr->pending, 2);
d5b4a21b3   Christoph Hellwig   target: increase ...
715
  	bio_cnt = 1;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
716

5787cacd0   Christoph Hellwig   target: remove st...
717
  	for_each_sg(sgl, sg, sgl_nents, i) {
dbbf3e94c   Christoph Hellwig   target: cleanup i...
718
719
720
721
722
723
724
  		/*
  		 * 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 ...
725
726
727
728
  			if (bio_cnt >= IBLOCK_MAX_BIO_PER_TASK) {
  				iblock_submit_bios(&list, rw);
  				bio_cnt = 0;
  			}
5787cacd0   Christoph Hellwig   target: remove st...
729
  			bio = iblock_get_bio(cmd, block_lba, sg_num);
6708bb27b   Andy Grover   target: Follow up...
730
  			if (!bio)
5787cacd0   Christoph Hellwig   target: remove st...
731
732
733
  				goto fail_put_bios;
  
  			atomic_inc(&ibr->pending);
dbbf3e94c   Christoph Hellwig   target: cleanup i...
734
  			bio_list_add(&list, bio);
d5b4a21b3   Christoph Hellwig   target: increase ...
735
  			bio_cnt++;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
736
  		}
dbbf3e94c   Christoph Hellwig   target: cleanup i...
737

c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
738
739
740
  		/* Always in 512 byte units for Linux/Block */
  		block_lba += sg->length >> IBLOCK_LBA_SHIFT;
  		sg_num--;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
741
  	}
6f16ec43e   Nicholas Bellinger   target/iblock: Ad...
742
  	if (cmd->prot_type && dev->dev_attrib.pi_prot_type) {
ecebbf6cc   Nicholas Bellinger   target/iblock: Ad...
743
744
745
746
  		int rc = iblock_alloc_bip(cmd, bio_start);
  		if (rc)
  			goto fail_put_bios;
  	}
d5b4a21b3   Christoph Hellwig   target: increase ...
747
  	iblock_submit_bios(&list, rw);
5787cacd0   Christoph Hellwig   target: remove st...
748
  	iblock_complete_cmd(cmd);
03e98c9eb   Nicholas Bellinger   target: Address l...
749
  	return 0;
dbbf3e94c   Christoph Hellwig   target: cleanup i...
750

5787cacd0   Christoph Hellwig   target: remove st...
751
  fail_put_bios:
dbbf3e94c   Christoph Hellwig   target: cleanup i...
752
  	while ((bio = bio_list_pop(&list)))
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
753
  		bio_put(bio);
5787cacd0   Christoph Hellwig   target: remove st...
754
755
  fail_free_ibr:
  	kfree(ibr);
5787cacd0   Christoph Hellwig   target: remove st...
756
  fail:
de103c93a   Christoph Hellwig   target: pass sens...
757
  	return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
758
  }
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
759
760
  static sector_t iblock_get_blocks(struct se_device *dev)
  {
0fd97ccf4   Christoph Hellwig   target: kill stru...
761
762
  	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
  	struct block_device *bd = ib_dev->ibd_bd;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
763
764
765
766
  	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...
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
  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...
805
  static struct sbc_ops iblock_sbc_ops = {
0c2ad7d11   Christoph Hellwig   target: add struc...
806
  	.execute_rw		= iblock_execute_rw,
ad67f0d9e   Christoph Hellwig   target: move sync...
807
  	.execute_sync_cache	= iblock_execute_sync_cache,
6f974e8ce   Christoph Hellwig   target: move writ...
808
  	.execute_write_same	= iblock_execute_write_same,
14150a6bb   Christoph Hellwig   target: move unma...
809
  	.execute_unmap		= iblock_execute_unmap,
0c2ad7d11   Christoph Hellwig   target: add struc...
810
  };
de103c93a   Christoph Hellwig   target: pass sens...
811
812
  static sense_reason_t
  iblock_parse_cdb(struct se_cmd *cmd)
0c2ad7d11   Christoph Hellwig   target: add struc...
813
  {
9e999a6c5   Christoph Hellwig   target: rename sp...
814
  	return sbc_parse_cdb(cmd, &iblock_sbc_ops);
0c2ad7d11   Christoph Hellwig   target: add struc...
815
  }
452e20106   Rashika Kheria   drivers: target: ...
816
  static bool iblock_get_write_cache(struct se_device *dev)
d0c8b259f   Nicholas Bellinger   target/iblock: Us...
817
818
819
820
821
822
823
  {
  	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;
  }
0a06d4309   Christoph Hellwig   target: simplify ...
824
  static const struct target_backend_ops iblock_ops = {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
825
  	.name			= "iblock",
0fd97ccf4   Christoph Hellwig   target: kill stru...
826
827
  	.inquiry_prod		= "IBLOCK",
  	.inquiry_rev		= IBLOCK_VERSION,
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
828
  	.owner			= THIS_MODULE,
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
829
830
  	.attach_hba		= iblock_attach_hba,
  	.detach_hba		= iblock_detach_hba,
0fd97ccf4   Christoph Hellwig   target: kill stru...
831
832
  	.alloc_device		= iblock_alloc_device,
  	.configure_device	= iblock_configure_device,
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
833
  	.free_device		= iblock_free_device,
0c2ad7d11   Christoph Hellwig   target: add struc...
834
  	.parse_cdb		= iblock_parse_cdb,
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
835
836
  	.set_configfs_dev_params = iblock_set_configfs_dev_params,
  	.show_configfs_dev_params = iblock_show_configfs_dev_params,
6f23ac8a3   Christoph Hellwig   target: provide g...
837
  	.get_device_type	= sbc_get_device_type,
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
838
  	.get_blocks		= iblock_get_blocks,
7f7caf6aa   Andy Grover   target: Pass thro...
839
840
841
842
  	.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...
843
  	.get_write_cache	= iblock_get_write_cache,
5873c4d15   Christoph Hellwig   target: consolida...
844
  	.tb_dev_attrib_attrs	= sbc_attrib_attrs,
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
845
846
847
848
  };
  
  static int __init iblock_module_init(void)
  {
0a06d4309   Christoph Hellwig   target: simplify ...
849
  	return transport_backend_register(&iblock_ops);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
850
  }
63b91d5a4   Asias He   target: Add __exi...
851
  static void __exit iblock_module_exit(void)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
852
  {
0a06d4309   Christoph Hellwig   target: simplify ...
853
  	target_backend_unregister(&iblock_ops);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
854
855
856
857
858
859
860
861
  }
  
  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);