diff --git a/Grow.c b/Grow.c index 1aab113..048351d 100644 --- a/Grow.c +++ b/Grow.c @@ -1893,7 +1893,7 @@ static int reshape_array(char *container, int fd, char *devname, */ if (devlist) Manage_subdevs(devname, fd, devlist, !quiet, - 0,NULL); + 0,NULL, 0); if (reshape.backup_blocks == 0) { /* No restriping needed, but we might need to impose diff --git a/Incremental.c b/Incremental.c index 09cdd9b..791ad85 100644 --- a/Incremental.c +++ b/Incremental.c @@ -1035,7 +1035,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, close(dfd); *dfdp = -1; rv = Manage_subdevs(chosen->sys_name, mdfd, &devlist, - -1, 0, NULL); + -1, 0, NULL, 0); close(mdfd); } if (verbose > 0) { @@ -1666,15 +1666,15 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) if (subfd >= 0) { Manage_subdevs(memb->dev, subfd, &devlist, verbose, 0, - NULL); + NULL, 0); close(subfd); } } free_mdstat(mdstat); } else - Manage_subdevs(ent->dev, mdfd, &devlist, verbose, 0, NULL); + Manage_subdevs(ent->dev, mdfd, &devlist, verbose, 0, NULL, 0); devlist.disposition = 'r'; - rv = Manage_subdevs(ent->dev, mdfd, &devlist, verbose, 0, NULL); + rv = Manage_subdevs(ent->dev, mdfd, &devlist, verbose, 0, NULL, 0); close(mdfd); free_mdstat(ent); return rv; diff --git a/Manage.c b/Manage.c index 66d6978..1b2b75a 100644 --- a/Manage.c +++ b/Manage.c @@ -371,7 +371,7 @@ int Manage_resize(char *devname, int fd, long long size, int raid_disks) int Manage_subdevs(char *devname, int fd, struct mddev_dev *devlist, int verbose, int test, - char *update) + char *update, int force) { /* do something to each dev. * devmode can be @@ -632,6 +632,27 @@ int Manage_subdevs(char *devname, int fd, continue; } + if (tst->ss->validate_geometry( + tst, array.level, array.layout, + array.raid_disks, NULL, + ldsize >> 9, NULL, NULL, 0) == 0) { + if (!force) { + fprintf(stderr, Name + ": %s is larger than %s can " + "effectively use.\n" + " Add --force is you " + "really wan to add this device.\n", + add_dev, devname); + close(tfd); + return 1; + } + fprintf(stderr, Name + ": %s is larger than %s can " + "effectively use.\n" + " Adding anyway as --force " + "was given.\n", + add_dev, devname); + } if (!tst->ss->external && array.major_version == 0 && md_get_version(fd)%100 < 2) { @@ -1188,9 +1209,9 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid) sprintf(devname, "%d:%d", major(devid), minor(devid)); devlist.disposition = 'r'; - if (Manage_subdevs(from_devname, fd2, &devlist, -1, 0, NULL) == 0) { + if (Manage_subdevs(from_devname, fd2, &devlist, -1, 0, NULL, 0) == 0) { devlist.disposition = 'a'; - if (Manage_subdevs(to_devname, fd1, &devlist, -1, 0, NULL) == 0) { + if (Manage_subdevs(to_devname, fd1, &devlist, -1, 0, NULL, 0) == 0) { /* make sure manager is aware of changes */ ping_manager(to_devname); ping_manager(from_devname); @@ -1198,7 +1219,7 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid) close(fd2); return 1; } - else Manage_subdevs(from_devname, fd2, &devlist, -1, 0, NULL); + else Manage_subdevs(from_devname, fd2, &devlist, -1, 0, NULL, 0); } close(fd1); close(fd2); diff --git a/mdadm.c b/mdadm.c index fb51051..4b817ab 100644 --- a/mdadm.c +++ b/mdadm.c @@ -609,6 +609,7 @@ int main(int argc, char *argv[]) case O(ASSEMBLE,Force): /* force assembly */ case O(MISC,'f'): /* force zero */ case O(MISC,Force): /* force zero */ + case O(MANAGE,Force): /* add device which is too large */ force=1; continue; @@ -1202,7 +1203,7 @@ int main(int argc, char *argv[]) if (!rv && devs_found>1) rv = Manage_subdevs(devlist->devname, mdfd, devlist->next, verbose-quiet, test, - update); + update, force); if (!rv && readonly < 0) rv = Manage_ro(devlist->devname, mdfd, readonly); if (!rv && runstop) diff --git a/mdadm.h b/mdadm.h index 8bd0077..d616966 100644 --- a/mdadm.h +++ b/mdadm.h @@ -1010,7 +1010,7 @@ extern int Manage_runstop(char *devname, int fd, int runstop, int quiet); extern int Manage_resize(char *devname, int fd, long long size, int raid_disks); extern int Manage_subdevs(char *devname, int fd, struct mddev_dev *devlist, int verbose, int test, - char *update); + char *update, int force); extern int autodetect(void); extern int Grow_Add_device(char *devname, int fd, char *newdev); extern int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int write_behind, int force);