From: Andi Kleen Implement barrier support for single device DM devices This patch implements barrier support in DM for the common case of dm linear just remapping a single underlying device. In this case we can safely pass the barrier through because there can be no reordering between devices. Signed-off-by: Andi Kleen --- drivers/md/dm-linear.c | 1 + drivers/md/dm-table.c | 26 +++++++++++++++++++++++++- drivers/md/dm.c | 14 ++++---------- drivers/md/dm.h | 2 ++ 4 files changed, 32 insertions(+), 11 deletions(-) Index: linux-2.6.27/drivers/md/dm-linear.c =================================================================== --- linux-2.6.27.orig/drivers/md/dm-linear.c 2008-10-23 23:44:15.000000000 +0100 +++ linux-2.6.27/drivers/md/dm-linear.c 2008-10-24 12:38:35.000000000 +0100 @@ -52,6 +52,7 @@ static int linear_ctr(struct dm_target * ti->error = "dm-linear: Device lookup failed"; goto bad; } + dm_table_support_barrier(ti->table); ti->private = lc; return 0; Index: linux-2.6.27/drivers/md/dm-table.c =================================================================== --- linux-2.6.27.orig/drivers/md/dm-table.c 2008-10-23 23:57:20.000000000 +0100 +++ linux-2.6.27/drivers/md/dm-table.c 2008-10-24 12:38:35.000000000 +0100 @@ -38,6 +38,9 @@ struct dm_table { sector_t *highs; struct dm_target *targets; + unsigned single_device : 1; + unsigned barrier_supported : 1; + /* * Indicates the rw permissions for the new logical * device. This should be a combination of FMODE_READ @@ -530,12 +533,21 @@ EXPORT_SYMBOL_GPL(dm_set_device_limits); int dm_get_device(struct dm_target *ti, const char *path, sector_t start, sector_t len, fmode_t mode, struct dm_dev **result) { - int r = __table_get_device(ti->table, ti, path, + struct dm_table *t = ti->table; + int r = __table_get_device(t, ti, path, start, len, mode, result); if (!r) dm_set_device_limits(ti, (*result)->bdev); + if (!r) { + /* Only got single device? */ + if (t->devices.next->next == &t->devices) + t->single_device = 1; + else + t->single_device = 0; + } + return r; } @@ -1024,6 +1036,16 @@ struct mapped_device *dm_table_get_md(st return t->md; } +int dm_table_barrier_ok(struct dm_table *t) +{ + return t->single_device && t->barrier_supported; +} + +void dm_table_support_barrier(struct dm_table *t) +{ + t->barrier_supported = 1; +} + EXPORT_SYMBOL(dm_vcalloc); EXPORT_SYMBOL(dm_get_device); EXPORT_SYMBOL(dm_put_device); @@ -1034,3 +1056,5 @@ EXPORT_SYMBOL(dm_table_get_md); EXPORT_SYMBOL(dm_table_put); EXPORT_SYMBOL(dm_table_get); EXPORT_SYMBOL(dm_table_unplug_all); +EXPORT_SYMBOL(dm_table_barrier_ok); +EXPORT_SYMBOL(dm_table_support_barrier); Index: linux-2.6.27/drivers/md/dm.c =================================================================== --- linux-2.6.27.orig/drivers/md/dm.c 2008-10-23 23:57:20.000000000 +0100 +++ linux-2.6.27/drivers/md/dm.c 2008-10-24 12:38:35.000000000 +0100 @@ -808,7 +808,10 @@ static int __split_bio(struct mapped_dev ci.map = dm_get_table(md); if (unlikely(!ci.map)) return -EIO; - + if (unlikely(bio_barrier(bio) && !dm_table_barrier_ok(ci.map))) { + bio_endio(bio, -EOPNOTSUPP); + return 0; + } ci.md = md; ci.bio = bio; ci.io = alloc_io(md); @@ -892,15 +895,6 @@ static int dm_request(struct request_que struct mapped_device *md = q->queuedata; int cpu; - /* - * There is no use in forwarding any barrier request since we can't - * guarantee it is (or can be) handled by the targets correctly. - */ - if (unlikely(bio_barrier(bio))) { - bio_endio(bio, -EOPNOTSUPP); - return 0; - } - down_read(&md->io_lock); cpu = part_stat_lock(); Index: linux-2.6.27/drivers/md/dm.h =================================================================== --- linux-2.6.27.orig/drivers/md/dm.h 2008-10-23 23:44:15.000000000 +0100 +++ linux-2.6.27/drivers/md/dm.h 2008-10-24 12:38:35.000000000 +0100 @@ -51,6 +51,8 @@ int dm_table_any_congested(struct dm_tab * To check the return value from dm_table_find_target(). */ #define dm_target_is_valid(t) ((t)->table) +int dm_table_barrier_ok(struct dm_table *t); +void dm_table_support_barrier(struct dm_table *t); /*----------------------------------------------------------------- * A registry of target types.