1 commit 6b2ba85752b8123d68ceb8770c94ebf4ba1dbb94
2 Author: S.Çağlar Onur <caglar@cs.princeton.edu>
3 Date: Fri Apr 2 18:33:58 2010 -0400
5 support_barriers_on_single_device_dm_devices.patch
7 diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
8 index 6449bcd..2d50fff 100644
9 --- a/drivers/md/dm-linear.c
10 +++ b/drivers/md/dm-linear.c
11 @@ -151,6 +151,7 @@ static struct target_type linear_target = {
12 .status = linear_status,
13 .ioctl = linear_ioctl,
14 .merge = linear_merge,
15 + .features = DM_TARGET_SUPPORTS_BARRIERS,
18 int __init dm_linear_init(void)
19 diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
20 index 61f4414..a27cce2 100644
21 --- a/drivers/md/dm-table.c
22 +++ b/drivers/md/dm-table.c
23 @@ -38,6 +38,8 @@ struct dm_table {
25 struct dm_target *targets;
27 + unsigned barriers_supported:1;
30 * Indicates the rw permissions for the new logical
31 * device. This should be a combination of FMODE_READ
32 @@ -227,6 +229,7 @@ int dm_table_create(struct dm_table **result, int mode,
34 INIT_LIST_HEAD(&t->devices);
35 atomic_set(&t->holders, 1);
36 + t->barriers_supported = 1;
39 num_targets = KEYS_PER_NODE;
40 @@ -723,6 +726,10 @@ int dm_table_add_target(struct dm_table *t, const char *type,
41 /* FIXME: the plan is to combine high here and then have
42 * the merge fn apply the target level restrictions. */
43 combine_restrictions_low(&t->limits, &tgt->limits);
45 + if (!(tgt->type->features & DM_TARGET_SUPPORTS_BARRIERS))
46 + t->barriers_supported = 0;
51 @@ -767,6 +774,12 @@ int dm_table_complete(struct dm_table *t)
53 check_for_valid_limits(&t->limits);
56 + * We only support barriers if there is exactly one underlying device.
58 + if (!list_is_singular(&t->devices))
59 + t->barriers_supported = 0;
61 /* how many indexes will the btree have ? */
62 leaf_nodes = dm_div_up(t->num_targets, KEYS_PER_NODE);
63 t->depth = 1 + int_log(leaf_nodes, CHILDREN_PER_NODE);
64 @@ -968,6 +981,11 @@ struct mapped_device *dm_table_get_md(struct dm_table *t)
68 +int dm_table_barrier_ok(struct dm_table *t)
70 + return t->barriers_supported;
72 +EXPORT_SYMBOL(dm_table_barrier_ok);
73 EXPORT_SYMBOL(dm_vcalloc);
74 EXPORT_SYMBOL(dm_get_device);
75 EXPORT_SYMBOL(dm_put_device);
76 diff --git a/drivers/md/dm.c b/drivers/md/dm.c
77 index 191f56d..8b11f14 100644
80 @@ -816,6 +816,12 @@ static int __split_bio(struct mapped_device *md, struct bio *bio)
81 if (unlikely(!ci.map))
84 + if (unlikely(bio_barrier(bio) && !dm_table_barrier_ok(ci.map))) {
85 + dm_table_put(ci.map);
86 + bio_endio(bio, -EOPNOTSUPP);
93 @@ -898,15 +904,6 @@ static int dm_request(struct request_queue *q, struct bio *bio)
94 int rw = bio_data_dir(bio);
95 struct mapped_device *md = q->queuedata;
98 - * There is no use in forwarding any barrier request since we can't
99 - * guarantee it is (or can be) handled by the targets correctly.
101 - if (unlikely(bio_barrier(bio))) {
102 - bio_endio(bio, -EOPNOTSUPP);
106 down_read(&md->io_lock);
108 disk_stat_inc(dm_disk(md), ios[rw]);
109 diff --git a/drivers/md/dm.h b/drivers/md/dm.h
110 index a72d6d7..cd82816 100644
111 --- a/drivers/md/dm.h
112 +++ b/drivers/md/dm.h
113 @@ -50,6 +50,7 @@ void dm_table_postsuspend_targets(struct dm_table *t);
114 int dm_table_resume_targets(struct dm_table *t);
115 int dm_table_any_congested(struct dm_table *t, int bdi_bits);
116 void dm_table_unplug_all(struct dm_table *t);
117 +int dm_table_barrier_ok(struct dm_table *t);
120 * To check the return value from dm_table_find_target().
121 diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
122 index a90222e..3854a3e 100644
123 --- a/include/linux/device-mapper.h
124 +++ b/include/linux/device-mapper.h
125 @@ -94,9 +94,15 @@ int dm_get_device(struct dm_target *ti, const char *path, sector_t start,
126 void dm_put_device(struct dm_target *ti, struct dm_dev *d);
131 +#define DM_TARGET_SUPPORTS_BARRIERS 0x00000001
134 * Information about a target type
139 struct module *module;