3
* (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org>
4
* This code is licenced under the GPL.
7
#include <linux/types.h>
8
#include <linux/parser.h>
11
#include "iscsi_dbg.h"
14
struct iet_volume *volume_lookup(struct iscsi_target *target, u32 lun)
16
struct iet_volume *volume;
18
list_for_each_entry(volume, &target->volumes, list) {
19
if (volume->lun == lun)
34
static match_table_t tokens = {
35
{opt_type, "type=%s"},
36
{opt_iomode, "iomode=%s"},
37
{opt_scsiid, "scsiid=%s"},
38
{opt_scsisn, "scsisn=%s"},
39
{opt_blk_size, "blocksize=%u"},
43
static int set_scsiid(struct iet_volume *volume, const char *id)
47
if ((len = strlen(id)) > SCSI_ID_LEN) {
48
eprintk("SCSI ID too long, %zd provided, %u max\n", len,
53
memcpy(volume->scsi_id, id, len);
58
static int set_scsisn(struct iet_volume *volume, const char *sn)
63
if ((len = strlen(sn)) > SCSI_SN_LEN) {
64
eprintk("SCSI SN too long, %zd provided, %u max\n", len,
69
for (i = 0; i < len; i++) {
70
if (!isascii(*(sn + i)) || !isprint(*(sn + i))) {
71
eprintk("invalid characters in SCSI SN, %s\n",
72
"only printable ascii characters allowed!");
77
memcpy(volume->scsi_sn, sn, len);
82
/* Generate a MD5 hash of the target IQN and LUN number */
83
static void gen_scsiid(struct iet_volume *volume)
85
struct hash_desc hash;
87
hash.tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
91
struct scatterlist sg[2];
92
unsigned int nbytes = 0;
96
sg_set_buf(&sg[0], volume->target->name,
97
strlen(volume->target->name));
98
nbytes += strlen(volume->target->name);
100
sg_set_buf(&sg[1], &volume->lun, sizeof(volume->lun));
101
nbytes += sizeof(volume->lun);
103
crypto_hash_init(&hash);
104
crypto_hash_update(&hash, sg, nbytes);
105
crypto_hash_final(&hash, volume->scsi_id);
107
crypto_free_hash(hash.tfm);
109
/* If no MD5 available set ID to TID and LUN */
110
memcpy(volume->scsi_id, &volume->target->tid,
111
sizeof(volume->target->tid));
112
memcpy(volume->scsi_id + sizeof(volume->target->tid),
113
&volume->lun, sizeof(volume->lun));
118
static int parse_volume_params(struct iet_volume *volume, char *params)
122
substring_t args[MAX_OPT_ARGS];
123
char *p, *argp = NULL, *buf = (char *) get_zeroed_page(GFP_USER);
128
strncpy(buf, params, PAGE_CACHE_SIZE);
130
while ((p = strsep(&buf, ",")) != NULL) {
136
token = match_token(p, tokens, args);
139
argp = match_strdup(&args[0]);
144
if (!(volume->iotype = get_iotype(argp)))
149
argp = match_strdup(&args[0]);
154
if (!strcmp(argp, "ro"))
155
SetLUReadonly(volume);
156
else if (!strcmp(argp, "wb"))
158
else if (strcmp(argp, "wt"))
163
argp = match_strdup(&args[0]);
168
err = set_scsiid(volume, argp);
172
argp = match_strdup(&args[0]);
177
err = set_scsisn(volume, argp);
181
argp = match_strdup(&args[0]);
186
blk_sz = simple_strtoull(argp, NULL, 10);
187
if (is_power_of_2(blk_sz) &&
188
512 <= blk_sz && blk_sz <= IET_MAX_BLOCK_SIZE)
189
volume->blk_shift = blksize_bits(blk_sz);
191
eprintk("invalid BlockSize=%u\n", blk_sz);
201
if (!err && !volume->iotype && !(volume->iotype = get_iotype("fileio"))) {
202
eprintk("%s\n", "Cannot find fileio");
206
free_page((unsigned long) buf);
211
int volume_add(struct iscsi_target *target, struct volume_info *info)
214
struct iet_volume *volume;
217
volume = volume_lookup(target, info->lun);
221
if (info->lun > 0x3fff)
224
volume = kzalloc(sizeof(*volume), GFP_KERNEL);
228
volume->target = target;
229
volume->lun = info->lun;
231
args = kzalloc(info->args_len + 1, GFP_KERNEL);
237
ret = copy_from_user(args, (void *)(unsigned long)info->args_ptr,
244
ret = parse_volume_params(volume, args);
248
ret = volume->iotype->attach(volume, args);
252
if (!volume->scsi_id[0])
255
if (!volume->scsi_sn[0]) {
258
for (i = 0; i < SCSI_ID_LEN; i++)
259
snprintf(volume->scsi_sn + (i * 2), 3, "%02x",
263
INIT_LIST_HEAD(&volume->queue.wait_list);
264
spin_lock_init(&volume->queue.queue_lock);
265
spin_lock_init(&volume->reserve_lock);
267
volume->l_state = IDEV_RUNNING;
268
atomic_set(&volume->l_count, 0);
270
list_add_tail(&volume->list, &target->volumes);
271
atomic_inc(&target->nr_volumes);
279
put_iotype(volume->iotype);
285
void iscsi_volume_destroy(struct iet_volume *volume)
287
assert(volume->l_state == IDEV_DEL);
288
assert(!atomic_read(&volume->l_count));
290
volume->iotype->detach(volume);
291
put_iotype(volume->iotype);
292
list_del(&volume->list);
296
int iscsi_volume_del(struct iscsi_target *target, struct volume_info *info)
298
struct iet_volume *volume;
300
eprintk("%x %x\n", target->tid, info->lun);
301
if (!(volume = volume_lookup(target, info->lun)))
304
volume->l_state = IDEV_DEL;
305
atomic_dec(&target->nr_volumes);
306
if (!atomic_read(&volume->l_count))
307
iscsi_volume_destroy(volume);
312
struct iet_volume *volume_get(struct iscsi_target *target, u32 lun)
314
struct iet_volume *volume;
316
if ((volume = volume_lookup(target, lun))) {
317
if (volume->l_state == IDEV_RUNNING)
318
atomic_inc(&volume->l_count);
325
void volume_put(struct iet_volume *volume)
327
if (atomic_dec_and_test(&volume->l_count) && volume->l_state == IDEV_DEL)
328
iscsi_volume_destroy(volume);
331
int volume_reserve(struct iet_volume *volume, u64 sid)
338
spin_lock(&volume->reserve_lock);
339
if (volume->reserve_sid && volume->reserve_sid != sid)
342
volume->reserve_sid = sid;
344
spin_unlock(&volume->reserve_lock);
348
int is_volume_reserved(struct iet_volume *volume, u64 sid)
355
spin_lock(&volume->reserve_lock);
356
if (!volume->reserve_sid || volume->reserve_sid == sid)
361
spin_unlock(&volume->reserve_lock);
365
int volume_release(struct iet_volume *volume, u64 sid, int force)
372
spin_lock(&volume->reserve_lock);
374
if (force || volume->reserve_sid == sid)
375
volume->reserve_sid = 0;
379
spin_unlock(&volume->reserve_lock);
383
static void iet_volume_info_show(struct seq_file *seq, struct iscsi_target *target)
385
struct iet_volume *volume;
387
list_for_each_entry(volume, &target->volumes, list) {
388
seq_printf(seq, "\tlun:%u state:%x iotype:%s",
389
volume->lun, volume->l_state, volume->iotype->name);
390
if (LUReadonly(volume))
391
seq_printf(seq, " iomode:ro");
392
else if (LUWCache(volume))
393
seq_printf(seq, " iomode:wb");
395
seq_printf(seq, " iomode:wt");
397
seq_printf(seq, " blocks:%llu blocksize:%u",
398
volume->blk_cnt, 1 << volume->blk_shift);
399
if (volume->iotype->show)
400
volume->iotype->show(volume, seq);
402
seq_printf(seq, "\n");
406
static int iet_volume_seq_open(struct inode *inode, struct file *file)
409
res = seq_open(file, &iet_seq_op);
411
((struct seq_file *)file->private_data)->private =
412
iet_volume_info_show;
416
struct file_operations volume_seq_fops = {
417
.owner = THIS_MODULE,
418
.open = iet_volume_seq_open,
421
.release = seq_release,