From 96395475fca10d5ee665d6aceb60edacdd7c77dc Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Tue, 7 Jun 2005 23:03:45 +0000 Subject: [PATCH] Make --zero-superblock work for version 1 superblocks. This requires passing the supertype to store_super Signed-off-by: Neil Brown --- Assemble.c | 6 +++--- Create.c | 2 +- Grow.c | 4 ++-- Kill.c | 4 ++-- mdadm.h | 5 ++--- super0.c | 6 +++--- super1.c | 46 ++++++++++++++++++++++++++++++++++++++++++---- 7 files changed, 55 insertions(+), 18 deletions(-) diff --git a/Assemble.c b/Assemble.c index 080cfacc..5bf58ab1 100644 --- a/Assemble.c +++ b/Assemble.c @@ -280,7 +280,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, if (dfd < 0) fprintf(stderr, Name ": Cannot open %s for superblock update\n", devname); - else if (st->ss->store_super(dfd, super)) + else if (st->ss->store_super(st, dfd, super)) fprintf(stderr, Name ": Could not re-write superblock on %s.\n", devname); if (dfd >= 0) @@ -409,7 +409,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, info.events = devices[most_recent].events; st->ss->update_super(&info, super, "force", devices[chosen_drive].devname, verbose); - if (st->ss->store_super(fd, super)) { + if (st->ss->store_super(st, fd, super)) { close(fd); fprintf(stderr, Name ": Could not re-write superblock on %s\n", devices[chosen_drive].devname); @@ -510,7 +510,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, devices[chosen_drive].devname); return 1; } - if (st->ss->store_super(fd, super)) { + if (st->ss->store_super(st, fd, super)) { close(fd); fprintf(stderr, Name ": Could not re-write superblock on %s\n", devices[chosen_drive].devname); diff --git a/Create.c b/Create.c index 5a359ee8..20ef6bf1 100644 --- a/Create.c +++ b/Create.c @@ -343,7 +343,7 @@ int Create(struct supertype *st, char *mddev, int mdfd, array.chunk_size = chunk*1024; - if (!st->ss->init_super(&super, &array)) + if (!st->ss->init_super(st, &super, &array)) return 1; if (bitmap_file && strcmp(bitmap_file, "internal")==0) { diff --git a/Grow.c b/Grow.c index 33e50c35..d20bc6ed 100644 --- a/Grow.c +++ b/Grow.c @@ -123,7 +123,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev) info.disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE); st->ss->update_super(&info, super, "grow", newdev, 0); - if (st->ss->store_super(nfd, super)) { + if (st->ss->store_super(st, nfd, super)) { fprintf(stderr, Name ": Cannot store new superblock on %s\n", newdev); close(nfd); return 1; @@ -181,7 +181,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev) info.disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE); st->ss->update_super(&info, super, "grow", dv, 0); - if (st->ss->store_super(fd2, super)) { + if (st->ss->store_super(st, fd2, super)) { fprintf(stderr, Name ": Cannot store new superblock on %s\n", dv); close(fd2); return 1; diff --git a/Kill.c b/Kill.c index ba99c6e5..709306ab 100644 --- a/Kill.c +++ b/Kill.c @@ -63,8 +63,8 @@ int Kill(char *dev, int force) mdu_array_info_t info; info.major_version = -1; /* zero superblock */ free(super); - st->ss->init_super(&super, &info); - if (st->ss->store_super(fd, super)) { + st->ss->init_super(st, &super, &info); + if (st->ss->store_super(st, fd, super)) { fprintf(stderr, Name ": Could not zero superblock on %s\n", dev); rv = 1; diff --git a/mdadm.h b/mdadm.h index f82574a0..877f353a 100644 --- a/mdadm.h +++ b/mdadm.h @@ -177,9 +177,9 @@ extern struct superswitch { void (*getinfo_super)(struct mdinfo *info, void *sbv); int (*update_super)(struct mdinfo *info, void *sbv, char *update, char *devname, int verbose); __u64 (*event_super)(void *sbv); - int (*init_super)(void **sbp, mdu_array_info_t *info); + int (*init_super)(struct supertype *st, void **sbp, mdu_array_info_t *info); void (*add_to_super)(void *sbv, mdu_disk_info_t *dinfo); - int (*store_super)(int fd, void *sbv); + int (*store_super)(struct supertype *st, int fd, void *sbv); int (*write_init_super)(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo, char *devname); int (*compare_super)(void **firstp, void *secondv); int (*load_super)(struct supertype *st, int fd, void **sbp, char *devname); @@ -270,7 +270,6 @@ extern void uuid_from_super(int uuid[4], mdp_super_t *super); extern int same_uuid(int a[4], int b[4]); /* extern int compare_super(mdp_super_t *first, mdp_super_t *second);*/ extern unsigned long calc_csum(void *super, int bytes); -extern int store_super(int fd, mdp_super_t *super); extern int enough(int level, int raid_disks, int avail_disks); extern int ask(char *mesg); diff --git a/super0.c b/super0.c index 1c2bb5e0..0364da47 100644 --- a/super0.c +++ b/super0.c @@ -325,7 +325,7 @@ static __u64 event_super0(void *sbv) -static int init_super0(void **sbp, mdu_array_info_t *info) +static int init_super0(struct supertype *st, void **sbp, mdu_array_info_t *info) { mdp_super_t *sb = malloc(MD_SB_BYTES + sizeof(bitmap_super_t)); int spares; @@ -396,7 +396,7 @@ static void add_to_super0(void *sbv, mdu_disk_info_t *dinfo) dk->state = dinfo->state; } -static int store_super0(int fd, void *sbv) +static int store_super0(struct supertype *st, int fd, void *sbv) { unsigned long size; unsigned long long dsize; @@ -446,7 +446,7 @@ static int write_init_super0(struct supertype *st, void *sbv, mdu_disk_info_t *d sb->this_disk = sb->disks[dinfo->number]; sb->sb_csum = calc_sb0_csum(sb); - rv = store_super0(fd, sb); + rv = store_super0(st, fd, sb); if (sb->state & (1<events); } -static int init_super1(void **sbp, mdu_array_info_t *info) +static int init_super1(struct supertype *st, void **sbp, mdu_array_info_t *info) { struct mdp_superblock_1 *sb = malloc(1024); int spares; @@ -438,14 +438,52 @@ static void add_to_super1(void *sbv, mdu_disk_info_t *dk) *rp = 0xfffe; } -static int store_super1(int fd, void *sbv) +static int store_super1(struct supertype *st, int fd, void *sbv) { struct mdp_superblock_1 *sb = sbv; long long sb_offset; int sbsize; + long size; + + if (ioctl(fd, BLKGETSIZE, &size)) + return 1; + + + if (size < 24) + return 2; + + /* + * Calculate the position of the superblock. + * It is always aligned to a 4K boundary and + * depending on minor_version, it can be: + * 0: At least 8K, but less than 12K, from end of device + * 1: At start of device + * 2: 4K from start of device. + */ + switch(st->minor_version) { + case 0: + sb_offset = size; + sb_offset -= 8*2; + sb_offset &= ~(4*2-1); + break; + case 1: + sb->super_offset = __cpu_to_le64(0); + break; + case 2: + sb_offset = 4*2; + break; + default: + return -EINVAL; + } + - sb_offset = __le64_to_cpu(sb->super_offset) << 9; + if (sb_offset != (__le64_to_cpu(sb->super_offset) << 9 ) && + 0 != (__le64_to_cpu(sb->super_offset) << 9 ) + ) { + fprintf(stderr, Name ": internal error - sb_offset is wrong\n"); + abort(); + } if (lseek64(fd, sb_offset, 0)< 0LL) return 3; @@ -546,7 +584,7 @@ static int write_init_super1(struct supertype *st, void *sbv, mdu_disk_info_t *d sb->sb_csum = calc_sb_1_csum(sb); - rv = store_super1(fd, sb); + rv = store_super1(st, fd, sb); if (rv) fprintf(stderr, Name ": failed to write superblock to %s\n", devname); close(fd); -- 2.39.2