linux-raid.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Chris Webb <chris@arachsys.com>
To: Neil Brown <neilb@suse.de>
Cc: linux-raid@vger.kernel.org
Subject: Re: Trouble increasing md component size
Date: Thu, 19 Jun 2008 16:45:20 +0100	[thread overview]
Message-ID: <20080619154520.GB3708@arachsys.com> (raw)
In-Reply-To: <18521.54665.166875.489547@notabene.brown>

[-- Attachment #1: Type: text/plain, Size: 2361 bytes --]

Hi. Thanks for the helpful pointers.

Neil Brown <neilb@suse.de> writes:

> I'd put this on my todo list if it wasn't so long already :-)
> (Well, I've put it there anyway, but no promises).

I'll have a stab at implementing this if you like: it's only fair as I'm the
one who wants the feature!

> It would require changing the 'size' as known by md of each device
> first.  i.e. /sys/block/mdX/md/dev-*/size.
> However this currently cannot be changed while the array is active.
> 
> I cannot immediately see a good reason why not.  It may be as simple
> as removing
> 
> 	if (my_mddev->pers)
> 		return -EBUSY;
> 
> from the start of rdev_size_store, but I wouldn't recommend
> experimenting with that on a production system....

Looking through the kernel md.c driver, I can't see anywhere that will
obviously break if rdev->size increases on a running array; it's used very
rarely. Given this, I've tried taking this check out in a scratch virtual
machine, and it works nicely: it's sufficient to echo the new size into the
sysfs file exactly as you indicate, then --grow --size=max works correctly.

I added some checks that the new value of rdev->size won't allow the data to
overlap the superblock, with rdev_size_store truncating the size value if
it is too large for the device, and filling the device if size = 0 is passed
in.

The only glitch is that the available dev size doesn't get updated in the
metadata, so next time the device is assembled, it fails to add the device
with an invalid argument error. Calling --assemble with --update=devicesize
fixes this of course.

I guess that ideally rdev_size_store should write out the changed rdev->size
to the metadata when it's called on a running array, in a similar manner to
size_store for component_size? If the superblock is version 1.x, I'm already
updating the data_size in the superblock ready to write out:

  if (sb->major_version == 1) {
          ((struct mdp_superblock_1 *) sb)->data_size = cpu_to_le64(rdev->size*2);
          /* TODO: write superblock out */
  }

However, I'm not sure what the correct call to get the superblock written
out at this point would be. I tried

  md_super_write(rdev->mddev, rdev, rdev->sb_offset << 1, rdev->sb_size,
                 rdev->sb_page);

after updating sb->data_size as above, but that doesn't seem to do the right
thing.

Cheers,

Chris.

[-- Attachment #2: linux-2.6.24.4-md-rdev-size.patch --]
[-- Type: text/plain, Size: 1168 bytes --]

--- linux-2.6.24.4/drivers/md/md.c	2008-03-24 18:49:18.000000000 +0000
+++ linux-2.6.24.4-mdplay/drivers/md/md.c	2008-06-19 16:39:29.000000000 +0100
@@ -1946,8 +1946,21 @@ rdev_size_store(mdk_rdev_t *rdev, const 
 	unsigned long long size = simple_strtoull(buf, &e, 10);
 	if (e==buf || (*e && *e != '\n'))
 		return -EINVAL;
-	if (rdev->mddev->pers)
-		return -EBUSY;
+	if (rdev->mddev->pers) {
+		mdp_super_t *sb;
+		if (rdev->sb_offset > rdev->data_offset/2) {
+			if (!size || size > rdev->sb_offset - rdev->data_offset/2)
+				size = rdev->sb_offset - rdev->data_offset/2;
+		} else if (!size || 2*size + rdev->data_offset > rdev->bdev->bd_inode->i_size >> 9)
+			size = ((rdev->bdev->bd_inode->i_size >> 9) - rdev->data_offset)/2;
+		sb = (mdp_super_t *) page_address(rdev->sb_page);
+		if (sb->major_version == 1) {
+			((struct mdp_superblock_1 *) sb)->data_size = cpu_to_le64(rdev->size*2);
+			md_super_write(rdev->mddev, rdev, rdev->sb_offset << 1, rdev->sb_size,
+					                 rdev->sb_page);
+			/* TODO: write superblock out */
+		}
+	}
 	rdev->size = size;
 	if (size < rdev->mddev->size || rdev->mddev->size == 0)
 		rdev->mddev->size = size;

  reply	other threads:[~2008-06-19 15:45 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-06-18 18:26 Trouble increasing md component size Chris Webb
2008-06-18 19:22 ` Peter Rabbitson
2008-06-18 20:00   ` Chris Webb
2008-06-19  3:42     ` Neil Brown
2008-06-19 15:45       ` Chris Webb [this message]
2008-06-19 23:10         ` Chris Webb
2008-06-19 23:49         ` Chris Webb
2008-06-20 11:13           ` Chris Webb
2008-06-20 14:24             ` Chris Webb
2008-06-23  1:26               ` Neil Brown
2008-06-23 11:18                 ` Chris Webb
2008-06-23 22:53                   ` Neil Brown
2008-06-24 11:47                     ` Chris Webb
2008-06-24 23:19                       ` Chris Webb
2008-09-17 18:11                         ` [PATCH] md: Fix rdev_size_store with size = 0 Chris Webb
2008-10-07 12:40                         ` [Resend] " Chris Webb
2008-10-13  0:54                           ` Neil Brown
2008-06-24  2:40                   ` Trouble increasing md component size Neil Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080619154520.GB3708@arachsys.com \
    --to=chris@arachsys.com \
    --cc=linux-raid@vger.kernel.org \
    --cc=neilb@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).