[ARM] 3642/1: S3C24XX: Add machine SMDK2413
[powerpc.git] / drivers / md / dm-mpath.c
index 785806b..1816f30 100644 (file)
@@ -179,8 +179,7 @@ static struct multipath *alloc_multipath(void)
                m->queue_io = 1;
                INIT_WORK(&m->process_queued_ios, process_queued_ios, m);
                INIT_WORK(&m->trigger_event, trigger_event, m);
-               m->mpio_pool = mempool_create(MIN_IOS, mempool_alloc_slab,
-                                             mempool_free_slab, _mpio_cache);
+               m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache);
                if (!m->mpio_pool) {
                        kfree(m);
                        return NULL;
@@ -329,13 +328,17 @@ static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio,
 /*
  * If we run out of usable paths, should we queue I/O or error it?
  */
-static int queue_if_no_path(struct multipath *m, unsigned queue_if_no_path)
+static int queue_if_no_path(struct multipath *m, unsigned queue_if_no_path,
+                           unsigned save_old_value)
 {
        unsigned long flags;
 
        spin_lock_irqsave(&m->lock, flags);
 
-       m->saved_queue_if_no_path = m->queue_if_no_path;
+       if (save_old_value)
+               m->saved_queue_if_no_path = m->queue_if_no_path;
+       else
+               m->saved_queue_if_no_path = queue_if_no_path;
        m->queue_if_no_path = queue_if_no_path;
        if (!m->queue_if_no_path && m->queue_size)
                queue_work(kmultipathd, &m->process_queued_ios);
@@ -677,7 +680,7 @@ static int parse_features(struct arg_set *as, struct multipath *m,
                return 0;
 
        if (!strnicmp(shift(as), MESG_STR("queue_if_no_path")))
-               return queue_if_no_path(m, 1);
+               return queue_if_no_path(m, 1, 0);
        else {
                ti->error = "Unrecognised multipath feature request";
                return -EINVAL;
@@ -996,6 +999,7 @@ static int do_end_io(struct multipath *m, struct bio *bio,
 {
        struct hw_handler *hwh = &m->hw_handler;
        unsigned err_flags = MP_FAIL_PATH;      /* Default behavior */
+       unsigned long flags;
 
        if (!error)
                return 0;       /* I/O complete */
@@ -1006,17 +1010,17 @@ static int do_end_io(struct multipath *m, struct bio *bio,
        if (error == -EOPNOTSUPP)
                return error;
 
-       spin_lock(&m->lock);
+       spin_lock_irqsave(&m->lock, flags);
        if (!m->nr_valid_paths) {
                if (!m->queue_if_no_path) {
-                       spin_unlock(&m->lock);
+                       spin_unlock_irqrestore(&m->lock, flags);
                        return -EIO;
                } else {
-                       spin_unlock(&m->lock);
+                       spin_unlock_irqrestore(&m->lock, flags);
                        goto requeue;
                }
        }
-       spin_unlock(&m->lock);
+       spin_unlock_irqrestore(&m->lock, flags);
 
        if (hwh->type && hwh->type->error)
                err_flags = hwh->type->error(hwh, bio);
@@ -1036,12 +1040,12 @@ static int do_end_io(struct multipath *m, struct bio *bio,
        dm_bio_restore(&mpio->details, bio);
 
        /* queue for the daemon to resubmit or fail */
-       spin_lock(&m->lock);
+       spin_lock_irqsave(&m->lock, flags);
        bio_list_add(&m->queued_ios, bio);
        m->queue_size++;
        if (!m->queue_io)
                queue_work(kmultipathd, &m->process_queued_ios);
-       spin_unlock(&m->lock);
+       spin_unlock_irqrestore(&m->lock, flags);
 
        return 1;       /* io not complete */
 }
@@ -1077,7 +1081,7 @@ static void multipath_presuspend(struct dm_target *ti)
 {
        struct multipath *m = (struct multipath *) ti->private;
 
-       queue_if_no_path(m, 0);
+       queue_if_no_path(m, 0, 1);
 }
 
 /*
@@ -1222,9 +1226,9 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
 
        if (argc == 1) {
                if (!strnicmp(argv[0], MESG_STR("queue_if_no_path")))
-                       return queue_if_no_path(m, 1);
+                       return queue_if_no_path(m, 1, 0);
                else if (!strnicmp(argv[0], MESG_STR("fail_if_no_path")))
-                       return queue_if_no_path(m, 0);
+                       return queue_if_no_path(m, 0, 0);
        }
 
        if (argc != 2)