aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-01-13 15:00:01 -0500
committerAlasdair G Kergon <agk@redhat.com>2011-01-13 15:00:01 -0500
commit9d357b0787bb3c91835d5e658c3bda178f9ca419 (patch)
tree48f2c3adc8ae06918ef0523f073291990407fa28 /drivers
parent4e2d19e46b507018c6ed15f6c081d8f887ae229c (diff)
dm: introduce target callbacks and congestion callback
DM currently implements congestion checking by checking on congestion in each component device. For raid456 we need to also check if the stripe cache is congested. Add per-target congestion checker callback support. Extending the target_callbacks structure with additional callback functions allows for establishing multiple callbacks per-target (a callback is also needed for unplug). Cc: linux-raid@vger.kernel.org Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: Jonathan Brassow <jbrassow@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/md/dm-table.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 985c20a4f30e..7e2ec3c05550 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -71,6 +71,8 @@ struct dm_table {
71 void *event_context; 71 void *event_context;
72 72
73 struct dm_md_mempools *mempools; 73 struct dm_md_mempools *mempools;
74
75 struct list_head target_callbacks;
74}; 76};
75 77
76/* 78/*
@@ -204,6 +206,7 @@ int dm_table_create(struct dm_table **result, fmode_t mode,
204 return -ENOMEM; 206 return -ENOMEM;
205 207
206 INIT_LIST_HEAD(&t->devices); 208 INIT_LIST_HEAD(&t->devices);
209 INIT_LIST_HEAD(&t->target_callbacks);
207 atomic_set(&t->holders, 0); 210 atomic_set(&t->holders, 0);
208 t->discards_supported = 1; 211 t->discards_supported = 1;
209 212
@@ -1225,10 +1228,17 @@ int dm_table_resume_targets(struct dm_table *t)
1225 return 0; 1228 return 0;
1226} 1229}
1227 1230
1231void dm_table_add_target_callbacks(struct dm_table *t, struct dm_target_callbacks *cb)
1232{
1233 list_add(&cb->list, &t->target_callbacks);
1234}
1235EXPORT_SYMBOL_GPL(dm_table_add_target_callbacks);
1236
1228int dm_table_any_congested(struct dm_table *t, int bdi_bits) 1237int dm_table_any_congested(struct dm_table *t, int bdi_bits)
1229{ 1238{
1230 struct dm_dev_internal *dd; 1239 struct dm_dev_internal *dd;
1231 struct list_head *devices = dm_table_get_devices(t); 1240 struct list_head *devices = dm_table_get_devices(t);
1241 struct dm_target_callbacks *cb;
1232 int r = 0; 1242 int r = 0;
1233 1243
1234 list_for_each_entry(dd, devices, list) { 1244 list_for_each_entry(dd, devices, list) {
@@ -1243,6 +1253,10 @@ int dm_table_any_congested(struct dm_table *t, int bdi_bits)
1243 bdevname(dd->dm_dev.bdev, b)); 1253 bdevname(dd->dm_dev.bdev, b));
1244 } 1254 }
1245 1255
1256 list_for_each_entry(cb, &t->target_callbacks, list)
1257 if (cb->congested_fn)
1258 r |= cb->congested_fn(cb, bdi_bits);
1259
1246 return r; 1260 return r;
1247} 1261}
1248 1262