]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Don't close fds in write_init_super
authorNeilBrown <neilb@suse.de>
Mon, 24 Jan 2011 20:56:53 +0000 (07:56 +1100)
committerNeilBrown <neilb@suse.de>
Mon, 24 Jan 2011 20:56:53 +0000 (07:56 +1100)
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>
Examine.c
Manage.c
super-ddf.c
super-intel.c
super0.c
super1.c

index ffca9ca5f9d615721b68db3a9af0a1d2eda57788..f949646f48aea561e8b68545b5e0f9d1dd13af67 100644 (file)
--- a/Examine.c
+++ b/Examine.c
@@ -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);
index 4e6afb50390e6df10e162c39a6d69c7ac600e434..824caa98d1dedbd00b02ccf31ecc33ed59ad52ac 100644 (file)
--- a/Manage.c
+++ b/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':
index bd3e8840c54efaf569f11273925e2d9194fc6e91..287fa7f8e1e958d96c8492ec222bb5ce3034ab4c 100644 (file)
@@ -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");
 }
 
index d86e8d8111de1748d203d965c06c9b4eba7f1edb..83fcb064f6abe896e6041b856babc02c00ca77db 100644 (file)
@@ -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;
index d69d0c049ad81d5337a1432158c91e4d0cf08e66..0b95dac214c73c34bf64d6bcf704a51395cd50f7 100644 (file)
--- a/super0.c
+++ b/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;
 }
 
index f879e669db79ee1bb3f0376d43bfc850141139fc..8a89d3b1cc00705bd6c3da78ce30121248653300 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -1641,6 +1641,13 @@ static void free_super1(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;
 }