提交 adb9250a 编写于 作者: T Thomas Maier 提交者: Linus Torvalds

[PATCH] pktcdvd: reusability of procfs functions

This patch makes some of the procfs functions reusable (for
coming sysfs patch e.g.):
pkt_setup_dev()
pkt_remove_dev()
...
Signed-off-by: NThomas Maier <balagi@justmail.de>
Signed-off-by: NPeter Osterlund <petero2@telia.com>
Signed-off-by: NAndrew Morton <akpm@osdl.org>
Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
上级 dae3c5a0
/*
* Copyright (C) 2000 Jens Axboe <axboe@suse.de>
* Copyright (C) 2001-2004 Peter Osterlund <petero2@telia.com>
* Copyright (C) 2006 Thomas Maier <balagi@justmail.de>
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
......@@ -2436,36 +2437,33 @@ static struct block_device_operations pktcdvd_ops = {
/*
* Set up mapping from pktcdvd device to CD-ROM device.
*/
static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev)
{
int idx;
int ret = -ENOMEM;
struct pktcdvd_device *pd;
struct gendisk *disk;
dev_t dev = new_decode_dev(ctrl_cmd->dev);
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
for (idx = 0; idx < MAX_WRITERS; idx++)
if (!pkt_devs[idx])
break;
if (idx == MAX_WRITERS) {
printk(DRIVER_NAME": max %d writers supported\n", MAX_WRITERS);
return -EBUSY;
ret = -EBUSY;
goto out_mutex;
}
pd = kzalloc(sizeof(struct pktcdvd_device), GFP_KERNEL);
if (!pd)
return ret;
goto out_mutex;
pd->rb_pool = mempool_create_kmalloc_pool(PKT_RB_POOL_SIZE,
sizeof(struct pkt_rb_node));
if (!pd->rb_pool)
goto out_mem;
disk = alloc_disk(1);
if (!disk)
goto out_mem;
pd->disk = disk;
INIT_LIST_HEAD(&pd->cdrw.pkt_free_list);
INIT_LIST_HEAD(&pd->cdrw.pkt_active_list);
spin_lock_init(&pd->cdrw.active_list_lock);
......@@ -2476,11 +2474,15 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
init_waitqueue_head(&pd->wqueue);
pd->bio_queue = RB_ROOT;
disk = alloc_disk(1);
if (!disk)
goto out_mem;
pd->disk = disk;
disk->major = pktdev_major;
disk->first_minor = idx;
disk->fops = &pktcdvd_ops;
disk->flags = GENHD_FL_REMOVABLE;
sprintf(disk->disk_name, DRIVER_NAME"%d", idx);
strcpy(disk->disk_name, pd->name);
disk->private_data = pd;
disk->queue = blk_alloc_queue(GFP_KERNEL);
if (!disk->queue)
......@@ -2492,8 +2494,12 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
goto out_new_dev;
add_disk(disk);
pkt_devs[idx] = pd;
ctrl_cmd->pkt_dev = new_encode_dev(pd->pkt_dev);
if (pkt_dev)
*pkt_dev = pd->pkt_dev;
mutex_unlock(&ctl_mutex);
return 0;
out_new_dev:
......@@ -2504,17 +2510,22 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
if (pd->rb_pool)
mempool_destroy(pd->rb_pool);
kfree(pd);
out_mutex:
mutex_unlock(&ctl_mutex);
printk(DRIVER_NAME": setup of pktcdvd device failed\n");
return ret;
}
/*
* Tear down mapping from pktcdvd device to CD-ROM device.
*/
static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd)
static int pkt_remove_dev(dev_t pkt_dev)
{
struct pktcdvd_device *pd;
int idx;
dev_t pkt_dev = new_decode_dev(ctrl_cmd->pkt_dev);
int ret = 0;
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
for (idx = 0; idx < MAX_WRITERS; idx++) {
pd = pkt_devs[idx];
......@@ -2523,12 +2534,14 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd)
}
if (idx == MAX_WRITERS) {
DPRINTK(DRIVER_NAME": dev not setup\n");
return -ENXIO;
ret = -ENXIO;
goto out;
}
if (pd->refcnt > 0)
return -EBUSY;
if (pd->refcnt > 0) {
ret = -EBUSY;
goto out;
}
if (!IS_ERR(pd->cdrw.thread))
kthread_stop(pd->cdrw.thread);
......@@ -2547,12 +2560,19 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd)
/* This is safe: open() is still holding a reference. */
module_put(THIS_MODULE);
return 0;
out:
mutex_unlock(&ctl_mutex);
return ret;
}
static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd)
{
struct pktcdvd_device *pd = pkt_find_dev_from_minor(ctrl_cmd->dev_index);
struct pktcdvd_device *pd;
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
pd = pkt_find_dev_from_minor(ctrl_cmd->dev_index);
if (pd) {
ctrl_cmd->dev = new_encode_dev(pd->bdev->bd_dev);
ctrl_cmd->pkt_dev = new_encode_dev(pd->pkt_dev);
......@@ -2561,6 +2581,8 @@ static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd)
ctrl_cmd->pkt_dev = 0;
}
ctrl_cmd->num_devices = MAX_WRITERS;
mutex_unlock(&ctl_mutex);
}
static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
......@@ -2568,6 +2590,7 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm
void __user *argp = (void __user *)arg;
struct pkt_ctrl_command ctrl_cmd;
int ret = 0;
dev_t pkt_dev = 0;
if (cmd != PACKET_CTRL_CMD)
return -ENOTTY;
......@@ -2579,21 +2602,16 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm
case PKT_CTRL_CMD_SETUP:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
ret = pkt_setup_dev(&ctrl_cmd);
mutex_unlock(&ctl_mutex);
ret = pkt_setup_dev(new_decode_dev(ctrl_cmd.dev), &pkt_dev);
ctrl_cmd.pkt_dev = new_encode_dev(pkt_dev);
break;
case PKT_CTRL_CMD_TEARDOWN:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
ret = pkt_remove_dev(&ctrl_cmd);
mutex_unlock(&ctl_mutex);
ret = pkt_remove_dev(new_decode_dev(ctrl_cmd.pkt_dev));
break;
case PKT_CTRL_CMD_STATUS:
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
pkt_get_status(&ctrl_cmd);
mutex_unlock(&ctl_mutex);
break;
default:
return -ENOTTY;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册