[S390] tape: cleanup reference counting
Rename tape_get_device to tape_find_device and tape_get_device_reference to tape_get_device. The old names didn't make too much sense. Follow the get_device()/put_device() semantic and convert tape_put_device to a void function. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
committed by
Martin Schwidefsky
parent
1b52fff059
commit
8fd138c366
@@ -292,9 +292,9 @@ extern int tape_generic_pm_suspend(struct ccw_device *);
|
|||||||
extern int tape_generic_probe(struct ccw_device *);
|
extern int tape_generic_probe(struct ccw_device *);
|
||||||
extern void tape_generic_remove(struct ccw_device *);
|
extern void tape_generic_remove(struct ccw_device *);
|
||||||
|
|
||||||
extern struct tape_device *tape_get_device(int devindex);
|
extern struct tape_device *tape_find_device(int devindex);
|
||||||
extern struct tape_device *tape_get_device_reference(struct tape_device *);
|
extern struct tape_device *tape_get_device(struct tape_device *);
|
||||||
extern struct tape_device *tape_put_device(struct tape_device *);
|
extern void tape_put_device(struct tape_device *);
|
||||||
|
|
||||||
/* Externals from tape_char.c */
|
/* Externals from tape_char.c */
|
||||||
extern int tapechar_init(void);
|
extern int tapechar_init(void);
|
||||||
|
|||||||
@@ -113,16 +113,16 @@ tape_34xx_work_handler(struct work_struct *work)
|
|||||||
{
|
{
|
||||||
struct tape_34xx_work *p =
|
struct tape_34xx_work *p =
|
||||||
container_of(work, struct tape_34xx_work, work);
|
container_of(work, struct tape_34xx_work, work);
|
||||||
|
struct tape_device *device = p->device;
|
||||||
|
|
||||||
switch(p->op) {
|
switch(p->op) {
|
||||||
case TO_MSEN:
|
case TO_MSEN:
|
||||||
tape_34xx_medium_sense(p->device);
|
tape_34xx_medium_sense(device);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DBF_EVENT(3, "T34XX: internal error: unknown work\n");
|
DBF_EVENT(3, "T34XX: internal error: unknown work\n");
|
||||||
}
|
}
|
||||||
|
tape_put_device(device);
|
||||||
p->device = tape_put_device(p->device);
|
|
||||||
kfree(p);
|
kfree(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ tape_34xx_schedule_work(struct tape_device *device, enum tape_op op)
|
|||||||
|
|
||||||
INIT_WORK(&p->work, tape_34xx_work_handler);
|
INIT_WORK(&p->work, tape_34xx_work_handler);
|
||||||
|
|
||||||
p->device = tape_get_device_reference(device);
|
p->device = tape_get_device(device);
|
||||||
p->op = op;
|
p->op = op;
|
||||||
|
|
||||||
schedule_work(&p->work);
|
schedule_work(&p->work);
|
||||||
|
|||||||
@@ -608,7 +608,7 @@ tape_3590_schedule_work(struct tape_device *device, enum tape_op op)
|
|||||||
|
|
||||||
INIT_WORK(&p->work, tape_3590_work_handler);
|
INIT_WORK(&p->work, tape_3590_work_handler);
|
||||||
|
|
||||||
p->device = tape_get_device_reference(device);
|
p->device = tape_get_device(device);
|
||||||
p->op = op;
|
p->op = op;
|
||||||
|
|
||||||
schedule_work(&p->work);
|
schedule_work(&p->work);
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ tapeblock_setup_device(struct tape_device * device)
|
|||||||
disk->major = tapeblock_major;
|
disk->major = tapeblock_major;
|
||||||
disk->first_minor = device->first_minor;
|
disk->first_minor = device->first_minor;
|
||||||
disk->fops = &tapeblock_fops;
|
disk->fops = &tapeblock_fops;
|
||||||
disk->private_data = tape_get_device_reference(device);
|
disk->private_data = tape_get_device(device);
|
||||||
disk->queue = blkdat->request_queue;
|
disk->queue = blkdat->request_queue;
|
||||||
set_capacity(disk, 0);
|
set_capacity(disk, 0);
|
||||||
sprintf(disk->disk_name, "btibm%d",
|
sprintf(disk->disk_name, "btibm%d",
|
||||||
@@ -247,11 +247,11 @@ tapeblock_setup_device(struct tape_device * device)
|
|||||||
|
|
||||||
blkdat->disk = disk;
|
blkdat->disk = disk;
|
||||||
blkdat->medium_changed = 1;
|
blkdat->medium_changed = 1;
|
||||||
blkdat->request_queue->queuedata = tape_get_device_reference(device);
|
blkdat->request_queue->queuedata = tape_get_device(device);
|
||||||
|
|
||||||
add_disk(disk);
|
add_disk(disk);
|
||||||
|
|
||||||
tape_get_device_reference(device);
|
tape_get_device(device);
|
||||||
INIT_WORK(&blkdat->requeue_task, tapeblock_requeue);
|
INIT_WORK(&blkdat->requeue_task, tapeblock_requeue);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -274,13 +274,14 @@ tapeblock_cleanup_device(struct tape_device *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
del_gendisk(device->blk_data.disk);
|
del_gendisk(device->blk_data.disk);
|
||||||
device->blk_data.disk->private_data =
|
device->blk_data.disk->private_data = NULL;
|
||||||
tape_put_device(device->blk_data.disk->private_data);
|
tape_put_device(device);
|
||||||
put_disk(device->blk_data.disk);
|
put_disk(device->blk_data.disk);
|
||||||
|
|
||||||
device->blk_data.disk = NULL;
|
device->blk_data.disk = NULL;
|
||||||
cleanup_queue:
|
cleanup_queue:
|
||||||
device->blk_data.request_queue->queuedata = tape_put_device(device);
|
device->blk_data.request_queue->queuedata = NULL;
|
||||||
|
tape_put_device(device);
|
||||||
|
|
||||||
blk_cleanup_queue(device->blk_data.request_queue);
|
blk_cleanup_queue(device->blk_data.request_queue);
|
||||||
device->blk_data.request_queue = NULL;
|
device->blk_data.request_queue = NULL;
|
||||||
@@ -363,7 +364,7 @@ tapeblock_open(struct block_device *bdev, fmode_t mode)
|
|||||||
struct tape_device * device;
|
struct tape_device * device;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
device = tape_get_device_reference(disk->private_data);
|
device = tape_get_device(disk->private_data);
|
||||||
|
|
||||||
if (device->required_tapemarks) {
|
if (device->required_tapemarks) {
|
||||||
DBF_EVENT(2, "TBLOCK: missing tapemarks\n");
|
DBF_EVENT(2, "TBLOCK: missing tapemarks\n");
|
||||||
|
|||||||
@@ -286,9 +286,9 @@ tapechar_open (struct inode *inode, struct file *filp)
|
|||||||
|
|
||||||
lock_kernel();
|
lock_kernel();
|
||||||
minor = iminor(filp->f_path.dentry->d_inode);
|
minor = iminor(filp->f_path.dentry->d_inode);
|
||||||
device = tape_get_device(minor / TAPE_MINORS_PER_DEV);
|
device = tape_find_device(minor / TAPE_MINORS_PER_DEV);
|
||||||
if (IS_ERR(device)) {
|
if (IS_ERR(device)) {
|
||||||
DBF_EVENT(3, "TCHAR:open: tape_get_device() failed\n");
|
DBF_EVENT(3, "TCHAR:open: tape_find_device() failed\n");
|
||||||
rc = PTR_ERR(device);
|
rc = PTR_ERR(device);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -340,7 +340,8 @@ tapechar_release(struct inode *inode, struct file *filp)
|
|||||||
device->char_data.idal_buf = NULL;
|
device->char_data.idal_buf = NULL;
|
||||||
}
|
}
|
||||||
tape_release(device);
|
tape_release(device);
|
||||||
filp->private_data = tape_put_device(device);
|
filp->private_data = NULL;
|
||||||
|
tape_put_device(device);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -511,11 +511,12 @@ tape_alloc_device(void)
|
|||||||
* increment the reference count.
|
* increment the reference count.
|
||||||
*/
|
*/
|
||||||
struct tape_device *
|
struct tape_device *
|
||||||
tape_get_device_reference(struct tape_device *device)
|
tape_get_device(struct tape_device *device)
|
||||||
{
|
{
|
||||||
DBF_EVENT(4, "tape_get_device_reference(%p) = %i\n", device,
|
int count;
|
||||||
atomic_inc_return(&device->ref_count));
|
|
||||||
|
|
||||||
|
count = atomic_inc_return(&device->ref_count);
|
||||||
|
DBF_EVENT(4, "tape_get_device(%p) = %i\n", device, count);
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -525,32 +526,25 @@ tape_get_device_reference(struct tape_device *device)
|
|||||||
* The function returns a NULL pointer to be used by the caller
|
* The function returns a NULL pointer to be used by the caller
|
||||||
* for clearing reference pointers.
|
* for clearing reference pointers.
|
||||||
*/
|
*/
|
||||||
struct tape_device *
|
void
|
||||||
tape_put_device(struct tape_device *device)
|
tape_put_device(struct tape_device *device)
|
||||||
{
|
{
|
||||||
int remain;
|
int count;
|
||||||
|
|
||||||
remain = atomic_dec_return(&device->ref_count);
|
count = atomic_dec_return(&device->ref_count);
|
||||||
if (remain > 0) {
|
DBF_EVENT(4, "tape_put_device(%p) -> %i\n", device, count);
|
||||||
DBF_EVENT(4, "tape_put_device(%p) -> %i\n", device, remain);
|
BUG_ON(count < 0);
|
||||||
} else {
|
if (count == 0) {
|
||||||
if (remain < 0) {
|
|
||||||
DBF_EVENT(4, "put device without reference\n");
|
|
||||||
} else {
|
|
||||||
DBF_EVENT(4, "tape_free_device(%p)\n", device);
|
|
||||||
kfree(device->modeset_byte);
|
kfree(device->modeset_byte);
|
||||||
kfree(device);
|
kfree(device);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find tape device by a device index.
|
* Find tape device by a device index.
|
||||||
*/
|
*/
|
||||||
struct tape_device *
|
struct tape_device *
|
||||||
tape_get_device(int devindex)
|
tape_find_device(int devindex)
|
||||||
{
|
{
|
||||||
struct tape_device *device, *tmp;
|
struct tape_device *device, *tmp;
|
||||||
|
|
||||||
@@ -558,7 +552,7 @@ tape_get_device(int devindex)
|
|||||||
read_lock(&tape_device_lock);
|
read_lock(&tape_device_lock);
|
||||||
list_for_each_entry(tmp, &tape_device_list, node) {
|
list_for_each_entry(tmp, &tape_device_list, node) {
|
||||||
if (tmp->first_minor / TAPE_MINORS_PER_DEV == devindex) {
|
if (tmp->first_minor / TAPE_MINORS_PER_DEV == devindex) {
|
||||||
device = tape_get_device_reference(tmp);
|
device = tape_get_device(tmp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -607,7 +601,8 @@ __tape_discard_requests(struct tape_device *device)
|
|||||||
list_del(&request->list);
|
list_del(&request->list);
|
||||||
|
|
||||||
/* Decrease ref_count for removed request. */
|
/* Decrease ref_count for removed request. */
|
||||||
request->device = tape_put_device(device);
|
request->device = NULL;
|
||||||
|
tape_put_device(device);
|
||||||
request->rc = -EIO;
|
request->rc = -EIO;
|
||||||
if (request->callback != NULL)
|
if (request->callback != NULL)
|
||||||
request->callback(request, request->callback_data);
|
request->callback(request, request->callback_data);
|
||||||
@@ -665,9 +660,11 @@ tape_generic_remove(struct ccw_device *cdev)
|
|||||||
tape_cleanup_device(device);
|
tape_cleanup_device(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev_get_drvdata(&cdev->dev)) {
|
device = dev_get_drvdata(&cdev->dev);
|
||||||
|
if (device) {
|
||||||
sysfs_remove_group(&cdev->dev.kobj, &tape_attr_group);
|
sysfs_remove_group(&cdev->dev.kobj, &tape_attr_group);
|
||||||
dev_set_drvdata(&cdev->dev, tape_put_device(dev_get_drvdata(&cdev->dev)));
|
dev_set_drvdata(&cdev->dev, NULL);
|
||||||
|
tape_put_device(device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -722,9 +719,8 @@ tape_free_request (struct tape_request * request)
|
|||||||
{
|
{
|
||||||
DBF_LH(6, "Free request %p\n", request);
|
DBF_LH(6, "Free request %p\n", request);
|
||||||
|
|
||||||
if (request->device != NULL) {
|
if (request->device)
|
||||||
request->device = tape_put_device(request->device);
|
tape_put_device(request->device);
|
||||||
}
|
|
||||||
kfree(request->cpdata);
|
kfree(request->cpdata);
|
||||||
kfree(request->cpaddr);
|
kfree(request->cpaddr);
|
||||||
kfree(request);
|
kfree(request);
|
||||||
@@ -839,7 +835,8 @@ static void tape_long_busy_timeout(unsigned long data)
|
|||||||
BUG_ON(request->status != TAPE_REQUEST_LONG_BUSY);
|
BUG_ON(request->status != TAPE_REQUEST_LONG_BUSY);
|
||||||
DBF_LH(6, "%08x: Long busy timeout.\n", device->cdev_id);
|
DBF_LH(6, "%08x: Long busy timeout.\n", device->cdev_id);
|
||||||
__tape_start_next_request(device);
|
__tape_start_next_request(device);
|
||||||
device->lb_timeout.data = (unsigned long) tape_put_device(device);
|
device->lb_timeout.data = 0UL;
|
||||||
|
tape_put_device(device);
|
||||||
spin_unlock_irq(get_ccwdev_lock(device->cdev));
|
spin_unlock_irq(get_ccwdev_lock(device->cdev));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -919,7 +916,7 @@ __tape_start_request(struct tape_device *device, struct tape_request *request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Increase use count of device for the added request. */
|
/* Increase use count of device for the added request. */
|
||||||
request->device = tape_get_device_reference(device);
|
request->device = tape_get_device(device);
|
||||||
|
|
||||||
if (list_empty(&device->req_queue)) {
|
if (list_empty(&device->req_queue)) {
|
||||||
/* No other requests are on the queue. Start this one. */
|
/* No other requests are on the queue. Start this one. */
|
||||||
@@ -1118,7 +1115,7 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
|
|||||||
if (req->status == TAPE_REQUEST_LONG_BUSY) {
|
if (req->status == TAPE_REQUEST_LONG_BUSY) {
|
||||||
DBF_EVENT(3, "(%08x): del timer\n", device->cdev_id);
|
DBF_EVENT(3, "(%08x): del timer\n", device->cdev_id);
|
||||||
if (del_timer(&device->lb_timeout)) {
|
if (del_timer(&device->lb_timeout)) {
|
||||||
device->lb_timeout.data = (unsigned long)
|
device->lb_timeout.data = 0UL;
|
||||||
tape_put_device(device);
|
tape_put_device(device);
|
||||||
__tape_start_next_request(device);
|
__tape_start_next_request(device);
|
||||||
}
|
}
|
||||||
@@ -1174,7 +1171,7 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
|
|||||||
break;
|
break;
|
||||||
case TAPE_IO_LONG_BUSY:
|
case TAPE_IO_LONG_BUSY:
|
||||||
device->lb_timeout.data =
|
device->lb_timeout.data =
|
||||||
(unsigned long)tape_get_device_reference(device);
|
(unsigned long) tape_get_device(device);
|
||||||
device->lb_timeout.expires = jiffies +
|
device->lb_timeout.expires = jiffies +
|
||||||
LONG_BUSY_TIMEOUT * HZ;
|
LONG_BUSY_TIMEOUT * HZ;
|
||||||
DBF_EVENT(3, "(%08x): add timer\n", device->cdev_id);
|
DBF_EVENT(3, "(%08x): add timer\n", device->cdev_id);
|
||||||
@@ -1327,7 +1324,7 @@ EXPORT_SYMBOL(tape_generic_online);
|
|||||||
EXPORT_SYMBOL(tape_generic_offline);
|
EXPORT_SYMBOL(tape_generic_offline);
|
||||||
EXPORT_SYMBOL(tape_generic_pm_suspend);
|
EXPORT_SYMBOL(tape_generic_pm_suspend);
|
||||||
EXPORT_SYMBOL(tape_put_device);
|
EXPORT_SYMBOL(tape_put_device);
|
||||||
EXPORT_SYMBOL(tape_get_device_reference);
|
EXPORT_SYMBOL(tape_get_device);
|
||||||
EXPORT_SYMBOL(tape_state_verbose);
|
EXPORT_SYMBOL(tape_state_verbose);
|
||||||
EXPORT_SYMBOL(tape_op_verbose);
|
EXPORT_SYMBOL(tape_op_verbose);
|
||||||
EXPORT_SYMBOL(tape_state_set);
|
EXPORT_SYMBOL(tape_state_set);
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ static int tape_proc_show(struct seq_file *m, void *v)
|
|||||||
seq_printf(m, "TapeNo\tBusID CuType/Model\t"
|
seq_printf(m, "TapeNo\tBusID CuType/Model\t"
|
||||||
"DevType/Model\tBlkSize\tState\tOp\tMedState\n");
|
"DevType/Model\tBlkSize\tState\tOp\tMedState\n");
|
||||||
}
|
}
|
||||||
device = tape_get_device(n);
|
device = tape_find_device(n);
|
||||||
if (IS_ERR(device))
|
if (IS_ERR(device))
|
||||||
return 0;
|
return 0;
|
||||||
spin_lock_irq(get_ccwdev_lock(device->cdev));
|
spin_lock_irq(get_ccwdev_lock(device->cdev));
|
||||||
|
|||||||
Reference in New Issue
Block a user