aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/dasd_ioctl.c
diff options
context:
space:
mode:
authorHorst Hummel <horst.hummel@de.ibm.com>2005-09-03 18:57:58 -0400
committerLinus Torvalds <torvalds@evo.osdl.org>2005-09-05 03:06:26 -0400
commitc6eb7b7703ac4b3401b74f411c8c51ded214bf19 (patch)
tree1cb3563cb83f80347dbc3e4bd30c4635d401e87a /drivers/s390/block/dasd_ioctl.c
parent942eaabd5d77522223a311ed9bddaaa3cefde27d (diff)
[PATCH] s390: deadlock in dasd_devmap
Reintroduce a read-only copy of the devmap features in the device struct. This is necessary to solve a deadlock on the dasd_devmap_lock which is acquired by dasd_get_features called from the dasd tasklet. The current implementation of devmap doesn't allow to call any devmap function from interrupt or softirq context. Signed-off-by: Horst Hummel <horst.hummel@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/s390/block/dasd_ioctl.c')
-rw-r--r--drivers/s390/block/dasd_ioctl.c17
1 files changed, 5 insertions, 12 deletions
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index 980c555aa538..789595b3fa09 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -7,7 +7,7 @@
7 * Bugreports.to..: <Linux390@de.ibm.com> 7 * Bugreports.to..: <Linux390@de.ibm.com>
8 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 8 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
9 * 9 *
10 * $Revision: 1.45 $ 10 * $Revision: 1.47 $
11 * 11 *
12 * i/o controls for the dasd driver. 12 * i/o controls for the dasd driver.
13 */ 13 */
@@ -296,7 +296,6 @@ dasd_ioctl_format(struct block_device *bdev, int no, long args)
296{ 296{
297 struct dasd_device *device; 297 struct dasd_device *device;
298 struct format_data_t fdata; 298 struct format_data_t fdata;
299 int feature_ro;
300 299
301 if (!capable(CAP_SYS_ADMIN)) 300 if (!capable(CAP_SYS_ADMIN))
302 return -EACCES; 301 return -EACCES;
@@ -308,10 +307,7 @@ dasd_ioctl_format(struct block_device *bdev, int no, long args)
308 if (device == NULL) 307 if (device == NULL)
309 return -ENODEV; 308 return -ENODEV;
310 309
311 feature_ro = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY); 310 if (device->features & DASD_FEATURE_READONLY)
312 if (feature_ro < 0)
313 return feature_ro;
314 if (feature_ro)
315 return -EROFS; 311 return -EROFS;
316 if (copy_from_user(&fdata, (void __user *) args, 312 if (copy_from_user(&fdata, (void __user *) args,
317 sizeof (struct format_data_t))) 313 sizeof (struct format_data_t)))
@@ -384,7 +380,7 @@ dasd_ioctl_information(struct block_device *bdev, int no, long args)
384 struct dasd_device *device; 380 struct dasd_device *device;
385 struct dasd_information2_t *dasd_info; 381 struct dasd_information2_t *dasd_info;
386 unsigned long flags; 382 unsigned long flags;
387 int rc, feature_ro; 383 int rc;
388 struct ccw_device *cdev; 384 struct ccw_device *cdev;
389 385
390 device = bdev->bd_disk->private_data; 386 device = bdev->bd_disk->private_data;
@@ -394,10 +390,6 @@ dasd_ioctl_information(struct block_device *bdev, int no, long args)
394 if (!device->discipline->fill_info) 390 if (!device->discipline->fill_info)
395 return -EINVAL; 391 return -EINVAL;
396 392
397 feature_ro = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY);
398 if (feature_ro < 0)
399 return feature_ro;
400
401 dasd_info = kmalloc(sizeof(struct dasd_information2_t), GFP_KERNEL); 393 dasd_info = kmalloc(sizeof(struct dasd_information2_t), GFP_KERNEL);
402 if (dasd_info == NULL) 394 if (dasd_info == NULL)
403 return -ENOMEM; 395 return -ENOMEM;
@@ -427,7 +419,8 @@ dasd_ioctl_information(struct block_device *bdev, int no, long args)
427 (dasd_check_blocksize(device->bp_block))) 419 (dasd_check_blocksize(device->bp_block)))
428 dasd_info->format = DASD_FORMAT_NONE; 420 dasd_info->format = DASD_FORMAT_NONE;
429 421
430 dasd_info->features |= feature_ro; 422 dasd_info->features |=
423 ((device->features & DASD_FEATURE_READONLY) != 0);
431 424
432 if (device->discipline) 425 if (device->discipline)
433 memcpy(dasd_info->type, device->discipline->name, 4); 426 memcpy(dasd_info->type, device->discipline->name, 4);