From 597a711b69cfff95c4b8f6069037e7ad3fc71f56 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 18 Jun 2009 08:47:42 +1000 Subject: md: remove unnecessary arguments from ->reconfig method. Passing the new layout and chunksize as args is not necessary as the mddev has fields for new_check and new_layout. This is preparation for combining the check_reshape and reconfig methods Signed-off-by: NeilBrown --- drivers/md/faulty.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/md/faulty.c') diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c index 8695809b24b..6513b7b3e37 100644 --- a/drivers/md/faulty.c +++ b/drivers/md/faulty.c @@ -255,14 +255,14 @@ static void status(struct seq_file *seq, mddev_t *mddev) } -static int reconfig(mddev_t *mddev, int layout, int chunk_size) +static int reconfig(mddev_t *mddev) { - int mode = layout & ModeMask; - int count = layout >> ModeShift; + int mode = mddev->new_layout & ModeMask; + int count = mddev->new_layout >> ModeShift; conf_t *conf = mddev->private; - if (chunk_size != -1) - return -EINVAL; + if (mddev->new_layout < 0) + return 0; /* new layout */ if (mode == ClearFaults) @@ -279,6 +279,7 @@ static int reconfig(mddev_t *mddev, int layout, int chunk_size) atomic_set(&conf->counters[mode], count); } else return -EINVAL; + mddev->new_layout = -1; mddev->layout = -1; /* makes sure further changes come through */ return 0; } @@ -315,7 +316,7 @@ static int run(mddev_t *mddev) md_set_array_sectors(mddev, faulty_size(mddev, 0, 0)); mddev->private = conf; - reconfig(mddev, mddev->layout, -1); + reconfig(mddev); return 0; } -- cgit v1.2.3-70-g09d2 From 50ac168a6e0a061bf5346d53aa9e7beb94c97527 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 18 Jun 2009 08:47:55 +1000 Subject: md: merge reconfig and check_reshape methods. The difference between these two methods is artificial. Both check that a pending reshape is valid, and perform any aspect of it that can be done immediately. 'reconfig' handles chunk size and layout. 'check_reshape' handles raid_disks. So make them just one method. Signed-off-by: NeilBrown --- drivers/md/faulty.c | 6 +++--- drivers/md/md.c | 15 ++++++++------- drivers/md/md.h | 1 - drivers/md/raid5.c | 17 ++++++++--------- 4 files changed, 19 insertions(+), 20 deletions(-) (limited to 'drivers/md/faulty.c') diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c index 6513b7b3e37..6e83b38d931 100644 --- a/drivers/md/faulty.c +++ b/drivers/md/faulty.c @@ -255,7 +255,7 @@ static void status(struct seq_file *seq, mddev_t *mddev) } -static int reconfig(mddev_t *mddev) +static int reshape(mddev_t *mddev) { int mode = mddev->new_layout & ModeMask; int count = mddev->new_layout >> ModeShift; @@ -316,7 +316,7 @@ static int run(mddev_t *mddev) md_set_array_sectors(mddev, faulty_size(mddev, 0, 0)); mddev->private = conf; - reconfig(mddev); + reshape(mddev); return 0; } @@ -339,7 +339,7 @@ static struct mdk_personality faulty_personality = .run = run, .stop = stop, .status = status, - .reconfig = reconfig, + .check_reshape = reshape, .size = faulty_size, }; diff --git a/drivers/md/md.c b/drivers/md/md.c index 5caa421c236..80f039ec3ac 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2807,10 +2807,10 @@ layout_store(mddev_t *mddev, const char *buf, size_t len) if (mddev->pers) { int err; - if (mddev->pers->reconfig == NULL) + if (mddev->pers->check_reshape == NULL) return -EBUSY; mddev->new_layout = n; - err = mddev->pers->reconfig(mddev); + err = mddev->pers->check_reshape(mddev); if (err) { mddev->new_layout = mddev->layout; return err; @@ -2885,10 +2885,10 @@ chunk_size_store(mddev_t *mddev, const char *buf, size_t len) if (mddev->pers) { int err; - if (mddev->pers->reconfig == NULL) + if (mddev->pers->check_reshape == NULL) return -EBUSY; mddev->new_chunk_sectors = n >> 9; - err = mddev->pers->reconfig(mddev); + err = mddev->pers->check_reshape(mddev); if (err) { mddev->new_chunk_sectors = mddev->chunk_sectors; return err; @@ -5224,11 +5224,11 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info) * we don't need to do anything at the md level, the * personality will take care of it all. */ - if (mddev->pers->reconfig == NULL) + if (mddev->pers->check_reshape == NULL) return -EINVAL; else { mddev->new_layout = info->layout; - rv = mddev->pers->reconfig(mddev); + rv = mddev->pers->check_reshape(mddev); if (rv) mddev->new_layout = mddev->layout; return rv; @@ -6731,7 +6731,8 @@ void md_check_recovery(mddev_t *mddev) */ if (mddev->reshape_position != MaxSector) { - if (mddev->pers->check_reshape(mddev) != 0) + if (mddev->pers->check_reshape == NULL || + mddev->pers->check_reshape(mddev) != 0) /* Cannot proceed */ goto unlock; set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); diff --git a/drivers/md/md.h b/drivers/md/md.h index 815013f8da6..bac7c2bf861 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -326,7 +326,6 @@ struct mdk_personality int (*check_reshape) (mddev_t *mddev); int (*start_reshape) (mddev_t *mddev); void (*finish_reshape) (mddev_t *mddev); - int (*reconfig) (mddev_t *mddev); /* quiesce moves between quiescence states * 0 - fully active * 1 - no new requests allowed diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 136051bc672..5ea2bdece27 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -4868,14 +4868,14 @@ static int check_stripe_cache(mddev_t *mddev) return 1; } -static int raid5_check_reshape(mddev_t *mddev) +static int check_reshape(mddev_t *mddev) { raid5_conf_t *conf = mddev->private; if (mddev->delta_disks == 0 && mddev->new_layout == mddev->layout && mddev->new_chunk_sectors == mddev->chunk_sectors) - return -EINVAL; /* nothing to do */ + return 0; /* nothing to do */ if (mddev->bitmap) /* Cannot grow a bitmap yet */ return -EBUSY; @@ -5165,7 +5165,7 @@ static void *raid5_takeover_raid6(mddev_t *mddev) } -static int raid5_reconfig(mddev_t *mddev) +static int raid5_check_reshape(mddev_t *mddev) { /* For a 2-drive array, the layout and chunk size can be changed * immediately as not restriping is needed. @@ -5202,12 +5202,13 @@ static int raid5_reconfig(mddev_t *mddev) set_bit(MD_CHANGE_DEVS, &mddev->flags); md_wakeup_thread(mddev->thread); } - return 0; + return check_reshape(mddev); } -static int raid6_reconfig(mddev_t *mddev) +static int raid6_check_reshape(mddev_t *mddev) { int new_chunk = mddev->new_chunk_sectors; + if (mddev->new_layout >= 0 && !algorithm_valid_raid6(mddev->new_layout)) return -EINVAL; if (new_chunk > 0) { @@ -5221,7 +5222,7 @@ static int raid6_reconfig(mddev_t *mddev) } /* They look valid */ - return 0; + return check_reshape(mddev); } static void *raid5_takeover(mddev_t *mddev) @@ -5312,12 +5313,11 @@ static struct mdk_personality raid6_personality = .sync_request = sync_request, .resize = raid5_resize, .size = raid5_size, - .check_reshape = raid5_check_reshape, + .check_reshape = raid6_check_reshape, .start_reshape = raid5_start_reshape, .finish_reshape = raid5_finish_reshape, .quiesce = raid5_quiesce, .takeover = raid6_takeover, - .reconfig = raid6_reconfig, }; static struct mdk_personality raid5_personality = { @@ -5340,7 +5340,6 @@ static struct mdk_personality raid5_personality = .finish_reshape = raid5_finish_reshape, .quiesce = raid5_quiesce, .takeover = raid5_takeover, - .reconfig = raid5_reconfig, }; static struct mdk_personality raid4_personality = -- cgit v1.2.3-70-g09d2 From 0894cc3066aaa3e75a99383c0d25feebf9b688ac Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Thu, 18 Jun 2009 08:49:23 +1000 Subject: md: Move check for bitmap presence to personality code. If the superblock of a component device indicates the presence of a bitmap but the corresponding raid personality does not support bitmaps (raid0, linear, multipath, faulty), then something is seriously wrong and we'd better refuse to run such an array. Currently, this check is performed while the superblocks are examined, i.e. before entering personality code. Therefore the generic md layer must know which raid levels support bitmaps and which do not. This patch avoids this layer violation without adding identical code to various personalities. This is accomplished by introducing a new public function to md.c, md_check_no_bitmap(), which replaces the hard-coded checks in the superblock loading functions. A call to md_check_no_bitmap() is added to the ->run method of each personality which does not support bitmaps and assembly is aborted if at least one component device contains a bitmap. Signed-off-by: Andre Noll Signed-off-by: NeilBrown --- drivers/md/faulty.c | 6 +++++- drivers/md/linear.c | 2 ++ drivers/md/md.c | 40 ++++++++++++++++++---------------------- drivers/md/md.h | 1 + drivers/md/multipath.c | 3 +++ drivers/md/raid0.c | 2 ++ 6 files changed, 31 insertions(+), 23 deletions(-) (limited to 'drivers/md/faulty.c') diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c index 6e83b38d931..87d88dbb667 100644 --- a/drivers/md/faulty.c +++ b/drivers/md/faulty.c @@ -299,8 +299,12 @@ static int run(mddev_t *mddev) { mdk_rdev_t *rdev; int i; + conf_t *conf; - conf_t *conf = kmalloc(sizeof(*conf), GFP_KERNEL); + if (md_check_no_bitmap(mddev)) + return -EINVAL; + + conf = kmalloc(sizeof(*conf), GFP_KERNEL); if (!conf) return -ENOMEM; diff --git a/drivers/md/linear.c b/drivers/md/linear.c index dda2f1b64a6..564c390f8a1 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c @@ -189,6 +189,8 @@ static int linear_run (mddev_t *mddev) { linear_conf_t *conf; + if (md_check_no_bitmap(mddev)) + return -EINVAL; mddev->queue->queue_lock = &mddev->queue->__queue_lock; conf = linear_conf(mddev, mddev->raid_disks); diff --git a/drivers/md/md.c b/drivers/md/md.c index 0f11fd1417a..09be637d52c 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -735,6 +735,24 @@ struct super_type { sector_t num_sectors); }; +/* + * Check that the given mddev has no bitmap. + * + * This function is called from the run method of all personalities that do not + * support bitmaps. It prints an error message and returns non-zero if mddev + * has a bitmap. Otherwise, it returns 0. + * + */ +int md_check_no_bitmap(mddev_t *mddev) +{ + if (!mddev->bitmap_file && !mddev->bitmap_offset) + return 0; + printk(KERN_ERR "%s: bitmaps are not supported for %s\n", + mdname(mddev), mddev->pers->name); + return 1; +} +EXPORT_SYMBOL(md_check_no_bitmap); + /* * load_super for 0.90.0 */ @@ -788,17 +806,6 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version rdev->data_offset = 0; rdev->sb_size = MD_SB_BYTES; - if (sb->state & (1<level != 1 && sb->level != 4 - && sb->level != 5 && sb->level != 6 - && sb->level != 10) { - /* FIXME use a better test */ - printk(KERN_WARNING - "md: bitmaps not supported for this level.\n"); - goto abort; - } - } - if (sb->level == LEVEL_MULTIPATH) rdev->desc_nr = -1; else @@ -1176,17 +1183,6 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) bdevname(rdev->bdev,b)); return -EINVAL; } - if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET)) { - if (sb->level != cpu_to_le32(1) && - sb->level != cpu_to_le32(4) && - sb->level != cpu_to_le32(5) && - sb->level != cpu_to_le32(6) && - sb->level != cpu_to_le32(10)) { - printk(KERN_WARNING - "md: bitmaps not supported for this level.\n"); - return -EINVAL; - } - } rdev->preferred_minor = 0xffff; rdev->data_offset = le64_to_cpu(sb->data_offset); diff --git a/drivers/md/md.h b/drivers/md/md.h index ea2c441449d..9430a110db9 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -430,5 +430,6 @@ extern void md_new_event(mddev_t *mddev); extern int md_allow_write(mddev_t *mddev); extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev); extern void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors); +extern int md_check_no_bitmap(mddev_t *mddev); #endif /* _MD_MD_H */ diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index c1ca63f278a..cbe368fa659 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -421,6 +421,9 @@ static int multipath_run (mddev_t *mddev) struct multipath_info *disk; mdk_rdev_t *rdev; + if (md_check_no_bitmap(mddev)) + return -EINVAL; + if (mddev->level != LEVEL_MULTIPATH) { printk("multipath: %s: raid level not set to multipath IO (%d)\n", mdname(mddev), mddev->level); diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 717e64a4af9..ab4a489d869 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -314,6 +314,8 @@ static int raid0_run(mddev_t *mddev) printk(KERN_ERR "md/raid0: chunk size must be set.\n"); return -EINVAL; } + if (md_check_no_bitmap(mddev)) + return -EINVAL; blk_queue_max_sectors(mddev->queue, mddev->chunk_sectors); mddev->queue->queue_lock = &mddev->queue->__queue_lock; -- cgit v1.2.3-70-g09d2