aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/pktcdvd.c72
1 files changed, 45 insertions, 27 deletions
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index e45eaa264119..7e7b892f621a 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (C) 2000 Jens Axboe <axboe@suse.de> 2 * Copyright (C) 2000 Jens Axboe <axboe@suse.de>
3 * Copyright (C) 2001-2004 Peter Osterlund <petero2@telia.com> 3 * Copyright (C) 2001-2004 Peter Osterlund <petero2@telia.com>
4 * Copyright (C) 2006 Thomas Maier <balagi@justmail.de>
4 * 5 *
5 * May be copied or modified under the terms of the GNU General Public 6 * May be copied or modified under the terms of the GNU General Public
6 * License. See linux/COPYING for more information. 7 * License. See linux/COPYING for more information.
@@ -2436,36 +2437,33 @@ static struct block_device_operations pktcdvd_ops = {
2436/* 2437/*
2437 * Set up mapping from pktcdvd device to CD-ROM device. 2438 * Set up mapping from pktcdvd device to CD-ROM device.
2438 */ 2439 */
2439static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd) 2440static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev)
2440{ 2441{
2441 int idx; 2442 int idx;
2442 int ret = -ENOMEM; 2443 int ret = -ENOMEM;
2443 struct pktcdvd_device *pd; 2444 struct pktcdvd_device *pd;
2444 struct gendisk *disk; 2445 struct gendisk *disk;
2445 dev_t dev = new_decode_dev(ctrl_cmd->dev); 2446
2447 mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
2446 2448
2447 for (idx = 0; idx < MAX_WRITERS; idx++) 2449 for (idx = 0; idx < MAX_WRITERS; idx++)
2448 if (!pkt_devs[idx]) 2450 if (!pkt_devs[idx])
2449 break; 2451 break;
2450 if (idx == MAX_WRITERS) { 2452 if (idx == MAX_WRITERS) {
2451 printk(DRIVER_NAME": max %d writers supported\n", MAX_WRITERS); 2453 printk(DRIVER_NAME": max %d writers supported\n", MAX_WRITERS);
2452 return -EBUSY; 2454 ret = -EBUSY;
2455 goto out_mutex;
2453 } 2456 }
2454 2457
2455 pd = kzalloc(sizeof(struct pktcdvd_device), GFP_KERNEL); 2458 pd = kzalloc(sizeof(struct pktcdvd_device), GFP_KERNEL);
2456 if (!pd) 2459 if (!pd)
2457 return ret; 2460 goto out_mutex;
2458 2461
2459 pd->rb_pool = mempool_create_kmalloc_pool(PKT_RB_POOL_SIZE, 2462 pd->rb_pool = mempool_create_kmalloc_pool(PKT_RB_POOL_SIZE,
2460 sizeof(struct pkt_rb_node)); 2463 sizeof(struct pkt_rb_node));
2461 if (!pd->rb_pool) 2464 if (!pd->rb_pool)
2462 goto out_mem; 2465 goto out_mem;
2463 2466
2464 disk = alloc_disk(1);
2465 if (!disk)
2466 goto out_mem;
2467 pd->disk = disk;
2468
2469 INIT_LIST_HEAD(&pd->cdrw.pkt_free_list); 2467 INIT_LIST_HEAD(&pd->cdrw.pkt_free_list);
2470 INIT_LIST_HEAD(&pd->cdrw.pkt_active_list); 2468 INIT_LIST_HEAD(&pd->cdrw.pkt_active_list);
2471 spin_lock_init(&pd->cdrw.active_list_lock); 2469 spin_lock_init(&pd->cdrw.active_list_lock);
@@ -2476,11 +2474,15 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
2476 init_waitqueue_head(&pd->wqueue); 2474 init_waitqueue_head(&pd->wqueue);
2477 pd->bio_queue = RB_ROOT; 2475 pd->bio_queue = RB_ROOT;
2478 2476
2477 disk = alloc_disk(1);
2478 if (!disk)
2479 goto out_mem;
2480 pd->disk = disk;
2479 disk->major = pktdev_major; 2481 disk->major = pktdev_major;
2480 disk->first_minor = idx; 2482 disk->first_minor = idx;
2481 disk->fops = &pktcdvd_ops; 2483 disk->fops = &pktcdvd_ops;
2482 disk->flags = GENHD_FL_REMOVABLE; 2484 disk->flags = GENHD_FL_REMOVABLE;
2483 sprintf(disk->disk_name, DRIVER_NAME"%d", idx); 2485 strcpy(disk->disk_name, pd->name);
2484 disk->private_data = pd; 2486 disk->private_data = pd;
2485 disk->queue = blk_alloc_queue(GFP_KERNEL); 2487 disk->queue = blk_alloc_queue(GFP_KERNEL);
2486 if (!disk->queue) 2488 if (!disk->queue)
@@ -2492,8 +2494,12 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
2492 goto out_new_dev; 2494 goto out_new_dev;
2493 2495
2494 add_disk(disk); 2496 add_disk(disk);
2497
2495 pkt_devs[idx] = pd; 2498 pkt_devs[idx] = pd;
2496 ctrl_cmd->pkt_dev = new_encode_dev(pd->pkt_dev); 2499 if (pkt_dev)
2500 *pkt_dev = pd->pkt_dev;
2501
2502 mutex_unlock(&ctl_mutex);
2497 return 0; 2503 return 0;
2498 2504
2499out_new_dev: 2505out_new_dev:
@@ -2504,17 +2510,22 @@ out_mem:
2504 if (pd->rb_pool) 2510 if (pd->rb_pool)
2505 mempool_destroy(pd->rb_pool); 2511 mempool_destroy(pd->rb_pool);
2506 kfree(pd); 2512 kfree(pd);
2513out_mutex:
2514 mutex_unlock(&ctl_mutex);
2515 printk(DRIVER_NAME": setup of pktcdvd device failed\n");
2507 return ret; 2516 return ret;
2508} 2517}
2509 2518
2510/* 2519/*
2511 * Tear down mapping from pktcdvd device to CD-ROM device. 2520 * Tear down mapping from pktcdvd device to CD-ROM device.
2512 */ 2521 */
2513static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd) 2522static int pkt_remove_dev(dev_t pkt_dev)
2514{ 2523{
2515 struct pktcdvd_device *pd; 2524 struct pktcdvd_device *pd;
2516 int idx; 2525 int idx;
2517 dev_t pkt_dev = new_decode_dev(ctrl_cmd->pkt_dev); 2526 int ret = 0;
2527
2528 mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
2518 2529
2519 for (idx = 0; idx < MAX_WRITERS; idx++) { 2530 for (idx = 0; idx < MAX_WRITERS; idx++) {
2520 pd = pkt_devs[idx]; 2531 pd = pkt_devs[idx];
@@ -2523,12 +2534,14 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd)
2523 } 2534 }
2524 if (idx == MAX_WRITERS) { 2535 if (idx == MAX_WRITERS) {
2525 DPRINTK(DRIVER_NAME": dev not setup\n"); 2536 DPRINTK(DRIVER_NAME": dev not setup\n");
2526 return -ENXIO; 2537 ret = -ENXIO;
2538 goto out;
2527 } 2539 }
2528 2540
2529 if (pd->refcnt > 0) 2541 if (pd->refcnt > 0) {
2530 return -EBUSY; 2542 ret = -EBUSY;
2531 2543 goto out;
2544 }
2532 if (!IS_ERR(pd->cdrw.thread)) 2545 if (!IS_ERR(pd->cdrw.thread))
2533 kthread_stop(pd->cdrw.thread); 2546 kthread_stop(pd->cdrw.thread);
2534 2547
@@ -2547,12 +2560,19 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd)
2547 2560
2548 /* This is safe: open() is still holding a reference. */ 2561 /* This is safe: open() is still holding a reference. */
2549 module_put(THIS_MODULE); 2562 module_put(THIS_MODULE);
2550 return 0; 2563
2564out:
2565 mutex_unlock(&ctl_mutex);
2566 return ret;
2551} 2567}
2552 2568
2553static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd) 2569static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd)
2554{ 2570{
2555 struct pktcdvd_device *pd = pkt_find_dev_from_minor(ctrl_cmd->dev_index); 2571 struct pktcdvd_device *pd;
2572
2573 mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
2574
2575 pd = pkt_find_dev_from_minor(ctrl_cmd->dev_index);
2556 if (pd) { 2576 if (pd) {
2557 ctrl_cmd->dev = new_encode_dev(pd->bdev->bd_dev); 2577 ctrl_cmd->dev = new_encode_dev(pd->bdev->bd_dev);
2558 ctrl_cmd->pkt_dev = new_encode_dev(pd->pkt_dev); 2578 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)
2561 ctrl_cmd->pkt_dev = 0; 2581 ctrl_cmd->pkt_dev = 0;
2562 } 2582 }
2563 ctrl_cmd->num_devices = MAX_WRITERS; 2583 ctrl_cmd->num_devices = MAX_WRITERS;
2584
2585 mutex_unlock(&ctl_mutex);
2564} 2586}
2565 2587
2566static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 2588static 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
2568 void __user *argp = (void __user *)arg; 2590 void __user *argp = (void __user *)arg;
2569 struct pkt_ctrl_command ctrl_cmd; 2591 struct pkt_ctrl_command ctrl_cmd;
2570 int ret = 0; 2592 int ret = 0;
2593 dev_t pkt_dev = 0;
2571 2594
2572 if (cmd != PACKET_CTRL_CMD) 2595 if (cmd != PACKET_CTRL_CMD)
2573 return -ENOTTY; 2596 return -ENOTTY;
@@ -2579,21 +2602,16 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm
2579 case PKT_CTRL_CMD_SETUP: 2602 case PKT_CTRL_CMD_SETUP:
2580 if (!capable(CAP_SYS_ADMIN)) 2603 if (!capable(CAP_SYS_ADMIN))
2581 return -EPERM; 2604 return -EPERM;
2582 mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); 2605 ret = pkt_setup_dev(new_decode_dev(ctrl_cmd.dev), &pkt_dev);
2583 ret = pkt_setup_dev(&ctrl_cmd); 2606 ctrl_cmd.pkt_dev = new_encode_dev(pkt_dev);
2584 mutex_unlock(&ctl_mutex);
2585 break; 2607 break;
2586 case PKT_CTRL_CMD_TEARDOWN: 2608 case PKT_CTRL_CMD_TEARDOWN:
2587 if (!capable(CAP_SYS_ADMIN)) 2609 if (!capable(CAP_SYS_ADMIN))
2588 return -EPERM; 2610 return -EPERM;
2589 mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); 2611 ret = pkt_remove_dev(new_decode_dev(ctrl_cmd.pkt_dev));
2590 ret = pkt_remove_dev(&ctrl_cmd);
2591 mutex_unlock(&ctl_mutex);
2592 break; 2612 break;
2593 case PKT_CTRL_CMD_STATUS: 2613 case PKT_CTRL_CMD_STATUS:
2594 mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
2595 pkt_get_status(&ctrl_cmd); 2614 pkt_get_status(&ctrl_cmd);
2596 mutex_unlock(&ctl_mutex);
2597 break; 2615 break;
2598 default: 2616 default:
2599 return -ENOTTY; 2617 return -ENOTTY;