]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/md/dm.c
V4L/DVB (6926): tda18271: consolidate table lookup functions
[linux-2.6-omap-h63xx.git] / drivers / md / dm.c
index 07cbbb8eb3e0d5d67f5c7bed7ea399f6636e5954..f2d24eb3208c97e79bdf33b9d8c396f855f55566 100644 (file)
@@ -672,13 +672,19 @@ static struct bio *clone_bio(struct bio *bio, sector_t sector,
        return clone;
 }
 
-static void __clone_and_map(struct clone_info *ci)
+static int __clone_and_map(struct clone_info *ci)
 {
        struct bio *clone, *bio = ci->bio;
-       struct dm_target *ti = dm_table_find_target(ci->map, ci->sector);
-       sector_t len = 0, max = max_io_len(ci->md, ci->sector, ti);
+       struct dm_target *ti;
+       sector_t len = 0, max;
        struct dm_target_io *tio;
 
+       ti = dm_table_find_target(ci->map, ci->sector);
+       if (!dm_target_is_valid(ti))
+               return -EIO;
+
+       max = max_io_len(ci->md, ci->sector, ti);
+
        /*
         * Allocate a target io object.
         */
@@ -736,6 +742,9 @@ static void __clone_and_map(struct clone_info *ci)
                do {
                        if (offset) {
                                ti = dm_table_find_target(ci->map, ci->sector);
+                               if (!dm_target_is_valid(ti))
+                                       return -EIO;
+
                                max = max_io_len(ci->md, ci->sector, ti);
 
                                tio = alloc_tio(ci->md);
@@ -759,6 +768,8 @@ static void __clone_and_map(struct clone_info *ci)
 
                ci->idx++;
        }
+
+       return 0;
 }
 
 /*
@@ -767,6 +778,7 @@ static void __clone_and_map(struct clone_info *ci)
 static int __split_bio(struct mapped_device *md, struct bio *bio)
 {
        struct clone_info ci;
+       int error = 0;
 
        ci.map = dm_get_table(md);
        if (unlikely(!ci.map))
@@ -784,11 +796,11 @@ static int __split_bio(struct mapped_device *md, struct bio *bio)
        ci.idx = bio->bi_idx;
 
        start_io_acct(ci.io);
-       while (ci.sector_count)
-               __clone_and_map(&ci);
+       while (ci.sector_count && !error)
+               error = __clone_and_map(&ci);
 
        /* drop the extra reference count */
-       dec_pending(ci.io, 0);
+       dec_pending(ci.io, error);
        dm_table_put(ci.map);
 
        return 0;
@@ -1097,7 +1109,7 @@ static void event_callback(void *context)
        list_splice_init(&md->uevent_list, &uevents);
        spin_unlock_irqrestore(&md->uevent_lock, flags);
 
-       dm_send_uevents(&uevents, &md->disk->kobj);
+       dm_send_uevents(&uevents, &md->disk->dev.kobj);
 
        atomic_inc(&md->event_nr);
        wake_up(&md->eventq);
@@ -1502,7 +1514,7 @@ int dm_resume(struct mapped_device *md)
 
        dm_table_unplug_all(map);
 
-       kobject_uevent(&md->disk->kobj, KOBJ_CHANGE);
+       dm_kobject_uevent(md);
 
        r = 0;
 
@@ -1516,6 +1528,11 @@ out:
 /*-----------------------------------------------------------------
  * Event notification.
  *---------------------------------------------------------------*/
+void dm_kobject_uevent(struct mapped_device *md)
+{
+       kobject_uevent(&md->disk->dev.kobj, KOBJ_CHANGE);
+}
+
 uint32_t dm_next_uevent_seq(struct mapped_device *md)
 {
        return atomic_add_return(1, &md->uevent_seq);