Update to latest
authorJens Axboe <jaxboe@fusionio.com>
Thu, 7 Oct 2010 12:51:48 +0000 (14:51 +0200)
committerJens Axboe <jaxboe@fusionio.com>
Thu, 7 Oct 2010 12:51:48 +0000 (14:51 +0200)
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Makefile
binject.h
kcompat.h
main.c

index 4bcef47d80b4905e794a216b349e74f9a3f33e13..f99d012026c839c2ec0adbac259f0b173511ba20 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,10 +2,10 @@ obj-m         := binject.o
 binject-objs   := kcompat.o main.o
 
 all:
-       @make -C /lib/modules/`uname -r`/build M=`pwd` modules
+       make -C /lib/modules/`uname -r`/build M=`pwd` modules
 
 el5:
-       @make -C /mnt/kernel/rhat/2.6.18/linux-2.6.18 M=`pwd` modules
+       KBUILD_NOPEDANTIC=1 make -C /mnt/kernel/rhat/2.6.18/linux-2.6.18 M=`pwd` modules
 
 clean:
        make -C /lib/modules/`uname -r`/build M=`pwd` clean
index ced74604c6aa6f70e83b3625a838658606ecb6ff..b3316caec131eb83599f74f5a6c0f58de9731072 100644 (file)
--- a/binject.h
+++ b/binject.h
@@ -29,6 +29,8 @@ enum {
        B_TYPE_DISCARD,
        B_TYPE_READVOID,
        B_TYPE_WRITEZERO,
+       B_TYPE_READBARRIER,
+       B_TYPE_WRITEBARRIER,
        B_TYPE_NR
 };
 
index b5721561ff3366d1706d25778b715a45c07b56e2..366a4f2403cdbfb65e81191bd76d39af87db1ef2 100644 (file)
--- a/kcompat.h
+++ b/kcompat.h
@@ -61,6 +61,7 @@ static inline struct kmem_cache *binject_create_slab(const char *name,
 }
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
+#define B_REQ_WRITE                    REQ_WRITE
 #define        B_REQ_SYNC                      REQ_SYNC
 #define B_REQ_UNPLUG                   REQ_UNPLUG
 #define B_REQ_NOIDLE                   REQ_NOIDLE
@@ -70,7 +71,10 @@ static inline struct kmem_cache *binject_create_slab(const char *name,
 #define B_REQ_FAILFAST_DEV             REQ_FAILFAST_DEV
 #define B_REQ_FAILFAST_TRANSPORT       REQ_FAILFAST_TRANSPORT
 #define B_REQ_FAILFAST_DRIVER          REQ_FAILFAST_DRIVER
+#define B_REQ_DISCARD                  REQ_DISCARD
+#define B_REQ_FLUSH                    REQ_FLUSH
 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
+#define B_REQ_WRITE                    (1 << BIO_RW)
 #define        B_REQ_SYNC                      (1 << BIO_RW_SYNC)
 #define B_REQ_UNPLUG                   0
 #define B_REQ_NOIDLE                   0
@@ -80,6 +84,8 @@ static inline struct kmem_cache *binject_create_slab(const char *name,
 #define B_REQ_FAILFAST_DEV             (1 << BIO_RW_FAILFAST)
 #define B_REQ_FAILFAST_TRANSPORT       (1 << BIO_RW_FAILFAST)
 #define B_REQ_FAILFAST_DRIVER          (1 << BIO_RW_FAILFAST)
+#define B_REQ_DISCARD                  0
+#define B_REQ_FLUSH                    0
 #else
 #error The kernel is too old
 #endif
diff --git a/main.c b/main.c
index e0da62131e9ca51e151cc1a3aa32640c27c43225..5831cd55621959df8a69d26395ecd597e94c147c 100644 (file)
--- a/main.c
+++ b/main.c
@@ -68,6 +68,7 @@ struct uc_map {
        unsigned int data_transfer : 1;
        unsigned int todevice : 1;
        unsigned int map_zero : 1;
+       unsigned long rw_flags;
 };
 
 static const struct uc_map uc_map[B_TYPE_NR] = {
@@ -82,12 +83,14 @@ static const struct uc_map uc_map[B_TYPE_NR] = {
                .data_transfer  = 1,
                .todevice       = 1,
                .map_zero       = 0,
+               .rw_flags       = B_REQ_WRITE,
        },
        {
                .type           = B_TYPE_DISCARD,
                .data_transfer  = 0,
                .todevice       = 0,
                .map_zero       = 0,
+               .rw_flags       = B_REQ_DISCARD | B_REQ_WRITE,
        },
        {
                .type           = B_TYPE_READVOID,
@@ -100,6 +103,21 @@ static const struct uc_map uc_map[B_TYPE_NR] = {
                .data_transfer  = 1,
                .todevice       = 1,
                .map_zero       = 1,
+               .rw_flags       = B_REQ_WRITE,
+       },
+       {
+               .type           = B_TYPE_READBARRIER,
+               .data_transfer  = 1,
+               .todevice       = 0,
+               .map_zero       = 0,
+               .rw_flags       = B_REQ_HARDBARRIER,
+       },
+       {
+               .type           = B_TYPE_WRITEBARRIER,
+               .data_transfer  = 1,
+               .todevice       = 1,
+               .map_zero       = 0,
+               .rw_flags       = B_REQ_HARDBARRIER | B_REQ_FLUSH | B_REQ_WRITE,
        }
 };
 
@@ -281,13 +299,15 @@ static void bio_cmd_endio(struct bio *bio, int err)
 }
 #endif
 
+#define len_to_pages(len)      ((len + PAGE_SIZE - 1) / PAGE_SIZE)
+
 static int zero_map_bio(struct request_queue *q, struct bio *bio,
                        const struct uc_map *ucm, unsigned int len)
 {
        unsigned int i, nr_pages, this_len, ret, err;
        struct page *page;
 
-       nr_pages = len / PAGE_SIZE;
+       nr_pages = len_to_pages(len);
        for (i = 0; i < nr_pages; i++) {
                if (ucm->todevice)
                        page = ZERO_PAGE(0);
@@ -303,8 +323,8 @@ static int zero_map_bio(struct request_queue *q, struct bio *bio,
                if (this_len > len)
                        this_len = len;
 
-               ret = bio_add_pc_page(q, bio, page, len, 0);
-               if (ret < len) {
+               ret = bio_add_pc_page(q, bio, page, this_len, 0);
+               if (ret < this_len) {
                        err = -E2BIG;
                        goto oom;
                }
@@ -341,11 +361,9 @@ static struct bio *map_uc_to_bio(struct b_dev *bd, struct b_user_cmd *uc)
                bio = binject_map_bio(q, bd->bdev, uc->buf, uc->len,
                                        !ucm->todevice, GFP_KERNEL);
        } else {
-               bio = bio_alloc(GFP_KERNEL, uc->len / PAGE_SIZE);
+               bio = bio_alloc(GFP_KERNEL, len_to_pages(uc->len));
                if (bio) {
                        bio->bi_bdev = bd->bdev;
-                       if (ucm->todevice)
-                               binject_mark_bio_write(bio);
                        if (ucm->map_zero && uc->len) {
                                int err;
 
@@ -364,6 +382,7 @@ static struct bio *map_uc_to_bio(struct b_dev *bd, struct b_user_cmd *uc)
        else if (!IS_ERR(bio)) {
                map_uc_to_bio_flags(bio, uc);
                bio->bi_sector = uc->offset / binject_get_bs(q);
+               bio->bi_rw |= ucm->rw_flags;
        }
 
        return bio;
@@ -427,13 +446,12 @@ static struct b_dev *b_dev_lookup(int minor)
        struct b_dev *bd;
 
        rcu_read_lock();
+
        bd = idr_find(&b_minor_idr, minor);
-       if (bd) {
-               if (!atomic_inc_not_zero(&bd->ref))
-                       bd = NULL;
-       }
-       rcu_read_unlock();
+       if (bd && !atomic_inc_not_zero(&bd->ref))
+               bd = NULL;
 
+       rcu_read_unlock();
        return bd;
 }
 
@@ -453,6 +471,7 @@ static ssize_t b_dev_write(struct file *file, const char __user *buf,
                           size_t count, loff_t *ppos)
 {
        struct b_dev *bd = file->private_data;
+       struct b_cmd *bc = NULL;
        unsigned int total;
        ssize_t done = 0;
        int err = 0;
@@ -462,11 +481,10 @@ static ssize_t b_dev_write(struct file *file, const char __user *buf,
 
        total = count / sizeof(struct b_user_cmd);
        while (total) {
-               struct b_cmd *bc;
-
                bc = get_free_command(bd);
                if (IS_ERR(bc)) {
                        err = PTR_ERR(bc);
+                       bc = NULL;
                        break;
                }
 
@@ -476,22 +494,21 @@ static ssize_t b_dev_write(struct file *file, const char __user *buf,
                }
 
                err = b_dev_validate_command(&bc->cmd);
-               if (err) {
-                       b_dev_free_command(bd, bc);
+               if (err)
                        break;
-               }
 
                err = b_dev_add_command(bd, bc);
-               if (err) {
-                       b_dev_free_command(bd, bc);
+               if (err)
                        break;
-               }
 
                done += sizeof(struct b_user_cmd);
                buf += sizeof(struct b_user_cmd);
                total--;
        }
 
+       if (bc)
+               b_dev_free_command(bd, bc);
+
        *ppos = done;
        if (!done)
                done = err;