summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-03-15 14:48:20 +1100
committerNeilBrown <neilb@suse.de>2011-03-15 14:48:20 +1100
commit02c39ab1d5519d8d802e3c5d86034d68322c38e7 (patch)
treeb809fc48f3f62af34ec2f3ffbff23a7af73df88c
parent1502a43a08d0648a6b03d89b7cf189f15bea8647 (diff)
downloadmdadm-02c39ab1d5519d8d802e3c5d86034d68322c38e7.tar.gz
Manage/external: for external metadata, add_to_super needs lock on container.
add_to_super could use information from the current superblock (ddf does), so add_to_super for external metadata should be called with the O_EXCL lock held on the container to ensure the update is complete before any other process tries to make any changes (like adding another device to array). Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--Manage.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/Manage.c b/Manage.c
index 7ed4731..5932c90 100644
--- a/Manage.c
+++ b/Manage.c
@@ -774,7 +774,7 @@ int Manage_subdevs(char *devname, int fd,
disc.minor = minor(stb.st_rdev);
disc.number =j;
disc.state = 0;
- if (array.not_persistent==0 || tst->ss->external) {
+ if (array.not_persistent==0) {
int dfd;
if (dv->writemostly == 1)
disc.state |= 1 << MD_DISK_WRITEMOSTLY;
@@ -785,10 +785,7 @@ int Manage_subdevs(char *devname, int fd,
return 1;
}
/* write_init_super will close 'dfd' */
- if (tst->ss->external)
- /* mdmon will write the metadata */
- close(dfd);
- else if (tst->ss->write_init_super(tst))
+ if (tst->ss->write_init_super(tst))
return 1;
} else if (dv->re_add) {
/* this had better be raid1.
@@ -830,6 +827,7 @@ int Manage_subdevs(char *devname, int fd,
struct mdinfo *sra;
int container_fd;
int devnum = fd2devnum(fd);
+ int dfd;
container_fd = open_dev_excl(devnum);
if (container_fd < 0) {
@@ -846,6 +844,15 @@ int Manage_subdevs(char *devname, int fd,
return 1;
}
+ dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT);
+ if (tst->ss->add_to_super(tst, &disc, dfd,
+ dv->devname)) {
+ close(dfd);
+ close(container_fd);
+ return 1;
+ }
+ close(dfd);
+
sra = sysfs_read(container_fd, -1, 0);
if (!sra) {
fprintf(stderr, Name ": add failed for %s: sysfs_read failed\n",