diff options
-rw-r--r-- | drivers/md/dm-linear.c | 1 | ||||
-rw-r--r-- | drivers/md/dm-table.c | 19 | ||||
-rw-r--r-- | drivers/md/dm.c | 15 | ||||
-rw-r--r-- | drivers/md/dm.h | 1 | ||||
-rw-r--r-- | include/linux/device-mapper.h | 7 |
5 files changed, 33 insertions, 10 deletions
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c index 79fb53e51c70..bfa107f59d96 100644 --- a/drivers/md/dm-linear.c +++ b/drivers/md/dm-linear.c | |||
@@ -142,6 +142,7 @@ static struct target_type linear_target = { | |||
142 | .status = linear_status, | 142 | .status = linear_status, |
143 | .ioctl = linear_ioctl, | 143 | .ioctl = linear_ioctl, |
144 | .merge = linear_merge, | 144 | .merge = linear_merge, |
145 | .features = DM_TARGET_SUPPORTS_BARRIERS, | ||
145 | }; | 146 | }; |
146 | 147 | ||
147 | int __init dm_linear_init(void) | 148 | int __init dm_linear_init(void) |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 04e5fd742c2c..ebaaf72cd822 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -38,6 +38,8 @@ struct dm_table { | |||
38 | sector_t *highs; | 38 | sector_t *highs; |
39 | struct dm_target *targets; | 39 | struct dm_target *targets; |
40 | 40 | ||
41 | unsigned barriers_supported:1; | ||
42 | |||
41 | /* | 43 | /* |
42 | * Indicates the rw permissions for the new logical | 44 | * Indicates the rw permissions for the new logical |
43 | * device. This should be a combination of FMODE_READ | 45 | * device. This should be a combination of FMODE_READ |
@@ -227,6 +229,7 @@ int dm_table_create(struct dm_table **result, fmode_t mode, | |||
227 | 229 | ||
228 | INIT_LIST_HEAD(&t->devices); | 230 | INIT_LIST_HEAD(&t->devices); |
229 | atomic_set(&t->holders, 1); | 231 | atomic_set(&t->holders, 1); |
232 | t->barriers_supported = 1; | ||
230 | 233 | ||
231 | if (!num_targets) | 234 | if (!num_targets) |
232 | num_targets = KEYS_PER_NODE; | 235 | num_targets = KEYS_PER_NODE; |
@@ -728,6 +731,10 @@ int dm_table_add_target(struct dm_table *t, const char *type, | |||
728 | /* FIXME: the plan is to combine high here and then have | 731 | /* FIXME: the plan is to combine high here and then have |
729 | * the merge fn apply the target level restrictions. */ | 732 | * the merge fn apply the target level restrictions. */ |
730 | combine_restrictions_low(&t->limits, &tgt->limits); | 733 | combine_restrictions_low(&t->limits, &tgt->limits); |
734 | |||
735 | if (!(tgt->type->features & DM_TARGET_SUPPORTS_BARRIERS)) | ||
736 | t->barriers_supported = 0; | ||
737 | |||
731 | return 0; | 738 | return 0; |
732 | 739 | ||
733 | bad: | 740 | bad: |
@@ -772,6 +779,12 @@ int dm_table_complete(struct dm_table *t) | |||
772 | 779 | ||
773 | check_for_valid_limits(&t->limits); | 780 | check_for_valid_limits(&t->limits); |
774 | 781 | ||
782 | /* | ||
783 | * We only support barriers if there is exactly one underlying device. | ||
784 | */ | ||
785 | if (!list_is_singular(&t->devices)) | ||
786 | t->barriers_supported = 0; | ||
787 | |||
775 | /* how many indexes will the btree have ? */ | 788 | /* how many indexes will the btree have ? */ |
776 | leaf_nodes = dm_div_up(t->num_targets, KEYS_PER_NODE); | 789 | leaf_nodes = dm_div_up(t->num_targets, KEYS_PER_NODE); |
777 | t->depth = 1 + int_log(leaf_nodes, CHILDREN_PER_NODE); | 790 | t->depth = 1 + int_log(leaf_nodes, CHILDREN_PER_NODE); |
@@ -986,6 +999,12 @@ struct mapped_device *dm_table_get_md(struct dm_table *t) | |||
986 | return t->md; | 999 | return t->md; |
987 | } | 1000 | } |
988 | 1001 | ||
1002 | int dm_table_barrier_ok(struct dm_table *t) | ||
1003 | { | ||
1004 | return t->barriers_supported; | ||
1005 | } | ||
1006 | EXPORT_SYMBOL(dm_table_barrier_ok); | ||
1007 | |||
989 | EXPORT_SYMBOL(dm_vcalloc); | 1008 | EXPORT_SYMBOL(dm_vcalloc); |
990 | EXPORT_SYMBOL(dm_get_device); | 1009 | EXPORT_SYMBOL(dm_get_device); |
991 | EXPORT_SYMBOL(dm_put_device); | 1010 | EXPORT_SYMBOL(dm_put_device); |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 4882ce7e88a3..dd953b189f45 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -835,7 +835,11 @@ static int __split_bio(struct mapped_device *md, struct bio *bio) | |||
835 | ci.map = dm_get_table(md); | 835 | ci.map = dm_get_table(md); |
836 | if (unlikely(!ci.map)) | 836 | if (unlikely(!ci.map)) |
837 | return -EIO; | 837 | return -EIO; |
838 | 838 | if (unlikely(bio_barrier(bio) && !dm_table_barrier_ok(ci.map))) { | |
839 | dm_table_put(ci.map); | ||
840 | bio_endio(bio, -EOPNOTSUPP); | ||
841 | return 0; | ||
842 | } | ||
839 | ci.md = md; | 843 | ci.md = md; |
840 | ci.bio = bio; | 844 | ci.bio = bio; |
841 | ci.io = alloc_io(md); | 845 | ci.io = alloc_io(md); |
@@ -919,15 +923,6 @@ static int dm_request(struct request_queue *q, struct bio *bio) | |||
919 | struct mapped_device *md = q->queuedata; | 923 | struct mapped_device *md = q->queuedata; |
920 | int cpu; | 924 | int cpu; |
921 | 925 | ||
922 | /* | ||
923 | * There is no use in forwarding any barrier request since we can't | ||
924 | * guarantee it is (or can be) handled by the targets correctly. | ||
925 | */ | ||
926 | if (unlikely(bio_barrier(bio))) { | ||
927 | bio_endio(bio, -EOPNOTSUPP); | ||
928 | return 0; | ||
929 | } | ||
930 | |||
931 | down_read(&md->io_lock); | 926 | down_read(&md->io_lock); |
932 | 927 | ||
933 | cpu = part_stat_lock(); | 928 | cpu = part_stat_lock(); |
diff --git a/drivers/md/dm.h b/drivers/md/dm.h index 0ade60cdef42..5b5d08ba9e92 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h | |||
@@ -51,6 +51,7 @@ int dm_table_any_congested(struct dm_table *t, int bdi_bits); | |||
51 | * To check the return value from dm_table_find_target(). | 51 | * To check the return value from dm_table_find_target(). |
52 | */ | 52 | */ |
53 | #define dm_target_is_valid(t) ((t)->table) | 53 | #define dm_target_is_valid(t) ((t)->table) |
54 | int dm_table_barrier_ok(struct dm_table *t); | ||
54 | 55 | ||
55 | /*----------------------------------------------------------------- | 56 | /*----------------------------------------------------------------- |
56 | * A registry of target types. | 57 | * A registry of target types. |
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index c1ba76c7c0e5..8209e08969f9 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h | |||
@@ -112,7 +112,14 @@ void dm_put_device(struct dm_target *ti, struct dm_dev *d); | |||
112 | /* | 112 | /* |
113 | * Information about a target type | 113 | * Information about a target type |
114 | */ | 114 | */ |
115 | |||
116 | /* | ||
117 | * Target features | ||
118 | */ | ||
119 | #define DM_TARGET_SUPPORTS_BARRIERS 0x00000001 | ||
120 | |||
115 | struct target_type { | 121 | struct target_type { |
122 | uint64_t features; | ||
116 | const char *name; | 123 | const char *name; |
117 | struct module *module; | 124 | struct module *module; |
118 | unsigned version[3]; | 125 | unsigned version[3]; |