Increase raid456 stripe cache size if needed to --grow the array.

The setting used unfortunately requires intimate knowledge of the
kernel, and it not reset when the reshape finishes.
This commit is contained in:
Neil Brown 2006-12-14 17:31:16 +11:00
parent 583315d9c5
commit 758d3a8e7d
4 changed files with 29 additions and 2 deletions

View File

@ -12,6 +12,9 @@ Changes Prior to this release
get created automatically, as this is almost always what is wanted. get created automatically, as this is almost always what is wanted.
- Give useful message if raid4/5/6 cannot be started because it is - Give useful message if raid4/5/6 cannot be started because it is
not clean and is also degraded. not clean and is also degraded.
- Increase raid456 stripe cache size if needed to --grow the array.
The setting used unfortunately requires intimate knowledge of the
kernel, and it not reset when the reshape finishes.
Changes Prior to 2.5.6 release Changes Prior to 2.5.6 release
- Fix bug which meant "bitmap=xxx" in mdadm.conf was not handled - Fix bug which meant "bitmap=xxx" in mdadm.conf was not handled

20
Grow.c
View File

@ -523,7 +523,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
case 6: case 6:
st = super_by_version(array.major_version, st = super_by_version(array.major_version,
array.minor_version); array.minor_version);
/* size can be changed independantly. /* size can be changed independently.
* layout/chunksize/raid_disks/level can be changed * layout/chunksize/raid_disks/level can be changed
* though the kernel may not support it all. * though the kernel may not support it all.
* If 'suspend_lo' is not present in devfs, then * If 'suspend_lo' is not present in devfs, then
@ -620,7 +620,8 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
printf("mdadm: Need to backup %lluK of critical section..\n", last_block/2); printf("mdadm: Need to backup %lluK of critical section..\n", last_block/2);
sra = sysfs_read(fd, 0, sra = sysfs_read(fd, 0,
GET_COMPONENT|GET_DEVS|GET_OFFSET|GET_STATE); GET_COMPONENT|GET_DEVS|GET_OFFSET|GET_STATE|
GET_CACHE);
if (!sra) { if (!sra) {
fprintf(stderr, Name ": %s: Cannot get array details from sysfs\n", fprintf(stderr, Name ": %s: Cannot get array details from sysfs\n",
devname); devname);
@ -742,10 +743,25 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
array.chunk_size = nchunk; array.chunk_size = nchunk;
array.layout = nlayout; array.layout = nlayout;
if (ioctl(fd, SET_ARRAY_INFO, &array) != 0) { if (ioctl(fd, SET_ARRAY_INFO, &array) != 0) {
if (errno == ENOSPC) {
/* stripe cache is not big enough.
* It needs to be 4 times chunksize_size,
* and we assume pagesize is 4K
*/
if (sra->cache_size < 4 * (nchunk/4096)) {
sysfs_set_num(sra, NULL,
"stripe_cache_size",
4 * (nchunk/4096) +1);
if (ioctl(fd, SET_ARRAY_INFO,
&array) == 0)
goto ok;
}
}
fprintf(stderr, Name ": Cannot set device size/shape for %s: %s\n", fprintf(stderr, Name ": Cannot set device size/shape for %s: %s\n",
devname, strerror(errno)); devname, strerror(errno));
goto abort; goto abort;
} }
ok: ;
/* suspend the relevant region */ /* suspend the relevant region */
sysfs_set_num(sra, NULL, "suspend_hi", 0); /* just in case */ sysfs_set_num(sra, NULL, "suspend_hi", 0); /* just in case */

View File

@ -257,12 +257,14 @@ struct sysarray {
int layout; int layout;
int level; int level;
int spares; int spares;
int cache_size;
}; };
/* various details can be requested */ /* various details can be requested */
#define GET_LEVEL 1 #define GET_LEVEL 1
#define GET_LAYOUT 2 #define GET_LAYOUT 2
#define GET_COMPONENT 4 #define GET_COMPONENT 4
#define GET_CHUNK 8 #define GET_CHUNK 8
#define GET_CACHE 16
#define GET_DEVS 1024 /* gets role, major, minor */ #define GET_DEVS 1024 /* gets role, major, minor */
#define GET_OFFSET 2048 #define GET_OFFSET 2048

View File

@ -107,6 +107,12 @@ struct sysarray *sysfs_read(int fd, int devnum, unsigned long options)
goto abort; goto abort;
sra->chunk = strtoul(buf, NULL, 0); sra->chunk = strtoul(buf, NULL, 0);
} }
if (options & GET_CACHE) {
strcpy(base, "stripe_cache_size");
if (load_sys(fname, buf))
goto abort;
sra->cache_size = strtoul(buf, NULL, 0);
}
if (! (options & GET_DEVS)) if (! (options & GET_DEVS))
return sra; return sra;