]> git.hungrycats.org Git - linux/commitdiff
[PATCH] s390: dasd driver.
authorAndrew Morton <akpm@osdl.org>
Sat, 27 Mar 2004 05:00:37 +0000 (21:00 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Sat, 27 Mar 2004 05:00:37 +0000 (21:00 -0800)
From: Martin Schwidefsky <schwidefsky@de.ibm.com>

dasd device driver changes:
 - After a state change interrupt restart all running i/o on queue
   and reset device timer.
 - Improve some debug messages.
 - Lower timeout of reserve/release/steal_lock to 2 seconds.
 - Fix BIODASDPSRD ioctl.
 - Replace ro_flag, use_diag_flag and disconnect_error_flag words by bits.
 - Use BLKPG_DEL_PARTITION ioctl instead of a call to delete_partition because
   delete_partition is not an exported function. Since dasd_destroy_partitions
   can't do blkdev_get because dasd_open would fail, keep the block device
   open as long as partitions exist. This in turn requires a different
   approach to the open vs. offline race.

drivers/s390/block/dasd.c
drivers/s390/block/dasd_3990_erp.c
drivers/s390/block/dasd_devmap.c
drivers/s390/block/dasd_eckd.c
drivers/s390/block/dasd_genhd.c
drivers/s390/block/dasd_int.h
drivers/s390/block/dasd_ioctl.c
drivers/s390/block/dasd_proc.c

index a8395ca67fa091ee6d1fac274ee732fba4fdc050..d0ab034fa0c1834542b030458f0875ad271f4e7d 100644 (file)
@@ -7,7 +7,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
  *
- * $Revision: 1.133 $
+ * $Revision: 1.136 $
  */
 
 #include <linux/config.h>
@@ -224,7 +224,8 @@ dasd_state_basic_to_ready(struct dasd_device * device)
                return rc;
        dasd_setup_queue(device);
        device->state = DASD_STATE_READY;
-       dasd_scan_partitions(device);
+       if (dasd_scan_partitions(device) != 0)
+               device->state = DASD_STATE_BASIC;
        return 0;
 }
 
@@ -687,7 +688,10 @@ dasd_term_IO(struct dasd_ccw_req * cqr)
                rc = ccw_device_clear(device->cdev, (long) cqr);
                switch (rc) {
                case 0: /* termination successful */
-                       cqr->status = DASD_CQR_FAILED;
+                       if (cqr->retries > 0)
+                               cqr->status = DASD_CQR_QUEUED;
+                       else
+                               cqr->status = DASD_CQR_FAILED;
                        cqr->stopclk = get_clock();
                        break;
                case -ENODEV:
@@ -779,7 +783,7 @@ dasd_timeout_device(unsigned long ptr)
 
        device = (struct dasd_device *) ptr;
        spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
-       /* re-activate first request in queue */
+       /* re-activate request queue */
         device->stopped &= ~DASD_STOPPED_PENDING;
        spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
        dasd_schedule_bh(device);
@@ -827,12 +831,25 @@ do_state_change_pending(void *data)
                struct dasd_device *device;
        } *p;
        struct dasd_device *device;
+       struct dasd_ccw_req *cqr;
+       struct list_head *l, *n;
+       unsigned long flags;
 
        p = data;
        device = p->device;
        DBF_EVENT(DBF_NOTICE, "State change Interrupt for bus_id %s",
                  device->cdev->dev.bus_id);
        device->stopped &= ~DASD_STOPPED_PENDING;
+
+        /* restart all 'running' IO on queue */
+       spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
+       list_for_each_safe(l, n, &device->ccw_queue) {
+               cqr = list_entry(l, struct dasd_ccw_req, list);
+                if (cqr->status == DASD_CQR_IN_IO)
+                        cqr->status = DASD_CQR_QUEUED;
+        }
+       spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
+       dasd_set_timer (device, 0);
        dasd_schedule_bh(device);
        dasd_put_device(device);
        kfree(p);
@@ -847,7 +864,8 @@ dasd_handle_killed_request(struct ccw_device *cdev, unsigned long intparm)
        cqr = (struct dasd_ccw_req *) intparm;
        if (cqr->status != DASD_CQR_IN_IO) {
                MESSAGE(KERN_DEBUG,
-                       "invalid status: bus_id %s, status %02x",
+                       "invalid status in handle_killed_request: "
+                       "bus_id %s, status %02x",
                        cdev->dev.bus_id, cqr->status);
                return;
        }
@@ -1142,7 +1160,8 @@ __dasd_process_blk_queue(struct dasd_device * device)
               elv_next_request(queue) &&
                nr_queued < DASD_CHANQ_MAX_SIZE) {
                req = elv_next_request(queue);
-               if (device->ro_flag && rq_data_dir(req) == WRITE) {
+               if (test_bit(DASD_FLAG_RO, &device->flags) &&
+                   rq_data_dir(req) == WRITE) {
                        DBF_EVENT(DBF_ERR,
                                  "(%s) Rejecting write request %p",
                                  device->cdev->dev.bus_id,
@@ -1186,13 +1205,11 @@ static inline void
 __dasd_check_expire(struct dasd_device * device)
 {
        struct dasd_ccw_req *cqr;
-       unsigned long long now;
 
        if (list_empty(&device->ccw_queue))
                return;
        cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list);
        if (cqr->status == DASD_CQR_IN_IO && cqr->expires != 0) {
-               now = get_clock();
                if (time_after_eq(jiffies, cqr->expires + cqr->starttime)) {
                        if (device->discipline->term_IO(cqr) != 0)
                                /* Hmpf, try again in 1/100 sec */
@@ -1517,7 +1534,8 @@ dasd_sleep_on_immediatly(struct dasd_ccw_req * cqr)
  * terminated if it is currently in i/o.
  * Returns 1 if the request has been terminated.
  */
-int dasd_cancel_req(struct dasd_ccw_req *cqr)
+int
+dasd_cancel_req(struct dasd_ccw_req *cqr)
 {
        struct dasd_device *device = cqr->device;
        unsigned long flags;
@@ -1655,18 +1673,13 @@ dasd_open(struct inode *inp, struct file *filp)
 {
        struct gendisk *disk = inp->i_bdev->bd_disk;
        struct dasd_device *device = disk->private_data;
-       int old_count, rc;
+       int rc;
 
-       /*
-        * We use a negative value in open_count to indicate that
-        * the device must not be used.
-        */
-       do {
-               old_count = atomic_read(&device->open_count);
-               if (old_count < 0)
-                       return -ENODEV;
-       } while (atomic_compare_and_swap(old_count, old_count + 1,
-                                        &device->open_count));
+        atomic_inc(&device->open_count);
+       if (test_bit(DASD_FLAG_OFFLINE, &device->flags)) {
+               rc = -ENODEV;
+               goto unlock;
+       }
 
        if (!try_module_get(device->discipline->owner)) {
                rc = -EINVAL;
@@ -1681,7 +1694,6 @@ dasd_open(struct inode *inp, struct file *filp)
                goto out;
        }
 
-       rc = -ENODEV;
        if (device->state < DASD_STATE_BASIC) {
                DBF_DEV_EVENT(DBF_ERR, device, " %s",
                              " Cannot open unrecognized device");
@@ -1704,12 +1716,6 @@ dasd_release(struct inode *inp, struct file *filp)
        struct gendisk *disk = inp->i_bdev->bd_disk;
        struct dasd_device *device = disk->private_data;
 
-       if (device->state < DASD_STATE_BASIC) {
-               DBF_DEV_EVENT(DBF_ERR, device, " %s",
-                             " Cannot release unrecognized device");
-               return -EINVAL;
-       }
-
        atomic_dec(&device->open_count);
        module_put(device->discipline->owner);
        return 0;
@@ -1773,17 +1779,21 @@ dasd_generic_remove (struct ccw_device *cdev)
 
        dasd_remove_sysfs_files(cdev);
        device = dasd_device_from_cdev(cdev);
-       if (!IS_ERR(device)) {
-               /*
-                * This device is removed unconditionally. Set open_count
-                * to -1 to prevent dasd_open from opening it while it is
-                * no quite down yet.
-                */
-               atomic_set(&device->open_count,-1);
-               dasd_set_target_state(device, DASD_STATE_NEW);
-               /* dasd_delete_device destroys the device reference. */
-               dasd_delete_device(device);
+       if (IS_ERR(device))
+               return;
+       if (test_and_set_bit(DASD_FLAG_OFFLINE, &device->flags)) {
+               /* Already doing offline processing */
+               dasd_put_device(device);
+               return;
        }
+       /*
+        * This device is removed unconditionally. Set offline
+        * flag to prevent dasd_open from opening it while it is
+        * no quite down yet.
+        */
+       dasd_set_target_state(device, DASD_STATE_NEW);
+       /* dasd_delete_device destroys the device reference. */
+       dasd_delete_device(device);
 }
 
 /* activate a device. This is called from dasd_{eckd,fba}_probe() when either
@@ -1801,7 +1811,7 @@ dasd_generic_set_online (struct ccw_device *cdev,
        if (IS_ERR(device))
                return PTR_ERR(device);
 
-       if (device->use_diag_flag) {
+       if (test_bit(DASD_FLAG_USE_DIAG, &device->flags)) {
                if (!dasd_diag_discipline_pointer) {
                        printk (KERN_WARNING
                                "dasd_generic couldn't online device %s "
@@ -1849,18 +1859,28 @@ int
 dasd_generic_set_offline (struct ccw_device *cdev)
 {
        struct dasd_device *device;
+       int max_count;
 
        device = dasd_device_from_cdev(cdev);
+       if (IS_ERR(device))
+               return PTR_ERR(device);
+       if (test_and_set_bit(DASD_FLAG_OFFLINE, &device->flags)) {
+               /* Already doing offline processing */
+               dasd_put_device(device);
+               return 0;
+       }
        /*
-        * We must make sure that this device is currently not in use
-        * (current open_count == 0 ). We set open_count to -1 to indicate
-        * that from now on set_offline is in progress and the device must
-        * not be used otherwise.
+        * We must make sure that this device is currently not in use.
+        * The open_count is increased for every opener, that includes
+        * the blkdev_get in dasd_scan_partitions. We are only interested
+        * in the other openers.
         */
-       if (atomic_compare_and_swap(0, -1, &device->open_count)) {
+       max_count = device->bdev ? 1 : 0;
+       if (atomic_read(&device->open_count) > max_count) {
                printk (KERN_WARNING "Can't offline dasd device with open"
                        " count = %i.\n",
                        atomic_read(&device->open_count));
+               clear_bit(DASD_FLAG_OFFLINE, &device->flags);
                dasd_put_device(device);
                return -EBUSY;
        }
@@ -1890,7 +1910,7 @@ dasd_generic_notify(struct ccw_device *cdev, int event)
                if (device->state < DASD_STATE_BASIC)
                        break;
                /* Device is active. We want to keep it. */
-               if (device->disconnect_error_flag) {
+               if (test_bit(DASD_FLAG_DSC_ERROR, &device->flags)) {
                        list_for_each_entry(cqr, &device->ccw_queue, list)
                                if (cqr->status == DASD_CQR_IN_IO)
                                        cqr->status = DASD_CQR_FAILED;
index 711f1c17207ecf5bcd94f1d0550d21923d2c7012..c6b26e729aaa82e4c327d31479dea265d4739be3 100644 (file)
@@ -5,7 +5,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001
  *
- * $Revision: 1.27 $
+ * $Revision: 1.28 $
  */
 
 #include <linux/timer.h>
@@ -229,7 +229,7 @@ dasd_3990_erp_block_queue(struct dasd_ccw_req * erp, int expires)
        struct dasd_device *device = erp->device;
 
        DEV_MESSAGE(KERN_INFO, device,
-                   "blocking request queue for %is", expires);
+                   "blocking request queue for %is", expires/HZ);
 
        device->stopped |= DASD_STOPPED_PENDING;
        erp->status = DASD_CQR_QUEUED;
@@ -2623,7 +2623,7 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
 
 #ifdef ERP_DEBUG
        /* print current erp_chain */
-       DEV_MESSAGE(KERN_DEBUG, device, "%s",
+       DEV_MESSAGE(KERN_ERR, device, "%s",
                    "ERP chain at BEGINNING of ERP-ACTION");
        {
                struct dasd_ccw_req *temp_erp = NULL;
@@ -2631,9 +2631,10 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
                for (temp_erp = cqr;
                     temp_erp != NULL; temp_erp = temp_erp->refers) {
 
-                       DEV_MESSAGE(KERN_DEBUG, device,
-                                   "      erp %p refers to %p",
-                                   temp_erp, temp_erp->refers);
+                       DEV_MESSAGE(KERN_ERR, device,
+                                   "   erp %p (%02x) refers to %p",
+                                   temp_erp, temp_erp->status,
+                                   temp_erp->refers);
                }
        }
 #endif                         /* ERP_DEBUG */
@@ -2675,15 +2676,16 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
 
 #ifdef ERP_DEBUG
        /* print current erp_chain */
-       DEV_MESSAGE(KERN_DEBUG, device, "%s", "ERP chain at END of ERP-ACTION");
+       DEV_MESSAGE(KERN_ERR, device, "%s", "ERP chain at END of ERP-ACTION");
        {
                struct dasd_ccw_req *temp_erp = NULL;
                for (temp_erp = erp;
                     temp_erp != NULL; temp_erp = temp_erp->refers) {
 
-                       DEV_MESSAGE(KERN_DEBUG, device,
-                                   "      erp %p refers to %p",
-                                   temp_erp, temp_erp->refers);
+                       DEV_MESSAGE(KERN_ERR, device,
+                                   "   erp %p (%02x) refers to %p",
+                                   temp_erp, temp_erp->status,
+                                   temp_erp->refers);
                }
        }
 #endif                         /* ERP_DEBUG */
index a2b38b2248a0c8e4d6d7962b5a2293ac51f61a40..0fad4d5ce41858cf4f65f7cf9a00bb952662f512 100644 (file)
@@ -11,7 +11,7 @@
  * functions may not be called from interrupt context. In particular
  * dasd_get_device is a no-no from interrupt context.
  *
- * $Revision: 1.26 $
+ * $Revision: 1.27 $
  */
 
 #include <linux/config.h>
@@ -466,10 +466,14 @@ dasd_create_device(struct ccw_device *cdev)
        if (!devmap->device) {
                devmap->device = device;
                device->devindex = devmap->devindex;
-               device->ro_flag = 
-                       (devmap->features & DASD_FEATURE_READONLY) != 0;
-               device->use_diag_flag = 
-                       (devmap->features & DASD_FEATURE_USEDIAG) != 0;
+               if (devmap->features & DASD_FEATURE_READONLY)
+                       set_bit(DASD_FLAG_RO, &device->flags);
+               else
+                       clear_bit(DASD_FLAG_RO, &device->flags);
+               if (devmap->features & DASD_FEATURE_USEDIAG)
+                       set_bit(DASD_FLAG_USE_DIAG, &device->flags);
+               else
+                       clear_bit(DASD_FLAG_USE_DIAG, &device->flags);
                get_device(&cdev->dev);
                device->cdev = cdev;
                rc = 0;
@@ -596,7 +600,10 @@ dasd_ro_store(struct device *dev, const char *buf, size_t count)
        if (devmap->device) {
                if (devmap->device->gdp)
                        set_disk_ro(devmap->device->gdp, ro_flag);
-               devmap->device->ro_flag = ro_flag;
+               if (ro_flag)
+                       set_bit(DASD_FLAG_RO, &devmap->device->flags);
+               else
+                       clear_bit(DASD_FLAG_RO, &devmap->device->flags);
        }
        spin_unlock(&dasd_devmap_lock);
        return count;
index 4c66d72de3ba69aeb757041cb77643c8b64e41b0..1490f1e4a4ec7d998805a4488d7c43b12125e78f 100644 (file)
@@ -7,7 +7,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.51 $
+ * $Revision: 1.53 $
  */
 
 #include <linux/config.h>
@@ -1131,7 +1131,7 @@ dasd_eckd_release(struct block_device *bdev, int no, long args)
        cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
        cqr->device = device;
        cqr->retries = 0;
-       cqr->expires = 10 * HZ;
+       cqr->expires = 2 * HZ;
        cqr->buildclk = get_clock();
        cqr->status = DASD_CQR_FILLED;
 
@@ -1174,7 +1174,7 @@ dasd_eckd_reserve(struct block_device *bdev, int no, long args)
        cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
        cqr->device = device;
        cqr->retries = 0;
-       cqr->expires = 10 * HZ;
+       cqr->expires = 2 * HZ;
        cqr->buildclk = get_clock();
        cqr->status = DASD_CQR_FILLED;
 
@@ -1216,7 +1216,7 @@ dasd_eckd_steal_lock(struct block_device *bdev, int no, long args)
        cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
        cqr->device = device;
        cqr->retries = 0;
-       cqr->expires = 10 * HZ;
+       cqr->expires = 2 * HZ;
        cqr->buildclk = get_clock();
        cqr->status = DASD_CQR_FILLED;
 
@@ -1274,6 +1274,7 @@ dasd_eckd_performance(struct block_device *bdev, int no, long args)
        stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1);
        memset(stats, 0, sizeof (struct dasd_rssd_perf_stats_t));
 
+       ccw++;
        ccw->cmd_code = DASD_ECKD_CCW_RSSD;
        ccw->count = sizeof (struct dasd_rssd_perf_stats_t);
        ccw->cda = (__u32)(addr_t) stats;
index 62099f5bf582b32ebf8df340aef6dff4431070b7..44b6e73f06e6c3044c1365a180a0195b9423165e 100644 (file)
@@ -9,7 +9,7 @@
  *
  * gendisk related functions for the dasd driver.
  *
- * $Revision: 1.44 $
+ * $Revision: 1.46 $
  */
 
 #include <linux/config.h>
@@ -71,7 +71,7 @@ dasd_gendisk_alloc(struct dasd_device *device)
 
        sprintf(gdp->devfs_name, "dasd/%s", device->cdev->dev.bus_id);
 
-       if (device->ro_flag)
+       if (test_bit(DASD_FLAG_RO, &device->flags))
                set_disk_ro(gdp, 1);
        gdp->private_data = device;
        gdp->queue = device->request_queue;
@@ -96,22 +96,33 @@ dasd_gendisk_free(struct dasd_device *device)
 /*
  * Trigger a partition detection.
  */
-void
+int
 dasd_scan_partitions(struct dasd_device * device)
 {
        struct block_device *bdev;
 
        /* Make the disk known. */
        set_capacity(device->gdp, device->blocks << device->s2b_shift);
-       /* See fs/partition/check.c:register_disk,rescan_partitions */
        bdev = bdget_disk(device->gdp, 0);
-       if (bdev) {
-               if (blkdev_get(bdev, FMODE_READ, 1) >= 0) {
-                       /* Can't call rescan_partitions directly. Use ioctl. */
-                       ioctl_by_bdev(bdev, BLKRRPART, 0);
-                       blkdev_put(bdev);
-               }
-       }
+       if (!bdev || blkdev_get(bdev, FMODE_READ, 1) < 0)
+               return -ENODEV;
+       /*
+        * See fs/partition/check.c:register_disk,rescan_partitions
+        * Can't call rescan_partitions directly. Use ioctl.
+        */
+       ioctl_by_bdev(bdev, BLKRRPART, 0);
+       /*
+        * Since the matching blkdev_put call to the blkdev_get in
+        * this function is not called before dasd_destroy_partitions
+        * the offline open_count limit needs to be increased from
+        * 0 to 1. This is done by setting device->bdev (see
+        * dasd_generic_set_offline). As long as the partition
+        * detection is running no offline should be allowed. That
+        * is why the assignment to device->bdev is done AFTER
+        * the BLKRRPART ioctl.
+        */
+       device->bdev = bdev;
+       return 0;
 }
 
 /*
@@ -121,13 +132,32 @@ dasd_scan_partitions(struct dasd_device * device)
 void
 dasd_destroy_partitions(struct dasd_device * device)
 {
-       int p;
+       /* The two structs have 168/176 byte on 31/64 bit. */
+       struct blkpg_partition bpart;
+       struct blkpg_ioctl_arg barg;
+       struct block_device *bdev;
+
+       /*
+        * Get the bdev pointer from the device structure and clear
+        * device->bdev to lower the offline open_count limit again.
+        */
+       bdev = device->bdev;
+       device->bdev = 0;
+
+       /*
+        * See fs/partition/check.c:delete_partition
+        * Can't call delete_partitions directly. Use ioctl.
+        * The ioctl also does locking and invalidation.
+        */
+       memset(&bpart, sizeof(struct blkpg_partition), 0);
+       memset(&barg, sizeof(struct blkpg_ioctl_arg), 0);
+       barg.data = &bpart;
+       for (bpart.pno = device->gdp->minors - 1; bpart.pno > 0; bpart.pno--)
+               ioctl_by_bdev(bdev, BLKPG_DEL_PARTITION, (unsigned long) &barg);
 
-       for (p = device->gdp->minors - 1; p > 0; p--) {
-               invalidate_partition(device->gdp, p);
-               delete_partition(device->gdp, p);
-       }
        invalidate_partition(device->gdp, 0);
+       /* Matching blkdev_put to the blkdev_get in dasd_scan_partitions. */
+       blkdev_put(bdev);
        set_capacity(device->gdp, 0);
 }
 
index 2cdb395dab78b70dc851ce880dc59a7dd787ab08..70ccb1110d07741194940341063f042fca3dc9a5 100644 (file)
@@ -6,7 +6,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.55 $
+ * $Revision: 1.56 $
  */
 
 #ifndef DASD_INT_H
@@ -268,14 +268,12 @@ struct dasd_device {
        struct gendisk *gdp;
        request_queue_t *request_queue;
        spinlock_t request_queue_lock;
+       struct block_device *bdev;
         unsigned int devindex;
        unsigned long blocks;           /* size of volume in blocks */
        unsigned int bp_block;          /* bytes per block */
        unsigned int s2b_shift;         /* log2 (bp_block/512) */
-       int ro_flag;                    /* read-only flag */
-       int use_diag_flag;              /* diag allowed flag */
-       int disconnect_error_flag;      /* return -EIO when disconnected */
-
+       unsigned long flags;            /* per device flags */
 
        /* Device discipline stuff. */
        struct dasd_discipline *discipline;
@@ -318,6 +316,11 @@ struct dasd_device {
 #define DASD_STOPPED_DC_WAIT 8         /* disconnected, wait */
 #define DASD_STOPPED_DC_EIO  16        /* disconnected, return -EIO */
 
+/* per device flags */
+#define DASD_FLAG_RO           0       /* device is read-only */
+#define DASD_FLAG_USE_DIAG     1       /* use diag disciplnie */
+#define DASD_FLAG_DSC_ERROR    2       /* return -EIO when disconnected */
+#define DASD_FLAG_OFFLINE      3       /* device is in offline processing */
 
 void dasd_put_device_wake(struct dasd_device *);
 
@@ -498,7 +501,7 @@ int  dasd_gendisk_init(void);
 void dasd_gendisk_exit(void);
 int dasd_gendisk_alloc(struct dasd_device *);
 void dasd_gendisk_free(struct dasd_device *);
-void dasd_scan_partitions(struct dasd_device *);
+int dasd_scan_partitions(struct dasd_device *);
 void dasd_destroy_partitions(struct dasd_device *);
 
 /* externals in dasd_ioctl.c */
index 753bb94839e17a187db02bf7a64879b295781a9a..3efdcad2592875cf33c898fdb15155159c2847d3 100644 (file)
@@ -303,7 +303,7 @@ dasd_ioctl_format(struct block_device *bdev, int no, long args)
 
        if (device == NULL)
                return -ENODEV;
-       if (device->ro_flag)
+       if (test_bit(DASD_FLAG_RO, &device->flags))
                return -EROFS;
        if (copy_from_user(&fdata, (void *) args,
                           sizeof (struct format_data_t)))
@@ -415,8 +415,8 @@ dasd_ioctl_information(struct block_device *bdev, int no, long args)
            (dasd_check_blocksize(device->bp_block)))
                dasd_info->format = DASD_FORMAT_NONE;
        
-       dasd_info->features |= device->ro_flag ? DASD_FEATURE_READONLY
-                                              : DASD_FEATURE_DEFAULT;
+       dasd_info->features |= test_bit(DASD_FLAG_RO, &device->flags) ?
+               DASD_FEATURE_READONLY : DASD_FEATURE_DEFAULT;
 
        if (device->discipline)
                memcpy(dasd_info->type, device->discipline->name, 4);
@@ -472,7 +472,10 @@ dasd_ioctl_set_ro(struct block_device *bdev, int no, long args)
        if (device == NULL)
                return -ENODEV;
        set_disk_ro(bdev->bd_disk, intval);
-       device->ro_flag = intval;
+       if (intval)
+               set_bit(DASD_FLAG_RO, &device->flags);
+       else
+               clear_bit(DASD_FLAG_RO, &device->flags);
        return 0;
 }
 
index 386379bdc3bf624040f1996f169d65e5de6b57ae..70d6136d7c77ec991137417174fb23e826bf2790 100644 (file)
@@ -9,7 +9,7 @@
  *
  * /proc interface for the dasd driver.
  *
- * $Revision: 1.26 $
+ * $Revision: 1.27 $
  */
 
 #include <linux/config.h>
@@ -77,7 +77,7 @@ dasd_devices_show(struct seq_file *m, void *v)
        else
                seq_printf(m, " is ????????");
        /* Print devices features. */
-       substr = device->ro_flag ? "(ro)" : " ";
+       substr = test_bit(DASD_FLAG_RO, &device->flags) ? "(ro)" : " ";
        seq_printf(m, "%4s: ", substr);
        /* Print device status information. */
        switch ((device != NULL) ? device->state : -1) {