diff --git a/ChangeLog b/ChangeLog index fdf720d..fd42b4e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,8 @@ Changes Prior to this release - Avoid segfault when parsing /proc/mdstat with auto-read-only arrays. + - Fix problem with failing to add devices to v.large (>4TB) arrays, + cause by problems with device-size overflow. Changes Prior to 2.6.4 release - Make "--create --auto=mdp" work for non-standard device names. diff --git a/Detail.c b/Detail.c index de1f409..6199d26 100644 --- a/Detail.c +++ b/Detail.c @@ -191,7 +191,7 @@ int Detail(char *dev, int brief, int export, int test, char *homehost) if (dsize > 0) printf(" Used Dev Size : %llu%s\n", dsize, - human_size((long long)array.size<<10)); + human_size((long long)dsize<<10)); else printf(" Used Dev Size : unknown\n"); } else diff --git a/Manage.c b/Manage.c index f17105a..1fb8468 100644 --- a/Manage.c +++ b/Manage.c @@ -188,6 +188,7 @@ int Manage_subdevs(char *devname, int fd, */ mdu_array_info_t array; mdu_disk_info_t disc; + unsigned long long array_size; mddev_dev_t dv, next = NULL; struct stat stb; int j, jnext = 0; @@ -202,6 +203,14 @@ int Manage_subdevs(char *devname, int fd, return 1; } + /* array.size is only 32 bit and may be truncated. + * So read from sysfs if possible, and record number of sectors + */ + + array_size = get_component_size(fd); + if (array_size <= 0) + array_size = array.size * 2; + tst = super_by_fd(fd); if (!tst) { fprintf(stderr, Name ": unsupport array - version %d.%d\n", @@ -337,7 +346,7 @@ int Manage_subdevs(char *devname, int fd, /* Make sure device is large enough */ if (tst->ss->avail_size(tst, ldsize/512) < - array.size) { + array_size) { fprintf(stderr, Name ": %s not large enough to join array\n", dv->devname); return 1; @@ -412,7 +421,7 @@ int Manage_subdevs(char *devname, int fd, /* non-persistent. Must ensure that new drive * is at least array.size big. */ - if (ldsize/512 < array.size) { + if (ldsize/512 < array_size) { fprintf(stderr, Name ": %s not large enough to join array\n", dv->devname); return 1;