diff options
Diffstat (limited to 'Grow.c')
-rw-r--r-- | Grow.c | 42 |
1 files changed, 31 insertions, 11 deletions
@@ -530,8 +530,10 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) pr_err("Cannot add bitmap while array is resyncing or reshaping etc.\n"); pr_err("Cannot set bitmap file for %s: %s\n", devname, strerror(err)); + close_fd(&bitmap_fd); return 1; } + close_fd(&bitmap_fd); } return 0; @@ -3083,6 +3085,7 @@ static int reshape_array(char *container, int fd, char *devname, int done; struct mdinfo *sra = NULL; char buf[SYSFS_MAX_BUF_SIZE]; + bool located_backup = false; /* when reshaping a RAID0, the component_size might be zero. * So try to fix that up. @@ -3165,8 +3168,10 @@ static int reshape_array(char *container, int fd, char *devname, goto release; } - if (!backup_file) + if (!backup_file) { backup_file = locate_backup(sra->sys_name); + located_backup = true; + } goto started; } @@ -3612,15 +3617,13 @@ started: mdstat_wait(30 - (delayed-1) * 25); } while (delayed); mdstat_close(); - if (check_env("MDADM_GROW_VERIFY")) - fd = open(devname, O_RDONLY | O_DIRECT); - else - fd = -1; mlockall(MCL_FUTURE); if (signal_s(SIGTERM, catch_term) == SIG_ERR) goto release; + if (check_env("MDADM_GROW_VERIFY")) + fd = open(devname, O_RDONLY | O_DIRECT); if (st->ss->external) { /* metadata handler takes it from here */ done = st->ss->manage_reshape( @@ -3632,6 +3635,7 @@ started: fd, sra, &reshape, st, blocks, fdlist, offsets, d - odisks, fdlist + odisks, offsets + odisks); + close_fd(&fd); free(fdlist); free(offsets); @@ -3701,6 +3705,8 @@ out: exit(0); release: + if (located_backup) + free(backup_file); free(fdlist); free(offsets); if (orig_level != UnSet && sra) { @@ -3839,6 +3845,7 @@ int reshape_container(char *container, char *devname, pr_err("Unable to initialize sysfs for %s\n", mdstat->devnm); rv = 1; + close_fd(&fd); break; } @@ -4717,6 +4724,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, unsigned long long *offsets; unsigned long long nstripe, ostripe; int ndata, odata; + int fd, backup_fd = -1; odata = info->array.raid_disks - info->delta_disks - 1; if (info->array.level == 6) @@ -4732,9 +4740,18 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, * been used */ old_disks = cnt; + + if (backup_file) { + backup_fd = open(backup_file, O_RDONLY); + if (!is_fd_valid(backup_fd)) { + pr_err("Can't open backup file %s : %s\n", + backup_file, strerror(errno)); + return -EINVAL; + } + } + for (i=old_disks-(backup_file?1:0); i<cnt; i++) { struct mdinfo dinfo; - int fd; int bsbsize; char *devname, namebuf[20]; unsigned long long lo, hi; @@ -4747,12 +4764,9 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, * else restore data and update all superblocks */ if (i == old_disks-1) { - fd = open(backup_file, O_RDONLY); - if (fd<0) { - pr_err("backup file %s inaccessible: %s\n", - backup_file, strerror(errno)); + if (!is_fd_valid(backup_fd)) continue; - } + fd = backup_fd; devname = backup_file; } else { fd = fdlist[i]; @@ -4907,6 +4921,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, pr_err("Error restoring backup from %s\n", devname); free(offsets); + close_fd(&backup_fd); return 1; } @@ -4923,6 +4938,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, pr_err("Error restoring second backup from %s\n", devname); free(offsets); + close_fd(&backup_fd); return 1; } @@ -4984,8 +5000,12 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, st->ss->store_super(st, fdlist[j]); st->ss->free_super(st); } + close_fd(&backup_fd); return 0; } + + close_fd(&backup_fd); + /* Didn't find any backup data, try to see if any * was needed. */ |