All of lore.kernel.org
 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; 7+ 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] 7+ 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; 7+ 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] 7+ 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   ` NeilBrown
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ 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] 7+ 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   ` 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; 7+ 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] 7+ 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   ` NeilBrown
  0 siblings, 0 replies; 7+ 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] 7+ 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   ` 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; 7+ 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] 7+ 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; 7+ 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] 7+ messages in thread

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

Thread overview: 7+ 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   ` 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.