aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHorst Hummel <horst.hummel@de.ibm.com>2005-05-01 11:58:59 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-05-01 11:58:59 -0400
commitf24acd4503270ed4c842c8fef0b71105285e0a06 (patch)
tree9125df60bf98ddcd8197bf479e8a48d22f51af14
parente8f0641ef74eaa71ed9aa9d19c4b741c2143d752 (diff)
[PATCH] s390: dasd readonly attribute
The independent read-only flags in devmap, dasd_device and gendisk are not kept in sync. Use one bit per feature in the dasd driver and keep that bit in sync with the gendisk bit. 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>
-rw-r--r--drivers/s390/block/dasd.c20
-rw-r--r--drivers/s390/block/dasd_devmap.c59
-rw-r--r--drivers/s390/block/dasd_genhd.c10
-rw-r--r--drivers/s390/block/dasd_int.h7
-rw-r--r--drivers/s390/block/dasd_ioctl.c31
-rw-r--r--drivers/s390/block/dasd_proc.c8
6 files changed, 93 insertions, 42 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index b755bac6ccbc..826fd238034d 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.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.158 $ 10 * $Revision: 1.161 $
11 */ 11 */
12 12
13#include <linux/config.h> 13#include <linux/config.h>
@@ -1131,13 +1131,17 @@ __dasd_process_blk_queue(struct dasd_device * device)
1131 request_queue_t *queue; 1131 request_queue_t *queue;
1132 struct request *req; 1132 struct request *req;
1133 struct dasd_ccw_req *cqr; 1133 struct dasd_ccw_req *cqr;
1134 int nr_queued; 1134 int nr_queued, feature_ro;
1135 1135
1136 queue = device->request_queue; 1136 queue = device->request_queue;
1137 /* No queue ? Then there is nothing to do. */ 1137 /* No queue ? Then there is nothing to do. */
1138 if (queue == NULL) 1138 if (queue == NULL)
1139 return; 1139 return;
1140 1140
1141 feature_ro = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY);
1142 if (feature_ro < 0) /* no devmap */
1143 return;
1144
1141 /* 1145 /*
1142 * We requeue request from the block device queue to the ccw 1146 * We requeue request from the block device queue to the ccw
1143 * queue only in two states. In state DASD_STATE_READY the 1147 * queue only in two states. In state DASD_STATE_READY the
@@ -1157,8 +1161,8 @@ __dasd_process_blk_queue(struct dasd_device * device)
1157 elv_next_request(queue) && 1161 elv_next_request(queue) &&
1158 nr_queued < DASD_CHANQ_MAX_SIZE) { 1162 nr_queued < DASD_CHANQ_MAX_SIZE) {
1159 req = elv_next_request(queue); 1163 req = elv_next_request(queue);
1160 if (test_bit(DASD_FLAG_RO, &device->flags) && 1164
1161 rq_data_dir(req) == WRITE) { 1165 if (feature_ro && rq_data_dir(req) == WRITE) {
1162 DBF_DEV_EVENT(DBF_ERR, device, 1166 DBF_DEV_EVENT(DBF_ERR, device,
1163 "Rejecting write request %p", 1167 "Rejecting write request %p",
1164 req); 1168 req);
@@ -1803,13 +1807,17 @@ dasd_generic_set_online (struct ccw_device *cdev,
1803 1807
1804{ 1808{
1805 struct dasd_device *device; 1809 struct dasd_device *device;
1806 int rc; 1810 int feature_diag, rc;
1811
1812 feature_diag = dasd_get_feature(cdev, DASD_FEATURE_USEDIAG);
1813 if (feature_diag < 0)
1814 return feature_diag;
1807 1815
1808 device = dasd_create_device(cdev); 1816 device = dasd_create_device(cdev);
1809 if (IS_ERR(device)) 1817 if (IS_ERR(device))
1810 return PTR_ERR(device); 1818 return PTR_ERR(device);
1811 1819
1812 if (test_bit(DASD_FLAG_USE_DIAG, &device->flags)) { 1820 if (feature_diag) {
1813 if (!dasd_diag_discipline_pointer) { 1821 if (!dasd_diag_discipline_pointer) {
1814 printk (KERN_WARNING 1822 printk (KERN_WARNING
1815 "dasd_generic couldn't online device %s " 1823 "dasd_generic couldn't online device %s "
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index ad1841a96c87..1aedc48e5f85 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -11,7 +11,7 @@
11 * functions may not be called from interrupt context. In particular 11 * functions may not be called from interrupt context. In particular
12 * dasd_get_device is a no-no from interrupt context. 12 * dasd_get_device is a no-no from interrupt context.
13 * 13 *
14 * $Revision: 1.37 $ 14 * $Revision: 1.40 $
15 */ 15 */
16 16
17#include <linux/config.h> 17#include <linux/config.h>
@@ -513,14 +513,6 @@ dasd_create_device(struct ccw_device *cdev)
513 if (!devmap->device) { 513 if (!devmap->device) {
514 devmap->device = device; 514 devmap->device = device;
515 device->devindex = devmap->devindex; 515 device->devindex = devmap->devindex;
516 if (devmap->features & DASD_FEATURE_READONLY)
517 set_bit(DASD_FLAG_RO, &device->flags);
518 else
519 clear_bit(DASD_FLAG_RO, &device->flags);
520 if (devmap->features & DASD_FEATURE_USEDIAG)
521 set_bit(DASD_FLAG_USE_DIAG, &device->flags);
522 else
523 clear_bit(DASD_FLAG_USE_DIAG, &device->flags);
524 get_device(&cdev->dev); 516 get_device(&cdev->dev);
525 device->cdev = cdev; 517 device->cdev = cdev;
526 rc = 0; 518 rc = 0;
@@ -651,14 +643,8 @@ dasd_ro_store(struct device *dev, const char *buf, size_t count)
651 devmap->features |= DASD_FEATURE_READONLY; 643 devmap->features |= DASD_FEATURE_READONLY;
652 else 644 else
653 devmap->features &= ~DASD_FEATURE_READONLY; 645 devmap->features &= ~DASD_FEATURE_READONLY;
654 if (devmap->device) { 646 if (devmap->device && devmap->device->gdp)
655 if (devmap->device->gdp) 647 set_disk_ro(devmap->device->gdp, ro_flag);
656 set_disk_ro(devmap->device->gdp, ro_flag);
657 if (ro_flag)
658 set_bit(DASD_FLAG_RO, &devmap->device->flags);
659 else
660 clear_bit(DASD_FLAG_RO, &devmap->device->flags);
661 }
662 spin_unlock(&dasd_devmap_lock); 648 spin_unlock(&dasd_devmap_lock);
663 return count; 649 return count;
664} 650}
@@ -739,6 +725,45 @@ static struct attribute_group dasd_attr_group = {
739 .attrs = dasd_attrs, 725 .attrs = dasd_attrs,
740}; 726};
741 727
728/*
729 * Return value of the specified feature.
730 */
731int
732dasd_get_feature(struct ccw_device *cdev, int feature)
733{
734 struct dasd_devmap *devmap;
735
736 devmap = dasd_find_busid(cdev->dev.bus_id);
737 if (IS_ERR(devmap))
738 return (int) PTR_ERR(devmap);
739
740 return ((devmap->features & feature) != 0);
741}
742
743/*
744 * Set / reset given feature.
745 * Flag indicates wether to set (!=0) or the reset (=0) the feature.
746 */
747int
748dasd_set_feature(struct ccw_device *cdev, int feature, int flag)
749{
750 struct dasd_devmap *devmap;
751
752 devmap = dasd_find_busid(cdev->dev.bus_id);
753 if (IS_ERR(devmap))
754 return (int) PTR_ERR(devmap);
755
756 spin_lock(&dasd_devmap_lock);
757 if (flag)
758 devmap->features |= feature;
759 else
760 devmap->features &= ~feature;
761
762 spin_unlock(&dasd_devmap_lock);
763 return 0;
764}
765
766
742int 767int
743dasd_add_sysfs_files(struct ccw_device *cdev) 768dasd_add_sysfs_files(struct ccw_device *cdev)
744{ 769{
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index 1d52db406b2e..96c49349701f 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -9,7 +9,7 @@
9 * 9 *
10 * gendisk related functions for the dasd driver. 10 * gendisk related functions for the dasd driver.
11 * 11 *
12 * $Revision: 1.48 $ 12 * $Revision: 1.50 $
13 */ 13 */
14 14
15#include <linux/config.h> 15#include <linux/config.h>
@@ -31,12 +31,16 @@ int
31dasd_gendisk_alloc(struct dasd_device *device) 31dasd_gendisk_alloc(struct dasd_device *device)
32{ 32{
33 struct gendisk *gdp; 33 struct gendisk *gdp;
34 int len; 34 int len, feature_ro;
35 35
36 /* Make sure the minor for this device exists. */ 36 /* Make sure the minor for this device exists. */
37 if (device->devindex >= DASD_PER_MAJOR) 37 if (device->devindex >= DASD_PER_MAJOR)
38 return -EBUSY; 38 return -EBUSY;
39 39
40 feature_ro = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY);
41 if (feature_ro < 0)
42 return feature_ro;
43
40 gdp = alloc_disk(1 << DASD_PARTN_BITS); 44 gdp = alloc_disk(1 << DASD_PARTN_BITS);
41 if (!gdp) 45 if (!gdp)
42 return -ENOMEM; 46 return -ENOMEM;
@@ -71,7 +75,7 @@ dasd_gendisk_alloc(struct dasd_device *device)
71 75
72 sprintf(gdp->devfs_name, "dasd/%s", device->cdev->dev.bus_id); 76 sprintf(gdp->devfs_name, "dasd/%s", device->cdev->dev.bus_id);
73 77
74 if (test_bit(DASD_FLAG_RO, &device->flags)) 78 if (feature_ro)
75 set_disk_ro(gdp, 1); 79 set_disk_ro(gdp, 1);
76 gdp->private_data = device; 80 gdp->private_data = device;
77 gdp->queue = device->request_queue; 81 gdp->queue = device->request_queue;
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 4586e0ecc526..a9f38b235981 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -6,7 +6,7 @@
6 * Bugreports.to..: <Linux390@de.ibm.com> 6 * Bugreports.to..: <Linux390@de.ibm.com>
7 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 7 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
8 * 8 *
9 * $Revision: 1.63 $ 9 * $Revision: 1.64 $
10 */ 10 */
11 11
12#ifndef DASD_INT_H 12#ifndef DASD_INT_H
@@ -329,8 +329,6 @@ struct dasd_device {
329#define DASD_STOPPED_DC_EIO 16 /* disconnected, return -EIO */ 329#define DASD_STOPPED_DC_EIO 16 /* disconnected, return -EIO */
330 330
331/* per device flags */ 331/* per device flags */
332#define DASD_FLAG_RO 0 /* device is read-only */
333#define DASD_FLAG_USE_DIAG 1 /* use diag disciplnie */
334#define DASD_FLAG_DSC_ERROR 2 /* return -EIO when disconnected */ 332#define DASD_FLAG_DSC_ERROR 2 /* return -EIO when disconnected */
335#define DASD_FLAG_OFFLINE 3 /* device is in offline processing */ 333#define DASD_FLAG_OFFLINE 3 /* device is in offline processing */
336 334
@@ -501,6 +499,9 @@ void dasd_devmap_exit(void);
501struct dasd_device *dasd_create_device(struct ccw_device *); 499struct dasd_device *dasd_create_device(struct ccw_device *);
502void dasd_delete_device(struct dasd_device *); 500void dasd_delete_device(struct dasd_device *);
503 501
502int dasd_get_feature(struct ccw_device *, int);
503int dasd_set_feature(struct ccw_device *, int, int);
504
504int dasd_add_sysfs_files(struct ccw_device *); 505int dasd_add_sysfs_files(struct ccw_device *);
505void dasd_remove_sysfs_files(struct ccw_device *); 506void dasd_remove_sysfs_files(struct ccw_device *);
506 507
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index f1892baa3b18..980c555aa538 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
460dasd_ioctl_set_ro(struct block_device *bdev, int no, long args) 470dasd_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/*
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index 353d41118c62..d7f19745911f 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -9,7 +9,7 @@
9 * 9 *
10 * /proc interface for the dasd driver. 10 * /proc interface for the dasd driver.
11 * 11 *
12 * $Revision: 1.30 $ 12 * $Revision: 1.31 $
13 */ 13 */
14 14
15#include <linux/config.h> 15#include <linux/config.h>
@@ -54,6 +54,7 @@ dasd_devices_show(struct seq_file *m, void *v)
54{ 54{
55 struct dasd_device *device; 55 struct dasd_device *device;
56 char *substr; 56 char *substr;
57 int feature;
57 58
58 device = dasd_device_from_devindex((unsigned long) v - 1); 59 device = dasd_device_from_devindex((unsigned long) v - 1);
59 if (IS_ERR(device)) 60 if (IS_ERR(device))
@@ -77,7 +78,10 @@ dasd_devices_show(struct seq_file *m, void *v)
77 else 78 else
78 seq_printf(m, " is ????????"); 79 seq_printf(m, " is ????????");
79 /* Print devices features. */ 80 /* Print devices features. */
80 substr = test_bit(DASD_FLAG_RO, &device->flags) ? "(ro)" : " "; 81 feature = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY);
82 if (feature < 0)
83 return 0;
84 substr = feature ? "(ro)" : " ";
81 seq_printf(m, "%4s: ", substr); 85 seq_printf(m, "%4s: ", substr);
82 /* Print device status information. */ 86 /* Print device status information. */
83 switch ((device != NULL) ? device->state : -1) { 87 switch ((device != NULL) ? device->state : -1) {