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)
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);
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);
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) {
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;
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;
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;
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);
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);
-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;
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;
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;
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;
*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;
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);