diff options
author | Neil Brown <neilb@suse.de> | 2008-05-15 16:48:12 +1000 |
---|---|---|
committer | Neil Brown <neilb@suse.de> | 2008-05-15 16:48:12 +1000 |
commit | 111d01fcc76d2e7d0b05f78fae67e89cdf6856ad (patch) | |
tree | 2faa362b6581db04a41f876a57c4b1c9ca6582a7 /Create.c | |
parent | 11fcec12ef68fa3b915e26676c47ee0f97d62256 (diff) | |
download | mdadm-111d01fcc76d2e7d0b05f78fae67e89cdf6856ad.tar.gz mdadm-111d01fcc76d2e7d0b05f78fae67e89cdf6856ad.tar.xz mdadm-111d01fcc76d2e7d0b05f78fae67e89cdf6856ad.zip |
Change write_init_super to be called only once.
The current model for creating arrays involves writing
a superblock to each device in the array.
With containers (as with DDF), that model doesn't work.
Every device in the container may need to be updated
for an array made from just some the devices in a container.
So instead of calling write_init_super for each device,
we call it once for the array and have it iterate over
all the devices in the array.
To help with this, ->add_to_super now passes in an 'fd' and name for
the device. These get saved for use by write_init_super. So
add_to_super takes ownership of the fd, and write_init_super will
close it.
This information is stored in the new 'info' field of supertype.
As part of this, write_init_super now removes any old traces of raid
metadata rather than doing this in common code.
Diffstat (limited to 'Create.c')
-rw-r--r-- | Create.c | 41 |
1 files changed, 19 insertions, 22 deletions
@@ -547,33 +547,28 @@ int Create(struct supertype *st, char *mddev, int mdfd, info.disk.state |= (1<<MD_DISK_WRITEMOSTLY); if (dnum == insert_point || - strcasecmp(dv->devname, "missing")==0) { - info.disk.major = 0; - info.disk.minor = 0; - info.disk.state = (1<<MD_DISK_FAULTY); - } else { - fd = open(dv->devname, O_RDONLY|O_EXCL, 0); - if (fd < 0) { - fprintf(stderr, Name ": failed to open %s after earlier success - aborting\n", - dv->devname); - return 1; - } - fstat(fd, &stb); - info.disk.major = major(stb.st_rdev); - info.disk.minor = minor(stb.st_rdev); - remove_partitions(fd); - close(fd); + strcasecmp(dv->devname, "missing")==0) + continue; + + fd = open(dv->devname, O_RDWR|O_EXCL, 0); + if (fd < 0) { + fprintf(stderr, Name ": failed to open %s " + "after earlier success - aborting\n", + dv->devname); + return 1; } + fstat(fd, &stb); + info.disk.major = major(stb.st_rdev); + info.disk.minor = minor(stb.st_rdev); + switch(pass){ case 1: - st->ss->add_to_super(st, &info.disk); + remove_partitions(fd); + st->ss->add_to_super(st, &info.disk, + fd, dv->devname); break; case 2: - if (info.disk.state == 1) break; - Kill(dv->devname, 0, 1); /* Just be sure it is clean */ - Kill(dv->devname, 0, 1); /* and again, there could be two superblocks */ - st->ss->write_init_super(st, &info.disk, - dv->devname); + close(fd); if (ioctl(mdfd, ADD_NEW_DISK, &info.disk)) { fprintf(stderr, Name ": ADD_NEW_DISK for %s failed: %s\n", @@ -586,6 +581,8 @@ int Create(struct supertype *st, char *mddev, int mdfd, } if (dv == moved_disk && dnum != insert_point) break; } + if (pass == 1) + st->ss->write_init_super(st); } st->ss->free_super(st); |