Commit ab4c1424882be9cd70b89abf2b484add355712fa

Authored by Andi Kleen
Committed by Alasdair G Kergon
1 parent 7d76345da6

dm: support barriers on simple devices

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.

 NB. Any DM device might cease to support barriers if it gets
     reconfigured so code must continue to allow for a possible
     -EOPNOTSUPP on every barrier bio submitted.  - agk

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>

Showing 5 changed files with 33 additions and 10 deletions Side-by-side Diff

drivers/md/dm-linear.c
... ... @@ -142,6 +142,7 @@
142 142 .status = linear_status,
143 143 .ioctl = linear_ioctl,
144 144 .merge = linear_merge,
  145 + .features = DM_TARGET_SUPPORTS_BARRIERS,
145 146 };
146 147  
147 148 int __init dm_linear_init(void)
drivers/md/dm-table.c
... ... @@ -38,6 +38,8 @@
38 38 sector_t *highs;
39 39 struct dm_target *targets;
40 40  
  41 + unsigned barriers_supported:1;
  42 +
41 43 /*
42 44 * Indicates the rw permissions for the new logical
43 45 * device. This should be a combination of FMODE_READ
... ... @@ -227,6 +229,7 @@
227 229  
228 230 INIT_LIST_HEAD(&t->devices);
229 231 atomic_set(&t->holders, 1);
  232 + t->barriers_supported = 1;
230 233  
231 234 if (!num_targets)
232 235 num_targets = KEYS_PER_NODE;
... ... @@ -728,6 +731,10 @@
728 731 /* FIXME: the plan is to combine high here and then have
729 732 * the merge fn apply the target level restrictions. */
730 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 738 return 0;
732 739  
733 740 bad:
... ... @@ -772,6 +779,12 @@
772 779  
773 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 788 /* how many indexes will the btree have ? */
776 789 leaf_nodes = dm_div_up(t->num_targets, KEYS_PER_NODE);
777 790 t->depth = 1 + int_log(leaf_nodes, CHILDREN_PER_NODE);
... ... @@ -985,6 +998,12 @@
985 998  
986 999 return t->md;
987 1000 }
  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);
988 1007  
989 1008 EXPORT_SYMBOL(dm_vcalloc);
990 1009 EXPORT_SYMBOL(dm_get_device);
... ... @@ -835,7 +835,11 @@
835 835 ci.map = dm_get_table(md);
836 836 if (unlikely(!ci.map))
837 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 843 ci.md = md;
840 844 ci.bio = bio;
841 845 ci.io = alloc_io(md);
... ... @@ -918,15 +922,6 @@
918 922 int rw = bio_data_dir(bio);
919 923 struct mapped_device *md = q->queuedata;
920 924 int cpu;
921   -
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 925  
931 926 down_read(&md->io_lock);
932 927  
... ... @@ -51,6 +51,7 @@
51 51 * To check the return value from dm_table_find_target().
52 52 */
53 53 #define dm_target_is_valid(t) ((t)->table)
  54 +int dm_table_barrier_ok(struct dm_table *t);
54 55  
55 56 /*-----------------------------------------------------------------
56 57 * A registry of target types.
include/linux/device-mapper.h
... ... @@ -112,7 +112,14 @@
112 112 /*
113 113 * Information about a target type
114 114 */
  115 +
  116 +/*
  117 + * Target features
  118 + */
  119 +#define DM_TARGET_SUPPORTS_BARRIERS 0x00000001
  120 +
115 121 struct target_type {
  122 + uint64_t features;
116 123 const char *name;
117 124 struct module *module;
118 125 unsigned version[3];