Handle extra 'grow' variations.

UNFINISHED
This commit is contained in:
NeilBrown 2009-08-11 13:02:49 +10:00
parent a628848379
commit 7236ee7ad4
5 changed files with 974 additions and 335 deletions

1245
Grow.c

File diff suppressed because it is too large Load Diff

28
mdadm.c
View File

@ -329,6 +329,7 @@ int main(int argc, char *argv[])
* could depend on the mode */
#define O(a,b) ((a<<8)|b)
switch (O(mode,opt)) {
case O(GROW,'c'):
case O(CREATE,'c'):
case O(BUILD,'c'): /* chunk or rounding */
if (chunk) {
@ -418,7 +419,7 @@ int main(int argc, char *argv[])
}
continue;
case O(GROW,'l'): /* hack - needed to understand layout */
case O(GROW,'l'):
case O(CREATE,'l'):
case O(BUILD,'l'): /* set raid level*/
if (level != UnSet) {
@ -1412,8 +1413,8 @@ int main(int argc, char *argv[])
if (devs_found > 1) {
/* must be '-a'. */
if (size >= 0 || raiddisks) {
fprintf(stderr, Name ": --size, --raiddisks, and --add are exclusing in --grow mode\n");
if (size >= 0 || raiddisks || chunk || layout_str != NULL || bitmap_file) {
fprintf(stderr, Name ": --add cannot be used with other geometry changes in --grow mode\n");
rv = 1;
break;
}
@ -1422,17 +1423,20 @@ int main(int argc, char *argv[])
if (rv)
break;
}
} else if ((size >= 0) + (raiddisks != 0) + (layout_str != NULL) + (bitmap_file != NULL)> 1) {
fprintf(stderr, Name ": can change at most one of size, raiddisks, bitmap, and layout\n");
rv = 1;
break;
} else if (size >= 0 || raiddisks || layout_str != NULL)
rv = Grow_reshape(devlist->devname, mdfd, quiet, backup_file,
size, level, layout_str, chunk, raiddisks);
else if (bitmap_file) {
if (delay == 0) delay = DEFAULT_BITMAP_DELAY;
} else if (bitmap_file) {
if (size >= 0 || raiddisks || chunk || layout_str != NULL) {
fprintf(stderr, Name ": --bitmap changes cannot be used with other geometry changes in --grow mode\n");
rv = 1;
break;
}
if (delay == 0)
delay = DEFAULT_BITMAP_DELAY;
rv = Grow_addbitmap(devlist->devname, mdfd, bitmap_file,
bitmap_chunk, delay, write_behind, force);
} else if (size >= 0 || raiddisks != 0 || layout_str != NULL
|| chunk != 0 || level != UnSet) {
rv = Grow_reshape(devlist->devname, mdfd, quiet, backup_file,
size, level, layout_str, chunk, raiddisks);
} else if (array_size < 0)
fprintf(stderr, Name ": no changes to --grow\n");
break;

View File

@ -370,8 +370,12 @@ extern int sysfs_set_str(struct mdinfo *sra, struct mdinfo *dev,
extern int sysfs_set_num(struct mdinfo *sra, struct mdinfo *dev,
char *name, unsigned long long val);
extern int sysfs_uevent(struct mdinfo *sra, char *event);
extern int sysfs_get_fd(struct mdinfo *sra, struct mdinfo *dev,
char *name);
extern int sysfs_fd_get_ll(int fd, unsigned long long *val);
extern int sysfs_get_ll(struct mdinfo *sra, struct mdinfo *dev,
char *name, unsigned long long *val);
extern int sysfs_fd_get_str(int fd, char *val, int size);
extern int sysfs_get_str(struct mdinfo *sra, struct mdinfo *dev,
char *name, char *val, int size);
extern int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms);

View File

@ -418,15 +418,16 @@ int save_stripes(int *source, unsigned long long *offsets,
for (disk = 0; disk < raid_disks ; disk++) {
unsigned long long offset;
int dnum;
len = chunk_size;
offset = (start/chunk_size/data_disks)*chunk_size;
dnum = geo_map(disk < data_disks ? disk : data_disks - disk - 1,
start/chunk_size/data_disks,
raid_disks, level, layout);
if (dnum < 0) abort();
if (source[dnum] < 0 ||
lseek64(source[dnum], offsets[disk]+offset, 0) < 0 ||
read(source[dnum], buf+disk * chunk_size, len) != len)
read(source[dnum], buf+disk * chunk_size, chunk_size)
!= chunk_size)
if (failed <= 2) {
fdisk[failed] = dnum;
fblock[failed] = disk;

27
sysfs.c
View File

@ -487,25 +487,32 @@ int sysfs_get_ll(struct mdinfo *sra, struct mdinfo *dev,
return n;
}
int sysfs_get_str(struct mdinfo *sra, struct mdinfo *dev,
char *name, char *val, int size)
int sysfs_fd_get_str(int fd, char *val, int size)
{
char fname[50];
int n;
int fd;
sprintf(fname, "/sys/block/%s/md/%s/%s",
sra->sys_name, dev?dev->sys_name:"", name);
fd = open(fname, O_RDONLY);
if (fd < 0)
return -1;
lseek(fd, 0, 0);
n = read(fd, val, size);
close(fd);
if (n <= 0)
return -1;
val[n] = 0;
return n;
}
int sysfs_get_str(struct mdinfo *sra, struct mdinfo *dev,
char *name, char *val, int size)
{
int n;
int fd;
fd = sysfs_get_fd(sra, dev, name);
if (fd < 0)
return -1;
n = sysfs_fd_get_str(fd, val, size);
close(fd);
return n;
}
int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms)
{
unsigned long sec;