]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/md/dm.c
dm: add uevent to core
[linux-2.6-omap-h63xx.git] / drivers / md / dm.c
index 2120155929a6d0d860e4dffb78c2395cfcffdaa2..bb5c1eaca52b3688000f51bc841c69470fc7600a 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "dm.h"
 #include "dm-bio-list.h"
+#include "dm-uevent.h"
 
 #include <linux/init.h>
 #include <linux/module.h>
@@ -143,11 +144,19 @@ static int __init local_init(void)
                return -ENOMEM;
        }
 
+       r = dm_uevent_init();
+       if (r) {
+               kmem_cache_destroy(_tio_cache);
+               kmem_cache_destroy(_io_cache);
+               return r;
+       }
+
        _major = major;
        r = register_blkdev(_major, _name);
        if (r < 0) {
                kmem_cache_destroy(_tio_cache);
                kmem_cache_destroy(_io_cache);
+               dm_uevent_exit();
                return r;
        }
 
@@ -162,6 +171,7 @@ static void local_exit(void)
        kmem_cache_destroy(_tio_cache);
        kmem_cache_destroy(_io_cache);
        unregister_blkdev(_major, _name);
+       dm_uevent_exit();
 
        _major = 0;
 
@@ -484,23 +494,20 @@ static void dec_pending(struct dm_io *io, int error)
                        blk_add_trace_bio(io->md->queue, io->bio,
                                          BLK_TA_COMPLETE);
 
-                       bio_endio(io->bio, io->bio->bi_size, io->error);
+                       bio_endio(io->bio, io->error);
                }
 
                free_io(io->md, io);
        }
 }
 
-static int clone_endio(struct bio *bio, unsigned int done, int error)
+static void clone_endio(struct bio *bio, int error)
 {
        int r = 0;
        struct dm_target_io *tio = bio->bi_private;
        struct mapped_device *md = tio->io->md;
        dm_endio_fn endio = tio->ti->type->end_io;
 
-       if (bio->bi_size)
-               return 1;
-
        if (!bio_flagged(bio, BIO_UPTODATE) && !error)
                error = -EIO;
 
@@ -514,7 +521,7 @@ static int clone_endio(struct bio *bio, unsigned int done, int error)
                        error = r;
                else if (r == DM_ENDIO_INCOMPLETE)
                        /* The target will handle the io */
-                       return 1;
+                       return;
                else if (r) {
                        DMWARN("unimplemented target endio return value: %d", r);
                        BUG();
@@ -530,7 +537,6 @@ static int clone_endio(struct bio *bio, unsigned int done, int error)
 
        bio_put(bio);
        free_tio(md, tio);
-       return r;
 }
 
 static sector_t max_io_len(struct mapped_device *md,
@@ -755,15 +761,13 @@ static void __clone_and_map(struct clone_info *ci)
 /*
  * Split the bio into several clones.
  */
-static void __split_bio(struct mapped_device *md, struct bio *bio)
+static int __split_bio(struct mapped_device *md, struct bio *bio)
 {
        struct clone_info ci;
 
        ci.map = dm_get_table(md);
-       if (!ci.map) {
-               bio_io_error(bio, bio->bi_size);
-               return;
-       }
+       if (unlikely(!ci.map))
+               return -EIO;
 
        ci.md = md;
        ci.bio = bio;
@@ -783,6 +787,8 @@ static void __split_bio(struct mapped_device *md, struct bio *bio)
        /* drop the extra reference count */
        dec_pending(ci.io, 0);
        dm_table_put(ci.map);
+
+       return 0;
 }
 /*-----------------------------------------------------------------
  * CRUD END
@@ -794,7 +800,7 @@ static void __split_bio(struct mapped_device *md, struct bio *bio)
  */
 static int dm_request(struct request_queue *q, struct bio *bio)
 {
-       int r;
+       int r = -EIO;
        int rw = bio_data_dir(bio);
        struct mapped_device *md = q->queuedata;
 
@@ -803,7 +809,7 @@ static int dm_request(struct request_queue *q, struct bio *bio)
         * guarantee it is (or can be) handled by the targets correctly.
         */
        if (unlikely(bio_barrier(bio))) {
-               bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
+               bio_endio(bio, -EOPNOTSUPP);
                return 0;
        }
 
@@ -819,18 +825,11 @@ static int dm_request(struct request_queue *q, struct bio *bio)
        while (test_bit(DMF_BLOCK_IO, &md->flags)) {
                up_read(&md->io_lock);
 
-               if (bio_rw(bio) == READA) {
-                       bio_io_error(bio, bio->bi_size);
-                       return 0;
-               }
+               if (bio_rw(bio) != READA)
+                       r = queue_io(md, bio);
 
-               r = queue_io(md, bio);
-               if (r < 0) {
-                       bio_io_error(bio, bio->bi_size);
-                       return 0;
-
-               } else if (r == 0)
-                       return 0;       /* deferred successfully */
+               if (r <= 0)
+                       goto out_req;
 
                /*
                 * We're in a while loop, because someone could suspend
@@ -839,24 +838,14 @@ static int dm_request(struct request_queue *q, struct bio *bio)
                down_read(&md->io_lock);
        }
 
-       __split_bio(md, bio);
+       r = __split_bio(md, bio);
        up_read(&md->io_lock);
-       return 0;
-}
-
-static int dm_flush_all(struct request_queue *q, struct gendisk *disk,
-                       sector_t *error_sector)
-{
-       struct mapped_device *md = q->queuedata;
-       struct dm_table *map = dm_get_table(md);
-       int ret = -ENXIO;
 
-       if (map) {
-               ret = dm_table_flush_all(map);
-               dm_table_put(map);
-       }
+out_req:
+       if (r < 0)
+               bio_io_error(bio);
 
-       return ret;
+       return 0;
 }
 
 static void dm_unplug_all(struct request_queue *q)
@@ -1007,7 +996,6 @@ static struct mapped_device *alloc_dev(int minor)
        blk_queue_make_request(md->queue, dm_request);
        blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY);
        md->queue->unplug_fn = dm_unplug_all;
-       md->queue->issue_flush_fn = dm_flush_all;
 
        md->io_pool = mempool_create_slab_pool(MIN_IOS, _io_cache);
        if (!md->io_pool)
@@ -1064,12 +1052,14 @@ static struct mapped_device *alloc_dev(int minor)
        return NULL;
 }
 
+static void unlock_fs(struct mapped_device *md);
+
 static void free_dev(struct mapped_device *md)
 {
        int minor = md->disk->first_minor;
 
        if (md->suspended_bdev) {
-               thaw_bdev(md->suspended_bdev, NULL);
+               unlock_fs(md);
                bdput(md->suspended_bdev);
        }
        mempool_destroy(md->tio_pool);
@@ -1253,7 +1243,8 @@ static void __flush_deferred_io(struct mapped_device *md, struct bio *c)
        while (c) {
                n = c->bi_next;
                c->bi_next = NULL;
-               __split_bio(md, c);
+               if (__split_bio(md, c))
+                       bio_io_error(c);
                c = n;
        }
 }