From: NeilBrown <neilb@suse.de>

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.

Establish the raid_is_congested() callback for dm-raid.

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>

---
drivers/md/dm-raid.c          |   18 ++++++++++++++++--
 drivers/md/dm-raid.c |   18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

Index: linux-2.6.37/drivers/md/dm-raid.c
===================================================================
--- linux-2.6.37.orig/drivers/md/dm-raid.c
+++ linux-2.6.37/drivers/md/dm-raid.c
@@ -58,6 +58,7 @@ struct raid_set {
 
 	struct mddev_s md;
 	struct raid_type *raid_type;
+	struct dm_target_callbacks callbacks;
 
 	struct raid_dev dev[0];
 };
@@ -363,6 +364,13 @@ static void do_table_event(struct work_s
 	dm_table_event(rs->ti->table);
 }
 
+static int raid_is_congested(struct dm_target_callbacks *cb, int bits)
+{
+	struct raid_set *rs = container_of(cb, struct raid_set,
+					   callbacks);
+	return md_raid5_congested(&rs->md, bits);
+}
+
 /*
  * Construct a RAID4/5/6 mapping:
  * Args:
@@ -443,8 +451,13 @@ static int raid_ctr(struct dm_target *ti
 	rs->md.in_sync = 0; /* Assume already marked dirty */
 	mutex_unlock(&rs->md.reconfig_mutex);
 
-	if (!errnum)
-		return 0;
+	if (errnum)
+		goto err;
+
+	rs->callbacks.congested_fn = raid_is_congested;
+	dm_table_add_target_callbacks(ti->table, &rs->callbacks);
+
+	return 0;
 
 err:
 	if (rs)
@@ -457,6 +470,7 @@ static void raid_dtr(struct dm_target *t
 {
 	struct raid_set *rs = ti->private;
 
+	list_del_init(&rs->callbacks.list);
 	md_stop(&rs->md);
 	context_free(rs);
 }
