summaryrefslogtreecommitdiffstats
path: root/super1.c
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2005-06-07 23:03:45 +0000
committerNeil Brown <neilb@suse.de>2005-06-07 23:03:45 +0000
commit96395475fca10d5ee665d6aceb60edacdd7c77dc (patch)
tree0e4a63203bd0ee3729a578d2025119e4fa98f4fe /super1.c
parent34321279b8142284e86b0fc49dc9af9af92f9717 (diff)
downloadmdadm-96395475fca10d5ee665d6aceb60edacdd7c77dc.tar.gz
mdadm-96395475fca10d5ee665d6aceb60edacdd7c77dc.tar.xz
mdadm-96395475fca10d5ee665d6aceb60edacdd7c77dc.zip
Make --zero-superblock work for version 1 superblocks.
This requires passing the supertype to store_super Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
Diffstat (limited to 'super1.c')
-rw-r--r--super1.c46
1 files changed, 42 insertions, 4 deletions
diff --git a/super1.c b/super1.c
index 13859a7..a98acfa 100644
--- 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);