Don't close fds in write_init_super
We previously closed all 'fds' associated with an array in write_init_super .. sometimes, and sometimes at bad times. This isn't neat and free_super is a better place to close them. So make sure free_super always closes the fds that the metadata manager kept hold of, and stop closing them in write_init_super. Also add a few more calls to free_super to make sure they really do get closed. Reported-by: Adam Kwolek <adam.kwolek@intel.com> Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
446d2a5ad4
commit
1cc7f4feb9
|
@ -145,6 +145,7 @@ int Examine(struct mddev_dev *devlist, int brief, int export, int scan,
|
|||
} else if (export) {
|
||||
if (st->ss->export_examine_super)
|
||||
st->ss->export_examine_super(st);
|
||||
st->ss->free_super(st);
|
||||
} else {
|
||||
printf("%s:\n",devlist->devname);
|
||||
st->ss->examine_super(st, homehost);
|
||||
|
|
10
Manage.c
10
Manage.c
|
@ -728,6 +728,7 @@ int Manage_subdevs(char *devname, int fd,
|
|||
skip_re_add:
|
||||
re_add_failed = 1;
|
||||
}
|
||||
st->ss->free_super(st);
|
||||
}
|
||||
if (add_dev != dv->devname) {
|
||||
if (verbose > 0)
|
||||
|
@ -808,9 +809,10 @@ int Manage_subdevs(char *devname, int fd,
|
|||
close(dfd);
|
||||
return 1;
|
||||
}
|
||||
/* write_init_super will close 'dfd' */
|
||||
if (tst->ss->write_init_super(tst))
|
||||
if (tst->ss->write_init_super(tst)) {
|
||||
close(dfd);
|
||||
return 1;
|
||||
}
|
||||
} else if (dv->re_add) {
|
||||
/* this had better be raid1.
|
||||
* As we are "--re-add"ing we must find a spare slot
|
||||
|
@ -872,6 +874,9 @@ int Manage_subdevs(char *devname, int fd,
|
|||
new_mdi.disk.major = disc.major;
|
||||
new_mdi.disk.minor = disc.minor;
|
||||
new_mdi.recovery_start = 0;
|
||||
/* Make sure fds are closed as they are O_EXCL which
|
||||
* would block add_disk */
|
||||
tst->ss->free_super(tst);
|
||||
if (sysfs_add_disk(sra, &new_mdi, 0) != 0) {
|
||||
fprintf(stderr, Name ": add new device to external metadata"
|
||||
" failed for %s\n", dv->devname);
|
||||
|
@ -889,6 +894,7 @@ int Manage_subdevs(char *devname, int fd,
|
|||
}
|
||||
if (verbose >= 0)
|
||||
fprintf(stderr, Name ": added %s\n", dv->devname);
|
||||
tst->ss->free_super(tst);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
|
|
12
super-ddf.c
12
super-ddf.c
|
@ -2272,7 +2272,7 @@ static int add_to_super_ddf(struct supertype *st,
|
|||
|
||||
static unsigned char null_conf[4096+512];
|
||||
|
||||
static int __write_init_super_ddf(struct supertype *st, int do_close)
|
||||
static int __write_init_super_ddf(struct supertype *st)
|
||||
{
|
||||
|
||||
struct ddf_super *ddf = st->sb;
|
||||
|
@ -2379,12 +2379,6 @@ static int __write_init_super_ddf(struct supertype *st, int do_close)
|
|||
successes++;
|
||||
}
|
||||
|
||||
if (do_close)
|
||||
for (d = ddf->dlist; d; d=d->next) {
|
||||
close(d->fd);
|
||||
d->fd = -1;
|
||||
}
|
||||
|
||||
return attempts != successes;
|
||||
}
|
||||
|
||||
|
@ -2437,7 +2431,7 @@ static int write_init_super_ddf(struct supertype *st)
|
|||
struct dl *d;
|
||||
for (d = ddf->dlist; d; d=d->next)
|
||||
while (Kill(d->devname, NULL, 0, 1, 1) == 0);
|
||||
return __write_init_super_ddf(st, 1);
|
||||
return __write_init_super_ddf(st);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3239,7 +3233,7 @@ static void ddf_sync_metadata(struct supertype *st)
|
|||
if (!ddf->updates_pending)
|
||||
return;
|
||||
ddf->updates_pending = 0;
|
||||
__write_init_super_ddf(st, 0);
|
||||
__write_init_super_ddf(st);
|
||||
dprintf("ddf: sync_metadata\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -3743,7 +3743,6 @@ static int write_init_super_imsm(struct supertype *st)
|
|||
if (st->update_tail) {
|
||||
/* queue the recently created array / added disk
|
||||
* as a metadata update */
|
||||
struct dl *d;
|
||||
int rv;
|
||||
|
||||
/* determine if we are creating a volume or adding a disk */
|
||||
|
@ -3755,11 +3754,6 @@ static int write_init_super_imsm(struct supertype *st)
|
|||
} else
|
||||
rv = create_array(st, current_vol);
|
||||
|
||||
for (d = super->disks; d ; d = d->next) {
|
||||
close(d->fd);
|
||||
d->fd = -1;
|
||||
}
|
||||
|
||||
return rv;
|
||||
} else {
|
||||
struct dl *d;
|
||||
|
|
9
super0.c
9
super0.c
|
@ -752,8 +752,6 @@ static int write_init_super0(struct supertype *st)
|
|||
fprintf(stderr,
|
||||
Name ": failed to write superblock to %s\n",
|
||||
di->devname);
|
||||
close(di->fd);
|
||||
di->fd = -1;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -1079,6 +1077,13 @@ static void free_super0(struct supertype *st)
|
|||
{
|
||||
if (st->sb)
|
||||
free(st->sb);
|
||||
while (st->info) {
|
||||
struct devinfo *di = st->info;
|
||||
st->info = di->next;
|
||||
if (di->fd >= 0)
|
||||
close(di->fd);
|
||||
free(di);
|
||||
}
|
||||
st->sb = NULL;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue