2 * Target device block I/O.
4 * Based on file I/O driver from FUJITA Tomonori
5 * (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org>
6 * (C) 2006 Andre Brinkmann <brinkman at hni dot upb dot de>
7 * (C) 2007 Ross Walker <rswwalker at hotmail dot com>
8 * (C) 2007 Ming Zhang <blackmagic02881 at gmail dot com>
9 * This code is licenced under the GPL.
12 #include <linux/types.h>
13 #include <linux/blkdev.h>
14 #include <linux/parser.h>
15 #include <linux/buffer_head.h>
18 #include "iscsi_dbg.h"
23 struct block_device *bdev;
28 atomic_t bios_remaining;
29 struct completion tio_complete;
32 static void blockio_bio_endio(struct bio *bio, int error)
34 struct tio_work *tio_work = bio->bi_private;
36 error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? error : -EIO;
39 atomic_set(&tio_work->error, error);
41 /* If last bio signal completion */
42 if (atomic_dec_and_test(&tio_work->bios_remaining))
43 complete(&tio_work->tio_complete);
49 * Blockio_make_request(): The function translates an iscsi-request into
50 * a number of requests to the corresponding block device.
53 blockio_make_request(struct iet_volume *volume, struct tio *tio, int rw)
55 struct blockio_data *bio_data = volume->private;
56 struct request_queue *bdev_q = bdev_get_queue(bio_data->bdev);
57 struct tio_work *tio_work;
58 struct bio *tio_bio = NULL, *bio = NULL, *biotail = NULL;
60 u32 offset = tio->offset;
67 loff_t ppos = ((loff_t) tio->idx << PAGE_SHIFT) + offset;
69 /* Calculate max_pages for bio_alloc (memory saver) */
71 max_pages = bio_get_nr_vecs(bio_data->bdev);
73 tio_work = kzalloc(sizeof (*tio_work), GFP_KERNEL);
77 atomic_set(&tio_work->error, 0);
78 atomic_set(&tio_work->bios_remaining, 0);
79 init_completion(&tio_work->tio_complete);
81 /* Main processing loop, allocate and fill all bios */
82 while (tio_index < tio->pg_cnt) {
83 bio = bio_alloc(GFP_KERNEL, min(max_pages, BIO_MAX_PAGES));
89 /* bi_sector is ALWAYS in units of 512 bytes */
90 bio->bi_sector = ppos >> 9;
91 bio->bi_bdev = bio_data->bdev;
92 bio->bi_end_io = blockio_bio_endio;
93 bio->bi_private = tio_work;
96 biotail = biotail->bi_next = bio;
98 tio_bio = biotail = bio;
100 atomic_inc(&tio_work->bios_remaining);
102 /* Loop for filling bio */
103 while (tio_index < tio->pg_cnt) {
104 unsigned int bytes = PAGE_SIZE - offset;
109 if (!bio_add_page(bio, tio->pvec[tio_index], bytes, offset))
121 /* Walk the list, submitting bios 1 by 1 */
124 tio_bio = tio_bio->bi_next;
130 if (bdev_q && bdev_q->unplug_fn)
131 bdev_q->unplug_fn(bdev_q);
133 wait_for_completion(&tio_work->tio_complete);
135 err = atomic_read(&tio_work->error);
143 tio_bio = tio_bio->bi_next;
154 blockio_open_path(struct iet_volume *volume, const char *path)
156 struct blockio_data *bio_data = volume->private;
157 struct block_device *bdev;
158 int flags = FMODE_READ | (LUReadonly(volume) ? 0 : FMODE_WRITE);
161 bio_data->path = kstrdup(path, GFP_KERNEL);
165 bdev = blkdev_get_by_path(path, flags | FMODE_EXCL, THIS_MODULE);
168 eprintk("Can't open device %s, error %d\n", path, err);
169 bio_data->bdev = NULL;
171 bio_data->bdev = bdev;
172 fsync_bdev(bio_data->bdev);
178 /* Create an enumeration of our accepted actions */
181 opt_path, opt_ignore, opt_err,
184 /* Create a match table using our action enums and their matching options */
185 static match_table_t tokens = {
186 {opt_path, "path=%s"},
187 {opt_ignore, "scsiid=%s"},
188 {opt_ignore, "scsisn=%s"},
189 {opt_ignore, "type=%s"},
190 {opt_ignore, "iomode=%s"},
191 {opt_ignore, "blocksize=%s"},
196 parse_blockio_params(struct iet_volume *volume, char *params)
198 struct blockio_data *info = volume->private;
202 /* Loop through parameters separated by commas, look up our
203 * parameter in match table, return enumeration and arguments
204 * select case based on the returned enum and run the action */
205 while ((p = strsep(¶ms, ",")) != NULL) {
206 substring_t args[MAX_OPT_ARGS];
211 token = match_token(p, tokens, args);
215 iprintk("Target %s, LUN %u: "
216 "duplicate \"Path\" param\n",
217 volume->target->name, volume->lun);
221 if (!(q = match_strdup(&args[0]))) {
225 err = blockio_open_path(volume, q);
233 iprintk("Target %s, LUN %u: unknown param %s\n",
234 volume->target->name, volume->lun, p);
240 iprintk("Target %s, LUN %u: missing \"Path\" param\n",
241 volume->target->name, volume->lun);
250 blockio_detach(struct iet_volume *volume)
252 struct blockio_data *bio_data = volume->private;
253 int flags = FMODE_READ | (LUReadonly(volume) ? 0 : FMODE_WRITE);
256 blkdev_put(bio_data->bdev, flags | FMODE_EXCL);
257 kfree(bio_data->path);
259 kfree(volume->private);
263 blockio_attach(struct iet_volume *volume, char *args)
265 struct blockio_data *bio_data;
268 if (volume->private) {
269 eprintk("Lun %u already attached on Target %s \n",
270 volume->lun, volume->target->name);
274 bio_data = kzalloc(sizeof (*bio_data), GFP_KERNEL);
278 volume->private = bio_data;
280 err = parse_blockio_params(volume, args);
282 /* see Documentation/ABI/testing/sysfs-block */
283 unsigned bsz = bdev_logical_block_size(bio_data->bdev);
284 if (!volume->blk_shift)
285 volume->blk_shift = blksize_bits(bsz);
286 else if (volume->blk_shift < blksize_bits(bsz)) {
287 eprintk("Specified block size (%u) smaller than "
288 "device %s logical block size (%u)\n",
289 (1 << volume->blk_shift), bio_data->path, bsz);
294 eprintk("Error attaching Lun %u to Target %s \n",
295 volume->lun, volume->target->name);
299 volume->blk_cnt = bio_data->bdev->bd_inode->i_size >> volume->blk_shift;
301 /* Offer neither write nor read caching */
302 ClearLURCache(volume);
303 ClearLUWCache(volume);
307 blockio_detach(volume);
313 blockio_show(struct iet_volume *volume, struct seq_file *seq)
315 struct blockio_data *bio_data = volume->private;
317 /* Used to display blockio volume info in /proc/net/iet/volumes */
318 seq_printf(seq, " path:%s\n", bio_data->path);
321 struct iotype blockio = {
323 .attach = blockio_attach,
324 .make_request = blockio_make_request,
325 .detach = blockio_detach,
326 .show = blockio_show,