]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
super1: fix regression in write_init_super.
authorNeilBrown <neilb@suse.de>
Mon, 31 Jan 2011 00:33:18 +0000 (11:33 +1100)
committerNeilBrown <neilb@suse.de>
Mon, 31 Jan 2011 00:33:18 +0000 (11:33 +1100)
Now that a 'supertype' container more information, the simplistic
copying of 'st' into 'refst' is incorrect and results in closing
some fds when load_super1(refst) calls free_super().

So do it more correctly using dup_super.

Reported-by: "Labun, Marcin" <Marcin.Labun@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
super1.c

index 8a89d3b1cc00705bd6c3da78ce30121248653300..50a5f48779ca035432a9e4d8f4bd01b77c7fd97c 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -1019,11 +1019,13 @@ static unsigned long choose_bm_space(unsigned long devsize)
        return 4*2;
 }
 
+static void free_super1(struct supertype *st);
+
 #ifndef MDASSEMBLE
 static int write_init_super1(struct supertype *st)
 {
        struct mdp_superblock_1 *sb = st->sb;
-       struct supertype refst;
+       struct supertype *refst;
        int rfd;
        int rv = 0;
        unsigned long long bm_space;
@@ -1055,10 +1057,9 @@ static int write_init_super1(struct supertype *st)
 
                sb->events = 0;
 
-               refst =*st;
-               refst.sb = NULL;
-               if (load_super1(&refst, di->fd, NULL)==0) {
-                       struct mdp_superblock_1 *refsb = refst.sb;
+               refst = dup_super(st);
+               if (load_super1(refst, di->fd, NULL)==0) {
+                       struct mdp_superblock_1 *refsb = refst->sb;
 
                        memcpy(sb->device_uuid, refsb->device_uuid, 16);
                        if (memcmp(sb->set_uuid, refsb->set_uuid, 16)==0) {
@@ -1071,8 +1072,9 @@ static int write_init_super1(struct supertype *st)
                                if (get_linux_version() >= 2006018)
                                        sb->dev_number = refsb->dev_number;
                        }
-                       free(refsb);
+                       free_super1(refst);
                }
+               free(refst);
 
                if (!get_dev_size(di->fd, NULL, &dsize))
                        return 1;
@@ -1207,8 +1209,6 @@ static int compare_super1(struct supertype *st, struct supertype *tst)
        return 0;
 }
 
-static void free_super1(struct supertype *st);
-
 static int load_super1(struct supertype *st, int fd, char *devname)
 {
        unsigned long long dsize;