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:
NeilBrown 2011-01-25 07:56:53 +11:00
parent 446d2a5ad4
commit 1cc7f4feb9
6 changed files with 26 additions and 19 deletions

View File

@ -145,6 +145,7 @@ int Examine(struct mddev_dev *devlist, int brief, int export, int scan,
} else if (export) { } else if (export) {
if (st->ss->export_examine_super) if (st->ss->export_examine_super)
st->ss->export_examine_super(st); st->ss->export_examine_super(st);
st->ss->free_super(st);
} else { } else {
printf("%s:\n",devlist->devname); printf("%s:\n",devlist->devname);
st->ss->examine_super(st, homehost); st->ss->examine_super(st, homehost);

View File

@ -728,6 +728,7 @@ int Manage_subdevs(char *devname, int fd,
skip_re_add: skip_re_add:
re_add_failed = 1; re_add_failed = 1;
} }
st->ss->free_super(st);
} }
if (add_dev != dv->devname) { if (add_dev != dv->devname) {
if (verbose > 0) if (verbose > 0)
@ -808,9 +809,10 @@ int Manage_subdevs(char *devname, int fd,
close(dfd); close(dfd);
return 1; 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; return 1;
}
} else if (dv->re_add) { } else if (dv->re_add) {
/* this had better be raid1. /* this had better be raid1.
* As we are "--re-add"ing we must find a spare slot * 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.major = disc.major;
new_mdi.disk.minor = disc.minor; new_mdi.disk.minor = disc.minor;
new_mdi.recovery_start = 0; 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) { if (sysfs_add_disk(sra, &new_mdi, 0) != 0) {
fprintf(stderr, Name ": add new device to external metadata" fprintf(stderr, Name ": add new device to external metadata"
" failed for %s\n", dv->devname); " failed for %s\n", dv->devname);
@ -889,6 +894,7 @@ int Manage_subdevs(char *devname, int fd,
} }
if (verbose >= 0) if (verbose >= 0)
fprintf(stderr, Name ": added %s\n", dv->devname); fprintf(stderr, Name ": added %s\n", dv->devname);
tst->ss->free_super(tst);
break; break;
case 'r': case 'r':

View File

@ -2272,7 +2272,7 @@ static int add_to_super_ddf(struct supertype *st,
static unsigned char null_conf[4096+512]; 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; struct ddf_super *ddf = st->sb;
@ -2379,12 +2379,6 @@ static int __write_init_super_ddf(struct supertype *st, int do_close)
successes++; successes++;
} }
if (do_close)
for (d = ddf->dlist; d; d=d->next) {
close(d->fd);
d->fd = -1;
}
return attempts != successes; return attempts != successes;
} }
@ -2437,7 +2431,7 @@ static int write_init_super_ddf(struct supertype *st)
struct dl *d; struct dl *d;
for (d = ddf->dlist; d; d=d->next) for (d = ddf->dlist; d; d=d->next)
while (Kill(d->devname, NULL, 0, 1, 1) == 0); 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) if (!ddf->updates_pending)
return; return;
ddf->updates_pending = 0; ddf->updates_pending = 0;
__write_init_super_ddf(st, 0); __write_init_super_ddf(st);
dprintf("ddf: sync_metadata\n"); dprintf("ddf: sync_metadata\n");
} }

View File

@ -3743,7 +3743,6 @@ static int write_init_super_imsm(struct supertype *st)
if (st->update_tail) { if (st->update_tail) {
/* queue the recently created array / added disk /* queue the recently created array / added disk
* as a metadata update */ * as a metadata update */
struct dl *d;
int rv; int rv;
/* determine if we are creating a volume or adding a disk */ /* 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 } else
rv = create_array(st, current_vol); rv = create_array(st, current_vol);
for (d = super->disks; d ; d = d->next) {
close(d->fd);
d->fd = -1;
}
return rv; return rv;
} else { } else {
struct dl *d; struct dl *d;

View File

@ -752,8 +752,6 @@ static int write_init_super0(struct supertype *st)
fprintf(stderr, fprintf(stderr,
Name ": failed to write superblock to %s\n", Name ": failed to write superblock to %s\n",
di->devname); di->devname);
close(di->fd);
di->fd = -1;
} }
return rv; return rv;
} }
@ -1079,6 +1077,13 @@ static void free_super0(struct supertype *st)
{ {
if (st->sb) if (st->sb)
free(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; st->sb = NULL;
} }

View File

@ -1641,6 +1641,13 @@ static void free_super1(struct supertype *st)
{ {
if (st->sb) if (st->sb)
free(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; st->sb = NULL;
} }