summaryrefslogtreecommitdiffstats
path: root/super0.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2013-05-23 06:41:29 +0200
committerNeilBrown <neilb@suse.de>2013-05-28 08:44:22 +0200
commitafa368f49ac0a12185f243eeedfa8242f2c7a036 (patch)
tree996475ef499a520f83997ebfc520069909b01cf2 /super0.c
parentsuper1: fix some casts of signed superblock fields. (diff)
downloadmdadm-afa368f49ac0a12185f243eeedfa8242f2c7a036.tar.xz
mdadm-afa368f49ac0a12185f243eeedfa8242f2c7a036.zip
Assemble: --update=metadata converts v0.90 to v1.0
This allows the smooth conversion of legacy 0.90 arrays to 1.0 metadata. Old metadata is likely to remain but will be ignored. It can be removed with mdadm --zero-superblock --metadata=0.90 /dev/whatever Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'super0.c')
-rw-r--r--super0.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/super0.c b/super0.c
index 061e475e..01c31c27 100644
--- a/super0.c
+++ b/super0.c
@@ -625,6 +625,26 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
uuid_from_super0(st, uuid);
memcpy(bm->uuid, uuid, 16);
}
+ } else if (strcmp(update, "metadata") == 0) {
+ /* Create some v1.0 metadata to match ours but make the
+ * ctime bigger. Also update info->array.*_version.
+ * We need to arrange that store_super writes out
+ * the v1.0 metadata.
+ * Not permitted for unclean array, or array with
+ * bitmap.
+ */
+ if (info->bitmap_offset) {
+ pr_err("Cannot update metadata when bitmap is present\n");
+ rv = -2;
+ } else if (info->array.state != 1) {
+ pr_err("Cannot update metadata on unclean array\n");
+ rv = -2;
+ } else {
+ info->array.major_version = 1;
+ info->array.minor_version = 0;
+ uuid_from_super0(st, info->uuid);
+ st->other = super1_make_v0(st, info, st->sb);
+ }
} else if (strcmp(update, "no-bitmap") == 0) {
sb->state &= ~(1<<MD_SB_BITMAP_PRESENT);
} else if (strcmp(update, "_reshape_progress")==0)
@@ -788,6 +808,24 @@ static int store_super0(struct supertype *st, int fd)
if (dsize < MD_RESERVED_SECTORS*512)
return 2;
+ if (st->other) {
+ /* Writing out v1.0 metadata for --update=metadata */
+ int ret;
+
+ offset = dsize/512 - 8*2;
+ offset &= ~(4*2-1);
+ offset *= 512;
+ if (lseek64(fd, offset, 0)< 0LL)
+ ret = 3;
+ else if (write(fd, st->other, 1024) != 1024)
+ ret = 4;
+ else
+ fsync(fd);
+ free(st->other);
+ st->other = NULL;
+ return ret;
+ }
+
offset = MD_NEW_SIZE_SECTORS(dsize>>9);
offset *= 512;
@@ -915,6 +953,7 @@ static int load_super0(struct supertype *st, int fd, char *devname)
devname, dsize);
return 1;
}
+ st->devsize = dsize;
offset = MD_NEW_SIZE_SECTORS(dsize>>9);