summaryrefslogtreecommitdiff
path: root/super1.c
diff options
context:
space:
mode:
authorGuoqing Jiang <gqjiang@suse.com>2015-10-19 16:03:19 +0800
committerNeilBrown <neilb@suse.com>2015-10-21 11:19:05 +1100
commitd15a1f72bd92bc4724ee94b2ae8132633ffeb72b (patch)
tree4e47c3a55d0edca1b255eb429647df358a9482b6 /super1.c
parent28d744468e0ec839cdfc4400ea7176ced5ebbc1d (diff)
downloadmdadm-d15a1f72bd92bc4724ee94b2ae8132633ffeb72b.tar.gz
Safeguard against writing to an active device of another node
Modifying an exiting device's superblock or creating a new superblock on an existing device needs to be checked because the device could be in use by another node in another array. So, we check this by taking all superblock locks in userspace so that we don't step onto an active device used by another node and safeguard against accidental edits. After the edit is complete, we release all locks and the lockspace so that it can be used by the kernel space. Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com> Signed-off-by: Guoqing Jiang <gqjiang@suse.com> Signed-off-by: NeilBrown <neilb@suse.com>
Diffstat (limited to 'super1.c')
-rw-r--r--super1.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/super1.c b/super1.c
index 47acdec..c879713 100644
--- a/super1.c
+++ b/super1.c
@@ -1110,8 +1110,18 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
* ignored.
*/
int rv = 0;
+ int lockid;
struct mdp_superblock_1 *sb = st->sb;
+ if (is_clustered(st)) {
+ rv = cluster_get_dlmlock(st, &lockid);
+ if (rv) {
+ pr_err("Cannot get dlmlock in %s return %d\n", __func__, rv);
+ cluster_release_dlmlock(st, lockid);
+ return rv;
+ }
+ }
+
if (strcmp(update, "homehost") == 0 &&
homehost) {
/* Note that 'homehost' is special as it is really
@@ -1370,6 +1380,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
rv = -1;
sb->sb_csum = calc_sb_1_csum(sb);
+ if (is_clustered(st))
+ cluster_release_dlmlock(st, lockid);
+
return rv;
}
@@ -1473,6 +1486,16 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
struct mdp_superblock_1 *sb = st->sb;
__u16 *rp = sb->dev_roles + dk->number;
struct devinfo *di, **dip;
+ int rv, lockid;
+
+ if (is_clustered(st)) {
+ rv = cluster_get_dlmlock(st, &lockid);
+ if (rv) {
+ pr_err("Cannot get dlmlock in %s return %d\n", __func__, rv);
+ cluster_release_dlmlock(st, lockid);
+ return rv;
+ }
+ }
if ((dk->state & 6) == 6) /* active, sync */
*rp = __cpu_to_le16(dk->raid_disk);
@@ -1502,6 +1525,9 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
di->next = NULL;
*dip = di;
+ if (is_clustered(st))
+ cluster_release_dlmlock(st, lockid);
+
return 0;
}
#endif
@@ -1515,6 +1541,16 @@ static int store_super1(struct supertype *st, int fd)
struct align_fd afd;
int sbsize;
unsigned long long dsize;
+ int rv, lockid;
+
+ if (is_clustered(st)) {
+ rv = cluster_get_dlmlock(st, &lockid);
+ if (rv) {
+ pr_err("Cannot get dlmlock in %s return %d\n", __func__, rv);
+ cluster_release_dlmlock(st, lockid);
+ return rv;
+ }
+ }
if (!get_dev_size(fd, NULL, &dsize))
return 1;
@@ -1575,6 +1611,9 @@ static int store_super1(struct supertype *st, int fd)
}
}
fsync(fd);
+ if (is_clustered(st))
+ cluster_release_dlmlock(st, lockid);
+
return 0;
}
@@ -2391,6 +2430,16 @@ static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update
static void free_super1(struct supertype *st)
{
+ int rv, lockid;
+ if (is_clustered(st)) {
+ rv = cluster_get_dlmlock(st, &lockid);
+ if (rv) {
+ pr_err("Cannot get dlmlock in %s return %d\n", __func__, rv);
+ cluster_release_dlmlock(st, lockid);
+ return;
+ }
+ }
+
if (st->sb)
free(st->sb);
while (st->info) {
@@ -2401,6 +2450,8 @@ static void free_super1(struct supertype *st)
free(di);
}
st->sb = NULL;
+ if (is_clustered(st))
+ cluster_release_dlmlock(st, lockid);
}
#ifndef MDASSEMBLE