diff options
Diffstat (limited to 'drivers/s390/block/dasd_ioctl.c')
-rw-r--r-- | drivers/s390/block/dasd_ioctl.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index f1892baa3b1..980c555aa53 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c | |||
@@ -7,6 +7,8 @@ | |||
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 $ | ||
11 | * | ||
10 | * i/o controls for the dasd driver. | 12 | * i/o controls for the dasd driver. |
11 | */ | 13 | */ |
12 | #include <linux/config.h> | 14 | #include <linux/config.h> |
@@ -294,6 +296,7 @@ dasd_ioctl_format(struct block_device *bdev, int no, long args) | |||
294 | { | 296 | { |
295 | struct dasd_device *device; | 297 | struct dasd_device *device; |
296 | struct format_data_t fdata; | 298 | struct format_data_t fdata; |
299 | int feature_ro; | ||
297 | 300 | ||
298 | if (!capable(CAP_SYS_ADMIN)) | 301 | if (!capable(CAP_SYS_ADMIN)) |
299 | return -EACCES; | 302 | return -EACCES; |
@@ -304,7 +307,11 @@ dasd_ioctl_format(struct block_device *bdev, int no, long args) | |||
304 | 307 | ||
305 | if (device == NULL) | 308 | if (device == NULL) |
306 | return -ENODEV; | 309 | return -ENODEV; |
307 | if (test_bit(DASD_FLAG_RO, &device->flags)) | 310 | |
311 | feature_ro = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY); | ||
312 | if (feature_ro < 0) | ||
313 | return feature_ro; | ||
314 | if (feature_ro) | ||
308 | return -EROFS; | 315 | return -EROFS; |
309 | if (copy_from_user(&fdata, (void __user *) args, | 316 | if (copy_from_user(&fdata, (void __user *) args, |
310 | sizeof (struct format_data_t))) | 317 | sizeof (struct format_data_t))) |
@@ -377,7 +384,7 @@ dasd_ioctl_information(struct block_device *bdev, int no, long args) | |||
377 | struct dasd_device *device; | 384 | struct dasd_device *device; |
378 | struct dasd_information2_t *dasd_info; | 385 | struct dasd_information2_t *dasd_info; |
379 | unsigned long flags; | 386 | unsigned long flags; |
380 | int rc; | 387 | int rc, feature_ro; |
381 | struct ccw_device *cdev; | 388 | struct ccw_device *cdev; |
382 | 389 | ||
383 | device = bdev->bd_disk->private_data; | 390 | device = bdev->bd_disk->private_data; |
@@ -387,6 +394,10 @@ dasd_ioctl_information(struct block_device *bdev, int no, long args) | |||
387 | if (!device->discipline->fill_info) | 394 | if (!device->discipline->fill_info) |
388 | return -EINVAL; | 395 | return -EINVAL; |
389 | 396 | ||
397 | feature_ro = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY); | ||
398 | if (feature_ro < 0) | ||
399 | return feature_ro; | ||
400 | |||
390 | dasd_info = kmalloc(sizeof(struct dasd_information2_t), GFP_KERNEL); | 401 | dasd_info = kmalloc(sizeof(struct dasd_information2_t), GFP_KERNEL); |
391 | if (dasd_info == NULL) | 402 | if (dasd_info == NULL) |
392 | return -ENOMEM; | 403 | return -ENOMEM; |
@@ -415,9 +426,8 @@ dasd_ioctl_information(struct block_device *bdev, int no, long args) | |||
415 | if ((device->state < DASD_STATE_READY) || | 426 | if ((device->state < DASD_STATE_READY) || |
416 | (dasd_check_blocksize(device->bp_block))) | 427 | (dasd_check_blocksize(device->bp_block))) |
417 | dasd_info->format = DASD_FORMAT_NONE; | 428 | dasd_info->format = DASD_FORMAT_NONE; |
418 | 429 | ||
419 | dasd_info->features |= test_bit(DASD_FLAG_RO, &device->flags) ? | 430 | dasd_info->features |= feature_ro; |
420 | DASD_FEATURE_READONLY : DASD_FEATURE_DEFAULT; | ||
421 | 431 | ||
422 | if (device->discipline) | 432 | if (device->discipline) |
423 | memcpy(dasd_info->type, device->discipline->name, 4); | 433 | memcpy(dasd_info->type, device->discipline->name, 4); |
@@ -460,7 +470,7 @@ static int | |||
460 | dasd_ioctl_set_ro(struct block_device *bdev, int no, long args) | 470 | dasd_ioctl_set_ro(struct block_device *bdev, int no, long args) |
461 | { | 471 | { |
462 | struct dasd_device *device; | 472 | struct dasd_device *device; |
463 | int intval; | 473 | int intval, rc; |
464 | 474 | ||
465 | if (!capable(CAP_SYS_ADMIN)) | 475 | if (!capable(CAP_SYS_ADMIN)) |
466 | return -EACCES; | 476 | return -EACCES; |
@@ -472,12 +482,11 @@ dasd_ioctl_set_ro(struct block_device *bdev, int no, long args) | |||
472 | device = bdev->bd_disk->private_data; | 482 | device = bdev->bd_disk->private_data; |
473 | if (device == NULL) | 483 | if (device == NULL) |
474 | return -ENODEV; | 484 | return -ENODEV; |
485 | |||
475 | set_disk_ro(bdev->bd_disk, intval); | 486 | set_disk_ro(bdev->bd_disk, intval); |
476 | if (intval) | 487 | rc = dasd_set_feature(device->cdev, DASD_FEATURE_READONLY, intval); |
477 | set_bit(DASD_FLAG_RO, &device->flags); | 488 | |
478 | else | 489 | return rc; |
479 | clear_bit(DASD_FLAG_RO, &device->flags); | ||
480 | return 0; | ||
481 | } | 490 | } |
482 | 491 | ||
483 | /* | 492 | /* |