⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 volume.c

📁 Ubuntu公司提供免费的iSCSI Target
💻 C
字号:
/* * Volume manager * (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org> * This code is licenced under the GPL. */#include "iscsi.h"#include "iscsi_dbg.h"#include "iotype.h"#include <linux/parser.h>struct iet_volume *volume_lookup(struct iscsi_target *target, u32 lun){	struct iet_volume *volume;	list_for_each_entry(volume, &target->volumes, list) {		if (volume->lun == lun)			return volume;	}	return NULL;}enum {	Opt_type,	Opt_iomode,	Opt_err,};static match_table_t tokens = {	{Opt_type, "Type=%s"},	{Opt_iomode, "IOMode=%s"},	{Opt_err, NULL},};static int set_iotype(struct iet_volume *volume, char *params){	int err = 0;	substring_t args[MAX_OPT_ARGS];	char *p, *argp = NULL, *buf = (char *) get_zeroed_page(GFP_USER);	if (!buf)		return -ENOMEM;	strncpy(buf, params, PAGE_CACHE_SIZE);	while ((p = strsep(&buf, ",")) != NULL) {		int token;		if (!*p)			continue;		token = match_token(p, tokens, args);		switch (token) {		case Opt_type:			if (!(argp = match_strdup(&args[0])))				err = -ENOMEM;			if (argp && !(volume->iotype = get_iotype(argp)))				err = -ENOENT;			kfree(argp);			break;		case Opt_iomode:			if (!(argp = match_strdup(&args[0])))				err = -ENOMEM;			if (argp && !strcmp(argp, "ro"))				SetLUReadonly(volume);			else if (argp && !strcmp(argp, "wb"))				SetLUAsync(volume);			kfree(argp);			break;		default:			break;		}	}	if (!err && !volume->iotype && !(volume->iotype = get_iotype("fileio"))) {		eprintk("%s\n", "Cannot find fileio");		err = -EINVAL;	}	free_page((unsigned long) buf);	return err;}int volume_add(struct iscsi_target *target, struct volume_info *info){	int ret;	struct iet_volume *volume;	char *args;	volume = volume_lookup(target, info->lun);	if (volume)		return -EEXIST;	if (info->lun > 0x3fff)		return -EINVAL;	volume = kzalloc(sizeof(*volume), GFP_KERNEL);	if (!volume)		return -ENOMEM;	volume->target = target;	volume->lun = info->lun;	args = kzalloc(info->args_len + 1, GFP_KERNEL);	if (!args) {		ret = -ENOMEM;		goto free_volume;	}	ret = copy_from_user(args, (void *)(unsigned long)info->args_ptr,			     info->args_len);	if (ret) {		ret = -EFAULT;		goto free_args;	}	ret = set_iotype(volume, args);	if (ret < 0)		goto free_args;	ret = volume->iotype->attach(volume, args);	if (ret < 0)		goto free_args;	INIT_LIST_HEAD(&volume->queue.wait_list);	spin_lock_init(&volume->queue.queue_lock);	spin_lock_init(&volume->reserve_lock);	volume->l_state = IDEV_RUNNING;	atomic_set(&volume->l_count, 0);	list_add_tail(&volume->list, &target->volumes);	atomic_inc(&target->nr_volumes);	kfree(args);	return 0;free_args:	kfree(args);free_volume:	put_iotype(volume->iotype);	kfree(volume);	return ret;}void iscsi_volume_destroy(struct iet_volume *volume){	assert(volume->l_state == IDEV_DEL);	assert(!atomic_read(&volume->l_count));	volume->iotype->detach(volume);	put_iotype(volume->iotype);	list_del(&volume->list);	kfree(volume);}int iscsi_volume_del(struct iscsi_target *target, struct volume_info *info){	struct iet_volume *volume;	eprintk("%x %x\n", target->tid, info->lun);	if (!(volume = volume_lookup(target, info->lun)))		return -ENOENT;	volume->l_state = IDEV_DEL;	atomic_dec(&target->nr_volumes);	if (!atomic_read(&volume->l_count))		iscsi_volume_destroy(volume);	return 0;}struct iet_volume *volume_get(struct iscsi_target *target, u32 lun){	struct iet_volume *volume;	if ((volume = volume_lookup(target, lun))) {		if (volume->l_state == IDEV_RUNNING)			atomic_inc(&volume->l_count);		else			volume = NULL;	}	return volume;}void volume_put(struct iet_volume *volume){	if (atomic_dec_and_test(&volume->l_count) && volume->l_state == IDEV_DEL)		iscsi_volume_destroy(volume);}int volume_reserve(struct iet_volume *volume, u64 sid){	if (!volume)		return -ENOENT;	spin_lock(&volume->reserve_lock);	if (volume->reserve_sid && volume->reserve_sid != sid) {		spin_unlock(&volume->reserve_lock);		return -EBUSY;	}	volume->reserve_sid = sid;	spin_unlock(&volume->reserve_lock);	return 0;}int is_volume_reserved(struct iet_volume *volume, u64 sid){	if (!volume || !volume->reserve_sid || volume->reserve_sid == sid)		return 0;	return -EBUSY;}int volume_release(struct iet_volume *volume, u64 sid, int force){	if (force || volume->reserve_sid == sid)		volume->reserve_sid = 0;	return 0;}static void iet_volume_info_show(struct seq_file *seq, struct iscsi_target *target){	struct iet_volume *volume;	list_for_each_entry(volume, &target->volumes, list) {		seq_printf(seq, "\tlun:%u state:%x iotype:%s",			   volume->lun, volume->l_state, volume->iotype->name);		if (LUReadonly(volume))			seq_printf(seq, " iomode:ro");		else if (LUAsync(volume))			seq_printf(seq, " iomode:wb");		else			seq_printf(seq, " iomode:wt");		if (volume->iotype->show)			volume->iotype->show(volume, seq);		else			seq_printf(seq, "\n");	}}static int iet_volumes_info_show(struct seq_file *seq, void *v){	return iet_info_show(seq, iet_volume_info_show);}static int iet_volume_seq_open(struct inode *inode, struct file *file){	return single_open(file, iet_volumes_info_show, NULL);}struct file_operations volume_seq_fops = {	.owner		= THIS_MODULE,	.open		= iet_volume_seq_open,	.read		= seq_read,	.llseek		= seq_lseek,	.release	= single_release,};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -