Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/shaggy...
[pandora-kernel.git] / drivers / md / dm-io.c
index 4809b20..4eb73d3 100644 (file)
@@ -32,16 +32,6 @@ struct io {
 static unsigned _num_ios;
 static mempool_t *_io_pool;
 
-static void *alloc_io(gfp_t gfp_mask, void *pool_data)
-{
-       return kmalloc(sizeof(struct io), gfp_mask);
-}
-
-static void free_io(void *element, void *pool_data)
-{
-       kfree(element);
-}
-
 static unsigned int pages_to_ios(unsigned int pages)
 {
        return 4 * pages;       /* too many ? */
@@ -65,7 +55,8 @@ static int resize_pool(unsigned int new_ios)
 
        } else {
                /* create new pool */
-               _io_pool = mempool_create(new_ios, alloc_io, free_io, NULL);
+               _io_pool = mempool_create_kmalloc_pool(new_ios,
+                                                      sizeof(struct io));
                if (!_io_pool)
                        return -ENOMEM;
 
@@ -101,12 +92,12 @@ void dm_io_put(unsigned int num_pages)
  *---------------------------------------------------------------*/
 static inline void bio_set_region(struct bio *bio, unsigned region)
 {
-       bio->bi_io_vec[bio->bi_max_vecs - 1].bv_len = region;
+       bio->bi_io_vec[bio->bi_max_vecs].bv_len = region;
 }
 
 static inline unsigned bio_get_region(struct bio *bio)
 {
-       return bio->bi_io_vec[bio->bi_max_vecs - 1].bv_len;
+       return bio->bi_io_vec[bio->bi_max_vecs].bv_len;
 }
 
 /*-----------------------------------------------------------------
@@ -145,6 +136,7 @@ static int endio(struct bio *bio, unsigned int done, int error)
                zero_fill_bio(bio);
 
        dec_count(io, bio_get_region(bio), error);
+       bio->bi_max_vecs++;
        bio_put(bio);
 
        return 0;
@@ -259,16 +251,18 @@ static void do_region(int rw, unsigned int region, struct io_region *where,
 
        while (remaining) {
                /*
-                * Allocate a suitably sized bio, we add an extra
-                * bvec for bio_get/set_region().
+                * Allocate a suitably sized-bio: we add an extra
+                * bvec for bio_get/set_region() and decrement bi_max_vecs
+                * to hide it from bio_add_page().
                 */
-               num_bvecs = (remaining / (PAGE_SIZE >> 9)) + 2;
+               num_bvecs = (remaining / (PAGE_SIZE >> SECTOR_SHIFT)) + 2;
                bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, _bios);
                bio->bi_sector = where->sector + (where->count - remaining);
                bio->bi_bdev = where->bdev;
                bio->bi_end_io = endio;
                bio->bi_private = io;
                bio->bi_destructor = dm_bio_destructor;
+               bio->bi_max_vecs--;
                bio_set_region(bio, region);
 
                /*
@@ -311,7 +305,7 @@ static void dispatch_io(int rw, unsigned int num_regions,
        }
 
        /*
-        * Drop the extra refence that we were holding to avoid
+        * Drop the extra reference that we were holding to avoid
         * the io being completed too early.
         */
        dec_count(io, 0, 0);