]> err.no Git - linux-2.6/blobdiff - drivers/md/md.c
Merge ssh://master.kernel.org/pub/scm/linux/kernel/git/sam/kbuild
[linux-2.6] / drivers / md / md.c
index 65ddc887dfd72dc97a2ace8bb4c8bbf93c8e5f94..808cd95494563d260456733e0d1e9ba80cbee21e 100644 (file)
@@ -211,9 +211,9 @@ static DEFINE_SPINLOCK(all_mddevs_lock);
                )
 
 
-static int md_fail_request (request_queue_t *q, struct bio *bio)
+static int md_fail_request (struct request_queue *q, struct bio *bio)
 {
-       bio_io_error(bio, bio->bi_size);
+       bio_io_error(bio);
        return 0;
 }
 
@@ -384,12 +384,10 @@ static void free_disk_sb(mdk_rdev_t * rdev)
 }
 
 
-static int super_written(struct bio *bio, unsigned int bytes_done, int error)
+static void super_written(struct bio *bio, int error)
 {
        mdk_rdev_t *rdev = bio->bi_private;
        mddev_t *mddev = rdev->mddev;
-       if (bio->bi_size)
-               return 1;
 
        if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags)) {
                printk("md: super_written gets error=%d, uptodate=%d\n",
@@ -401,16 +399,13 @@ static int super_written(struct bio *bio, unsigned int bytes_done, int error)
        if (atomic_dec_and_test(&mddev->pending_writes))
                wake_up(&mddev->sb_wait);
        bio_put(bio);
-       return 0;
 }
 
-static int super_written_barrier(struct bio *bio, unsigned int bytes_done, int error)
+static void super_written_barrier(struct bio *bio, int error)
 {
        struct bio *bio2 = bio->bi_private;
        mdk_rdev_t *rdev = bio2->bi_private;
        mddev_t *mddev = rdev->mddev;
-       if (bio->bi_size)
-               return 1;
 
        if (!test_bit(BIO_UPTODATE, &bio->bi_flags) &&
            error == -EOPNOTSUPP) {
@@ -424,11 +419,11 @@ static int super_written_barrier(struct bio *bio, unsigned int bytes_done, int e
                spin_unlock_irqrestore(&mddev->write_lock, flags);
                wake_up(&mddev->sb_wait);
                bio_put(bio);
-               return 0;
+       } else {
+               bio_put(bio2);
+               bio->bi_private = rdev;
+               super_written(bio, error);
        }
-       bio_put(bio2);
-       bio->bi_private = rdev;
-       return super_written(bio, bytes_done, error);
 }
 
 void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
@@ -489,13 +484,9 @@ void md_super_wait(mddev_t *mddev)
        finish_wait(&mddev->sb_wait, &wq);
 }
 
-static int bi_complete(struct bio *bio, unsigned int bytes_done, int error)
+static void bi_complete(struct bio *bio, int error)
 {
-       if (bio->bi_size)
-               return 1;
-
        complete((struct completion*)bio->bi_private);
-       return 0;
 }
 
 int sync_page_io(struct block_device *bdev, sector_t sector, int size,
@@ -2723,7 +2714,7 @@ action_show(mddev_t *mddev, char *page)
 {
        char *type = "idle";
        if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
-           test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) {
+           (!mddev->ro && test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))) {
                if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
                        type = "reshape";
                else if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
@@ -2842,6 +2833,12 @@ sync_max_store(mddev_t *mddev, const char *buf, size_t len)
 static struct md_sysfs_entry md_sync_max =
 __ATTR(sync_speed_max, S_IRUGO|S_IWUSR, sync_max_show, sync_max_store);
 
+static ssize_t
+degraded_show(mddev_t *mddev, char *page)
+{
+       return sprintf(page, "%d\n", mddev->degraded);
+}
+static struct md_sysfs_entry md_degraded = __ATTR_RO(degraded);
 
 static ssize_t
 sync_speed_show(mddev_t *mddev, char *page)
@@ -2985,6 +2982,7 @@ static struct attribute *md_redundancy_attrs[] = {
        &md_suspend_lo.attr,
        &md_suspend_hi.attr,
        &md_bitmap.attr,
+       &md_degraded.attr,
        NULL,
 };
 static struct attribute_group md_redundancy_group = {
@@ -3085,8 +3083,7 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data)
        mddev->gendisk = disk;
        mutex_unlock(&disks_mutex);
        mddev->kobj.parent = &disk->kobj;
-       mddev->kobj.k_name = NULL;
-       snprintf(mddev->kobj.name, KOBJ_NAME_LEN, "%s", "md");
+       kobject_set_name(&mddev->kobj, "%s", "md");
        mddev->kobj.ktype = &md_ktype;
        if (kobject_register(&mddev->kobj))
                printk(KERN_WARNING "md: cannot register %s/md - name in use\n",
@@ -3473,7 +3470,6 @@ static int do_md_stop(mddev_t * mddev, int mode)
                        mddev->pers->stop(mddev);
                        mddev->queue->merge_bvec_fn = NULL;
                        mddev->queue->unplug_fn = NULL;
-                       mddev->queue->issue_flush_fn = NULL;
                        mddev->queue->backing_dev_info.congested_fn = NULL;
                        if (mddev->pers->sync_request)
                                sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
@@ -4721,7 +4717,7 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
 
 void md_unregister_thread(mdk_thread_t *thread)
 {
-       dprintk("interrupting MD-thread pid %d\n", thread->tsk->pid);
+       dprintk("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk));
 
        kthread_stop(thread->tsk);
        kfree(thread);
@@ -5781,26 +5777,47 @@ static int __init md_init(void)
  * Searches all registered partitions for autorun RAID arrays
  * at boot time.
  */
-static dev_t detected_devices[128];
-static int dev_cnt;
+
+static LIST_HEAD(all_detected_devices);
+struct detected_devices_node {
+       struct list_head list;
+       dev_t dev;
+};
 
 void md_autodetect_dev(dev_t dev)
 {
-       if (dev_cnt >= 0 && dev_cnt < 127)
-               detected_devices[dev_cnt++] = dev;
+       struct detected_devices_node *node_detected_dev;
+
+       node_detected_dev = kzalloc(sizeof(*node_detected_dev), GFP_KERNEL);
+       if (node_detected_dev) {
+               node_detected_dev->dev = dev;
+               list_add_tail(&node_detected_dev->list, &all_detected_devices);
+       } else {
+               printk(KERN_CRIT "md: md_autodetect_dev: kzalloc failed"
+                       ", skipping dev(%d,%d)\n", MAJOR(dev), MINOR(dev));
+       }
 }
 
 
 static void autostart_arrays(int part)
 {
        mdk_rdev_t *rdev;
-       int i;
+       struct detected_devices_node *node_detected_dev;
+       dev_t dev;
+       int i_scanned, i_passed;
 
-       printk(KERN_INFO "md: Autodetecting RAID arrays.\n");
+       i_scanned = 0;
+       i_passed = 0;
 
-       for (i = 0; i < dev_cnt; i++) {
-               dev_t dev = detected_devices[i];
+       printk(KERN_INFO "md: Autodetecting RAID arrays.\n");
 
+       while (!list_empty(&all_detected_devices) && i_scanned < INT_MAX) {
+               i_scanned++;
+               node_detected_dev = list_entry(all_detected_devices.next,
+                                       struct detected_devices_node, list);
+               list_del(&node_detected_dev->list);
+               dev = node_detected_dev->dev;
+               kfree(node_detected_dev);
                rdev = md_import_device(dev,0, 90);
                if (IS_ERR(rdev))
                        continue;
@@ -5810,8 +5827,11 @@ static void autostart_arrays(int part)
                        continue;
                }
                list_add(&rdev->same_set, &pending_raid_disks);
+               i_passed++;
        }
-       dev_cnt = 0;
+
+       printk(KERN_INFO "md: Scanned %d and added %d devices.\n",
+                                               i_scanned, i_passed);
 
        autorun_devices(part);
 }