From 41c1852f59af2b30ccd9bd4eeb651f4fe116fe86 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 7 Oct 2010 14:51:48 +0200 Subject: [PATCH] Update to latest Signed-off-by: Jens Axboe --- Makefile | 4 ++-- binject.h | 2 ++ kcompat.h | 6 ++++++ main.c | 55 ++++++++++++++++++++++++++++++++++++------------------- 4 files changed, 46 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index 4bcef47..f99d012 100644 --- 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 diff --git a/binject.h b/binject.h index ced7460..b3316ca 100644 --- 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 }; diff --git a/kcompat.h b/kcompat.h index b572156..366a4f2 100644 --- 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 e0da621..5831cd5 100644 --- 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; -- 2.25.1