]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Make --zero-superblock work for version 1 superblocks.
authorNeil Brown <neilb@suse.de>
Tue, 7 Jun 2005 23:03:45 +0000 (23:03 +0000)
committerNeil Brown <neilb@suse.de>
Tue, 7 Jun 2005 23:03:45 +0000 (23:03 +0000)
This requires passing the supertype to store_super

Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
Assemble.c
Create.c
Grow.c
Kill.c
mdadm.h
super0.c
super1.c

index 080cfacc26ae0e974bada8194f29a9282fbf3565..5bf58ab1f108953261eed61e772663b29631ce61 100644 (file)
@@ -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);
index 5a359ee85b5b8d6f0500af179fdc85a16dd5288a..20ef6bf1dffb96880ba4ad9ecce362c160095d8f 100644 (file)
--- 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 33e50c35567f937a7943872d2e06c770fd6b3fe6..d20bc6edc8f17a9388902ecad60276ae43e78a6d 100644 (file)
--- 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 ba99c6e529f423ff6a0d62c5fa94b73e73bc5e39..709306abacbac01394caf1931e869a48b4225cec 100644 (file)
--- 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 f82574a013f16e649d0b1f3556ba701651e066fd..877f353aaa24e526cc90e98e1e362cbb240bbbeb 100644 (file)
--- 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);
 
index 1c2bb5e06a976a62373bfe5d54de25508e09f4a5..0364da474cc2eb6cbc85de3f478fc2b870868a02 100644 (file)
--- 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<<MD_SB_BITMAP_PRESENT)) {
                int towrite, n;
index 13859a7f84cc2c53f0c05421a1009a3255174677..a98acfaaf81377a3be5cf6d0b7c4e855397bfcf3 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -368,7 +368,7 @@ static __u64 event_super1(void *sbv)
        return __le64_to_cpu(sb->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);