linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 000 of 5] md: Introduction - assorted fixes
@ 2006-01-24  3:58 NeilBrown
  2006-01-24  3:58 ` [PATCH 001 of 5] md: Fix device-size updates in md NeilBrown
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: NeilBrown @ 2006-01-24  3:58 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-raid, linux-kernel

The following 5 patches are assorted fixes for md in 2.6.16-whatever

Patch 4 isn't exactly a 'fix'.  It adds functionality to raid6 to match
raid5.

All should be suitable for 2.6.16-rc2

Thanks,
NeilBrown


 [PATCH 001 of 5] md: Fix device-size updates in md.
 [PATCH 002 of 5] md: Make sure array geometry changes persist with version-1 superblocks.
 [PATCH 003 of 5] md: Don't remove bitmap from md array when switching to read-only
 [PATCH 004 of 5] md: Add sysfs access to raid6 stripe cache size
 [PATCH 005 of 5] md: Make sure QUEUE_FLAG_CLUSTER is set properly for md.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 001 of 5] md: Fix device-size updates in md.
  2006-01-24  3:58 [PATCH 000 of 5] md: Introduction - assorted fixes NeilBrown
@ 2006-01-24  3:58 ` NeilBrown
  2006-01-24  3:58 ` [PATCH 002 of 5] md: Make sure array geometry changes persist with version-1 superblocks NeilBrown
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: NeilBrown @ 2006-01-24  3:58 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-raid, linux-kernel


As 'array_size'  is a 'sector_t', it may overflow inappropriately 
when shifted 10 bits. So We should cast it to a loff_t first.

There are two places with this problem, but the second (in update_raid_disks) 
isn't needed so just remove it:
  The only personality that handles ->reshape currently is raid1,
  and it doesn't change the size of the array.
  When added for raid5/6, reshape again won't change the size of the array,
  at least not straight away.
  This code might be need for reshaping 'linear' but linear->shape,
  if implemented, should probably do the i_size_write itself.


Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./drivers/md/md.c |   13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff ./drivers/md/md.c~current~ ./drivers/md/md.c
--- ./drivers/md/md.c~current~	2006-01-24 13:30:25.000000000 +1100
+++ ./drivers/md/md.c	2006-01-24 13:32:25.000000000 +1100
@@ -3466,7 +3466,7 @@ static int update_size(mddev_t *mddev, u
 		bdev = bdget_disk(mddev->gendisk, 0);
 		if (bdev) {
 			mutex_lock(&bdev->bd_inode->i_mutex);
-			i_size_write(bdev->bd_inode, mddev->array_size << 10);
+			i_size_write(bdev->bd_inode, (loff_t)mddev->array_size << 10);
 			mutex_unlock(&bdev->bd_inode->i_mutex);
 			bdput(bdev);
 		}
@@ -3486,17 +3486,6 @@ static int update_raid_disks(mddev_t *md
 	if (mddev->sync_thread)
 		return -EBUSY;
 	rv = mddev->pers->reshape(mddev, raid_disks);
-	if (!rv) {
-		struct block_device *bdev;
-
-		bdev = bdget_disk(mddev->gendisk, 0);
-		if (bdev) {
-			mutex_lock(&bdev->bd_inode->i_mutex);
-			i_size_write(bdev->bd_inode, mddev->array_size << 10);
-			mutex_unlock(&bdev->bd_inode->i_mutex);
-			bdput(bdev);
-		}
-	}
 	return rv;
 }
 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 002 of 5] md: Make sure array geometry changes persist with version-1 superblocks.
  2006-01-24  3:58 [PATCH 000 of 5] md: Introduction - assorted fixes NeilBrown
  2006-01-24  3:58 ` [PATCH 001 of 5] md: Fix device-size updates in md NeilBrown
@ 2006-01-24  3:58 ` NeilBrown
  2006-01-24  3:58 ` [PATCH 003 of 5] md: Don't remove bitmap from md array when switching to read-only NeilBrown
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: NeilBrown @ 2006-01-24  3:58 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-raid, linux-kernel


super_1_sync only updates fields in the superblock that might
have changed.
'raid_disks' and 'size' could have changed, but this information
doesn't get updated.... until this patch.


Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./drivers/md/md.c |    3 +++
 1 file changed, 3 insertions(+)

diff ./drivers/md/md.c~current~ ./drivers/md/md.c
--- ./drivers/md/md.c~current~	2006-01-24 13:32:25.000000000 +1100
+++ ./drivers/md/md.c	2006-01-24 13:42:29.000000000 +1100
@@ -1162,6 +1162,9 @@ static void super_1_sync(mddev_t *mddev,
 
 	sb->cnt_corrected_read = atomic_read(&rdev->corrected_errors);
 
+	sb->raid_disks = cpu_to_le32(mddev->raid_disks);
+	sb->size = cpu_to_le64(mddev->size);
+
 	if (mddev->bitmap && mddev->bitmap_file == NULL) {
 		sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset);
 		sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET);

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 003 of 5] md: Don't remove bitmap from md array when switching to read-only
  2006-01-24  3:58 [PATCH 000 of 5] md: Introduction - assorted fixes NeilBrown
  2006-01-24  3:58 ` [PATCH 001 of 5] md: Fix device-size updates in md NeilBrown
  2006-01-24  3:58 ` [PATCH 002 of 5] md: Make sure array geometry changes persist with version-1 superblocks NeilBrown
@ 2006-01-24  3:58 ` NeilBrown
  2006-01-24  3:58 ` [PATCH 004 of 5] md: Add sysfs access to raid6 stripe cache size NeilBrown
  2006-01-24  3:58 ` [PATCH 005 of 5] md: Make sure QUEUE_FLAG_CLUSTER is set properly for md NeilBrown
  4 siblings, 0 replies; 6+ messages in thread
From: NeilBrown @ 2006-01-24  3:58 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Reuben Farrelly, linux-raid, linux-kernel


While a read-only array doesn't not really need a bitmap, we should
not remove the bitmap when switching an array to read-only because
 a/ There is no code to re-add the bitmap which switching to read-write,
 b/ There is insufficient locking - the bitmap could be accessed while it is
    being removed.

cc: Reuben Farrelly <reuben-lkml@reub.net>
Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./drivers/md/md.c |   16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff ./drivers/md/md.c~current~ ./drivers/md/md.c
--- ./drivers/md/md.c~current~	2006-01-24 13:42:29.000000000 +1100
+++ ./drivers/md/md.c	2006-01-24 14:47:17.000000000 +1100
@@ -2690,14 +2690,6 @@ static int do_md_stop(mddev_t * mddev, i
 			set_disk_ro(disk, 1);
 	}
 
-	bitmap_destroy(mddev);
-	if (mddev->bitmap_file) {
-		atomic_set(&mddev->bitmap_file->f_dentry->d_inode->i_writecount, 1);
-		fput(mddev->bitmap_file);
-		mddev->bitmap_file = NULL;
-	}
-	mddev->bitmap_offset = 0;
-
 	/*
 	 * Free resources if final stop
 	 */
@@ -2707,6 +2699,14 @@ static int do_md_stop(mddev_t * mddev, i
 		struct gendisk *disk;
 		printk(KERN_INFO "md: %s stopped.\n", mdname(mddev));
 
+		bitmap_destroy(mddev);
+		if (mddev->bitmap_file) {
+			atomic_set(&mddev->bitmap_file->f_dentry->d_inode->i_writecount, 1);
+			fput(mddev->bitmap_file);
+			mddev->bitmap_file = NULL;
+		}
+		mddev->bitmap_offset = 0;
+
 		ITERATE_RDEV(mddev,rdev,tmp)
 			if (rdev->raid_disk >= 0) {
 				char nm[20];

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 004 of 5] md: Add sysfs access to raid6 stripe cache size
  2006-01-24  3:58 [PATCH 000 of 5] md: Introduction - assorted fixes NeilBrown
                   ` (2 preceding siblings ...)
  2006-01-24  3:58 ` [PATCH 003 of 5] md: Don't remove bitmap from md array when switching to read-only NeilBrown
@ 2006-01-24  3:58 ` NeilBrown
  2006-01-24  3:58 ` [PATCH 005 of 5] md: Make sure QUEUE_FLAG_CLUSTER is set properly for md NeilBrown
  4 siblings, 0 replies; 6+ messages in thread
From: NeilBrown @ 2006-01-24  3:58 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-raid, linux-kernel


.. just as we already have for raid5.

Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./drivers/md/raid6main.c |  149 ++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 115 insertions(+), 34 deletions(-)

diff ./drivers/md/raid6main.c~current~ ./drivers/md/raid6main.c
--- ./drivers/md/raid6main.c~current~	2006-01-24 14:53:49.000000000 +1100
+++ ./drivers/md/raid6main.c	2006-01-24 14:53:49.000000000 +1100
@@ -115,7 +115,7 @@ static void __release_stripe(raid6_conf_
 			list_add_tail(&sh->lru, &conf->inactive_list);
 			atomic_dec(&conf->active_stripes);
 			if (!conf->inactive_blocked ||
-			    atomic_read(&conf->active_stripes) < (NR_STRIPES*3/4))
+			    atomic_read(&conf->active_stripes) < (conf->max_nr_stripes*3/4))
 				wake_up(&conf->wait_for_stripe);
 		}
 	}
@@ -273,7 +273,8 @@ static struct stripe_head *get_active_st
 				conf->inactive_blocked = 1;
 				wait_event_lock_irq(conf->wait_for_stripe,
 						    !list_empty(&conf->inactive_list) &&
-						    (atomic_read(&conf->active_stripes) < (NR_STRIPES *3/4)
+						    (atomic_read(&conf->active_stripes)
+						     < (conf->max_nr_stripes *3/4)
 						     || !conf->inactive_blocked),
 						    conf->device_lock,
 						    unplug_slaves(conf->mddev);
@@ -302,9 +303,31 @@ static struct stripe_head *get_active_st
 	return sh;
 }
 
-static int grow_stripes(raid6_conf_t *conf, int num)
+static int grow_one_stripe(raid6_conf_t *conf)
 {
 	struct stripe_head *sh;
+	sh = kmem_cache_alloc(conf->slab_cache, GFP_KERNEL);
+	if (!sh)
+		return 0;
+	memset(sh, 0, sizeof(*sh) + (conf->raid_disks-1)*sizeof(struct r5dev));
+	sh->raid_conf = conf;
+	spin_lock_init(&sh->lock);
+
+	if (grow_buffers(sh, conf->raid_disks)) {
+		shrink_buffers(sh, conf->raid_disks);
+		kmem_cache_free(conf->slab_cache, sh);
+		return 0;
+	}
+	/* we just created an active stripe so... */
+	atomic_set(&sh->count, 1);
+	atomic_inc(&conf->active_stripes);
+	INIT_LIST_HEAD(&sh->lru);
+	release_stripe(sh);
+	return 1;
+}
+
+static int grow_stripes(raid6_conf_t *conf, int num)
+{
 	kmem_cache_t *sc;
 	int devs = conf->raid_disks;
 
@@ -316,44 +339,33 @@ static int grow_stripes(raid6_conf_t *co
 	if (!sc)
 		return 1;
 	conf->slab_cache = sc;
-	while (num--) {
-		sh = kmem_cache_alloc(sc, GFP_KERNEL);
-		if (!sh)
+	while (num--)
+		if (!grow_one_stripe(conf))
 			return 1;
-		memset(sh, 0, sizeof(*sh) + (devs-1)*sizeof(struct r5dev));
-		sh->raid_conf = conf;
-		spin_lock_init(&sh->lock);
-
-		if (grow_buffers(sh, conf->raid_disks)) {
-			shrink_buffers(sh, conf->raid_disks);
-			kmem_cache_free(sc, sh);
-			return 1;
-		}
-		/* we just created an active stripe so... */
-		atomic_set(&sh->count, 1);
-		atomic_inc(&conf->active_stripes);
-		INIT_LIST_HEAD(&sh->lru);
-		release_stripe(sh);
-	}
 	return 0;
 }
 
-static void shrink_stripes(raid6_conf_t *conf)
+static int drop_one_stripe(raid6_conf_t *conf)
 {
 	struct stripe_head *sh;
+	spin_lock_irq(&conf->device_lock);
+	sh = get_free_stripe(conf);
+	spin_unlock_irq(&conf->device_lock);
+	if (!sh)
+		return 0;
+	if (atomic_read(&sh->count))
+		BUG();
+	shrink_buffers(sh, conf->raid_disks);
+	kmem_cache_free(conf->slab_cache, sh);
+	atomic_dec(&conf->active_stripes);
+	return 1;
+}
+
+static void shrink_stripes(raid6_conf_t *conf)
+{
+	while (drop_one_stripe(conf))
+		;
 
-	while (1) {
-		spin_lock_irq(&conf->device_lock);
-		sh = get_free_stripe(conf);
-		spin_unlock_irq(&conf->device_lock);
-		if (!sh)
-			break;
-		if (atomic_read(&sh->count))
-			BUG();
-		shrink_buffers(sh, conf->raid_disks);
-		kmem_cache_free(conf->slab_cache, sh);
-		atomic_dec(&conf->active_stripes);
-	}
 	kmem_cache_destroy(conf->slab_cache);
 	conf->slab_cache = NULL;
 }
@@ -1912,6 +1924,74 @@ static void raid6d (mddev_t *mddev)
 	PRINTK("--- raid6d inactive\n");
 }
 
+static ssize_t
+raid6_show_stripe_cache_size(mddev_t *mddev, char *page)
+{
+	raid6_conf_t *conf = mddev_to_conf(mddev);
+	if (conf)
+		return sprintf(page, "%d\n", conf->max_nr_stripes);
+	else
+		return 0;
+}
+
+static ssize_t
+raid6_store_stripe_cache_size(mddev_t *mddev, const char *page, size_t len)
+{
+	raid6_conf_t *conf = mddev_to_conf(mddev);
+	char *end;
+	int new;
+	if (len >= PAGE_SIZE)
+		return -EINVAL;
+	if (!conf)
+		return -ENODEV;
+
+	new = simple_strtoul(page, &end, 10);
+	if (!*page || (*end && *end != '\n') )
+		return -EINVAL;
+	if (new <= 16 || new > 32768)
+		return -EINVAL;
+	while (new < conf->max_nr_stripes) {
+		if (drop_one_stripe(conf))
+			conf->max_nr_stripes--;
+		else
+			break;
+	}
+	while (new > conf->max_nr_stripes) {
+		if (grow_one_stripe(conf))
+			conf->max_nr_stripes++;
+		else break;
+	}
+	return len;
+}
+
+static struct md_sysfs_entry
+raid6_stripecache_size = __ATTR(stripe_cache_size, S_IRUGO | S_IWUSR,
+				raid6_show_stripe_cache_size,
+				raid6_store_stripe_cache_size);
+
+static ssize_t
+stripe_cache_active_show(mddev_t *mddev, char *page)
+{
+	raid6_conf_t *conf = mddev_to_conf(mddev);
+	if (conf)
+		return sprintf(page, "%d\n", atomic_read(&conf->active_stripes));
+	else
+		return 0;
+}
+
+static struct md_sysfs_entry
+raid6_stripecache_active = __ATTR_RO(stripe_cache_active);
+
+static struct attribute *raid6_attrs[] =  {
+	&raid6_stripecache_size.attr,
+	&raid6_stripecache_active.attr,
+	NULL,
+};
+static struct attribute_group raid6_attrs_group = {
+	.name = NULL,
+	.attrs = raid6_attrs,
+};
+
 static int run(mddev_t *mddev)
 {
 	raid6_conf_t *conf;
@@ -2095,6 +2175,7 @@ static int stop (mddev_t *mddev)
 	shrink_stripes(conf);
 	kfree(conf->stripe_hashtbl);
 	blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
+	sysfs_remove_group(&mddev->kobj, &raid6_attrs_group);
 	kfree(conf);
 	mddev->private = NULL;
 	return 0;

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 005 of 5] md: Make sure QUEUE_FLAG_CLUSTER is set properly for md.
  2006-01-24  3:58 [PATCH 000 of 5] md: Introduction - assorted fixes NeilBrown
                   ` (3 preceding siblings ...)
  2006-01-24  3:58 ` [PATCH 004 of 5] md: Add sysfs access to raid6 stripe cache size NeilBrown
@ 2006-01-24  3:58 ` NeilBrown
  4 siblings, 0 replies; 6+ messages in thread
From: NeilBrown @ 2006-01-24  3:58 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-raid, linux-kernel


This flag should be set for a virtual device iff it is set
for all underlying devices.

Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./block/ll_rw_blk.c |    2 ++
 ./drivers/md/md.c   |    1 +
 2 files changed, 3 insertions(+)

diff ./block/ll_rw_blk.c~current~ ./block/ll_rw_blk.c
--- ./block/ll_rw_blk.c~current~	2006-01-24 14:54:19.000000000 +1100
+++ ./block/ll_rw_blk.c	2006-01-24 14:54:19.000000000 +1100
@@ -778,6 +778,8 @@ void blk_queue_stack_limits(request_queu
 	t->max_hw_segments = min(t->max_hw_segments,b->max_hw_segments);
 	t->max_segment_size = min(t->max_segment_size,b->max_segment_size);
 	t->hardsect_size = max(t->hardsect_size,b->hardsect_size);
+	if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags))
+		clear_bit(QUEUE_FLAG_CLUSTER, &t->queue_flags);
 }
 
 EXPORT_SYMBOL(blk_queue_stack_limits);

diff ./drivers/md/md.c~current~ ./drivers/md/md.c
--- ./drivers/md/md.c~current~	2006-01-24 14:47:17.000000000 +1100
+++ ./drivers/md/md.c	2006-01-24 14:54:19.000000000 +1100
@@ -264,6 +264,7 @@ static mddev_t * mddev_find(dev_t unit)
 		kfree(new);
 		return NULL;
 	}
+	set_bit(QUEUE_FLAG_CLUSTER, &new->queue->queue_flags);
 
 	blk_queue_make_request(new->queue, md_fail_request);
 

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2006-01-24  3:59 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-01-24  3:58 [PATCH 000 of 5] md: Introduction - assorted fixes NeilBrown
2006-01-24  3:58 ` [PATCH 001 of 5] md: Fix device-size updates in md NeilBrown
2006-01-24  3:58 ` [PATCH 002 of 5] md: Make sure array geometry changes persist with version-1 superblocks NeilBrown
2006-01-24  3:58 ` [PATCH 003 of 5] md: Don't remove bitmap from md array when switching to read-only NeilBrown
2006-01-24  3:58 ` [PATCH 004 of 5] md: Add sysfs access to raid6 stripe cache size NeilBrown
2006-01-24  3:58 ` [PATCH 005 of 5] md: Make sure QUEUE_FLAG_CLUSTER is set properly for md NeilBrown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).