Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 697

kernel-2.6.18-238.el5.src.rpm

From: Heinz Mauelshagen <heinzm@redhat.com>
Date: Fri, 29 May 2009 13:37:40 +0200
Subject: [dm] raid45 target: kernel oops in constructor
Message-id: 1243597060.22836.57.camel@o
O-Subject: [RHEL 5.4 PATCH] dm: raid45 target: kernel oops in constructor
Bugzilla: 503070
RH-Acked-by: Jonathan Brassow <jbrassow@redhat.com>

RHEL5.4 device mapper: raid45 target

The RAID target oopses in el5 beta kernels on mapping table loads,
because due to API differences between mainline based code and RHEL5,
wrong dm-memcache arguments are being calculated and passed into
dm_mem_cache_client_create(); dm_mem_cache_{grow,shrink}() arguments are
bogus as well.

Additionally, this patch fixes a wrong region_hash argument in the
rh_recovery_end() call for the same reason and a comment typo.

Resolves: bz#503070

Please ACK.

Heinz

----
 drivers/md/{dm-raid45.c.orig => dm-raid45.c} |   33 +++++++++++------------
 1 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/drivers/md/dm-raid45.c b/drivers/md/dm-raid45.c
index 0d2ac0e..bf74af8 100644
--- a/drivers/md/dm-raid45.c
+++ b/drivers/md/dm-raid45.c
@@ -1341,7 +1341,6 @@ static void stripe_init(struct stripe_cache *sc, struct stripe *stripe)
 
 	stripe->sc = sc;
 
-
 	i = ARRAY_SIZE(stripe->lists);
 	while (i--)
 		INIT_LIST_HEAD(stripe->lists + i);
@@ -1409,13 +1408,13 @@ static struct stripe *stripe_alloc(struct stripe_cache *sc,
 	if (stripe) {
 		/* Grow the dm-mem-cache by one object. */
 		if (grow == SC_GROW) {
-			r = dm_mem_cache_grow(mc, 1);
+			r = dm_mem_cache_grow(mc, pages_per_chunk);
 			if (r)
 				goto err_free;
 		}
 
 		stripe->obj = dm_mem_cache_alloc(mc, pages_per_chunk);
-		if (!stripe->obj)
+		if (IS_ERR(stripe->obj))
 			goto err_shrink;
 
 		stripe_init(sc, stripe);
@@ -1425,7 +1424,7 @@ static struct stripe *stripe_alloc(struct stripe_cache *sc,
 
 err_shrink:
 	if (grow == SC_GROW)
-		dm_mem_cache_shrink(mc, 1);
+		dm_mem_cache_shrink(mc, pages_per_chunk);
 err_free:
 	kmem_cache_free(sc->kc.cache, stripe);
 	return NULL;
@@ -1438,7 +1437,7 @@ err_free:
 static void stripe_free(struct stripe *stripe, struct dm_mem_cache_client *mc)
 {
 	dm_mem_cache_free(mc, stripe->obj);
-	dm_mem_cache_shrink(mc, 1);
+	dm_mem_cache_shrink(mc, chunk_pages(stripe->io.size));
 	kmem_cache_free(stripe->sc->kc.cache, stripe);
 }
 
@@ -1569,39 +1568,39 @@ static int sc_init(struct raid_set *rs, unsigned stripes)
 
 	/* Create memory cache client context for RAID stripe cache. */
 	sc->mem_cache_client =
-		dm_mem_cache_client_create(stripes, rs->set.raid_devs,
-					   chunk_pages(rs->set.io_size));
+		dm_mem_cache_client_create(stripes *
+					   stripe_pages(rs, rs->set.io_size),
+					   stripes, rs->set.raid_devs);
 	if (IS_ERR(sc->mem_cache_client))
 		return PTR_ERR(sc->mem_cache_client);
 
 	/* Create memory cache client context for RAID recovery stripe(s). */
 	rstripes = rec->recovery_stripes;
 	rec->mem_cache_client =
-		dm_mem_cache_client_create(rstripes, rs->set.raid_devs,
-					   chunk_pages(rec->io_size));
+		dm_mem_cache_client_create(rstripes *
+					   stripe_pages(rs, rec->io_size),
+					   rstripes, rs->set.raid_devs);
 	if (IS_ERR(rec->mem_cache_client))
 		return PTR_ERR(rec->mem_cache_client);
 
 	/* Create dm-io client context for IO stripes. */
 	sc->dm_io_client =
 		dm_io_client_create((stripes > 32 ? 32 : stripes) *
-				    rs->set.raid_devs *
-				    chunk_pages(rs->set.io_size));
+				    stripe_pages(rs, rs->set.io_size));
 	if (IS_ERR(sc->dm_io_client))
 		return PTR_ERR(sc->dm_io_client);
 
 	/* FIXME: intermingeled with stripe cache initialization. */
 	/* Create dm-io client context for recovery stripes. */
 	rec->dm_io_client =
-		dm_io_client_create(rstripes * rs->set.raid_devs *
-				    chunk_pages(rec->io_size));
+		dm_io_client_create(rstripes * stripe_pages(rs, rec->io_size));
 	if (IS_ERR(rec->dm_io_client))
 		return PTR_ERR(rec->dm_io_client);
 
 	/* Allocate stripes for set recovery. */
 	while (rstripes--) {
 		stripe = stripe_alloc(sc, rec->mem_cache_client,
-				      rs->recover.io_size, SC_KEEP);
+				      rec->io_size, SC_KEEP);
 		if (!stripe)
 			return -ENOMEM;
 
@@ -2928,8 +2927,8 @@ static void recover_rh_update(struct stripe *stripe, enum recover_type success)
 		return;
 	}
 
-	rh_recovery_end(addr->reg, success);
-	if (success)
+	rh_recovery_end(addr->reg, success == REC_SUCCESS ? 0 : -EIO);
+	if (success == REC_SUCCESS)
 		rec->nr_regions_recovered++;
 
 	addr->reg = NULL;
@@ -3753,7 +3752,7 @@ static int get_raid_variable_parms(struct dm_target *ti, char **argv,
 {
 	int p, value;
 	struct {
-		int action; /* -1: skip, 0: no pwer2 check, 1: power2 check */
+		int action; /* -1: skip, 0: no power2 check, 1: power2 check */
 		char *errmsg;
 		int min, max;
 		int *var, *var2, *var3;