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.
- Give useful message if raid4/5/6 cannot be started because it is
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
- 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:
st = super_by_version(array.major_version,
array.minor_version);
/* size can be changed independantly.
/* size can be changed independently.
* layout/chunksize/raid_disks/level can be changed
* though the kernel may not support it all.
* 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);
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) {
fprintf(stderr, Name ": %s: Cannot get array details from sysfs\n",
devname);
@ -742,10 +743,25 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
array.chunk_size = nchunk;
array.layout = nlayout;
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",
devname, strerror(errno));
goto abort;
}
ok: ;
/* suspend the relevant region */
sysfs_set_num(sra, NULL, "suspend_hi", 0); /* just in case */

View File

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

View File

@ -107,6 +107,12 @@ struct sysarray *sysfs_read(int fd, int devnum, unsigned long options)
goto abort;
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))
return sra;