/*
* mdadm - manage Linux "md" devices aka RAID arrays.
*
- * Copyright (C) 2001-2004 Neil Brown <neilb@cse.unsw.edu.au>
+ * Copyright (C) 2001-2006 Neil Brown <neilb@suse.de>
*
*
* This program is free software; you can redistribute it and/or modify
printf(" New Layout : %s\n", c?c:"-unknown-");
}
if (__le32_to_cpu(sb->level) == 10) {
- printf(" New Layout : near=%d, far=%d\n",
+ printf(" New Layout : near=%d, %s=%d\n",
__le32_to_cpu(sb->new_layout)&255,
+ (__le32_to_cpu(sb->new_layout)&0x10000)?"offset":"far",
(__le32_to_cpu(sb->new_layout)>>8)&255);
}
}
}
if (__le32_to_cpu(sb->level) == 10) {
int lo = __le32_to_cpu(sb->layout);
- printf(" Layout : near=%d, far=%d\n",
- lo&255, (lo>>8)&255);
+ printf(" Layout : near=%d, %s=%d\n",
+ lo&255,
+ (lo&0x10000)?"offset":"far",
+ (lo>>8)&255);
}
switch(__le32_to_cpu(sb->level)) {
case 0:
/* make sure resync happens */
sb->resync_offset = ~0ULL;
}
- if (strcmp(update, "uuid") == 0)
+ if (strcmp(update, "uuid") == 0) {
memcpy(sb->set_uuid, info->uuid, 16);
+ if (__le32_to_cpu(sb->feature_map)&MD_FEATURE_BITMAP_OFFSET) {
+ struct bitmap_super_s *bm;
+ bm = (struct bitmap_super_s*)(sbv+1024);
+ memcpy(bm->uuid, info->uuid, 16);
+ }
+ }
if (strcmp(update, "_reshape_progress")==0)
sb->reshape_position = __cpu_to_le64(info->reshape_progress);
*rp = 0xfffe;
}
+static void locate_bitmap1(struct supertype *st, int fd, void *sbv);
+
static int store_super1(struct supertype *st, int fd, void *sbv)
{
struct mdp_superblock_1 *sb = sbv;
if (write(fd, sb, sbsize) != sbsize)
return 4;
+ if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) {
+ struct bitmap_super_s *bm = (struct bitmap_super_s*)
+ ((char*)sb)+1024;
+ if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC) {
+ locate_bitmap1(st, fd, sbv);
+ write(fd, bm, sizeof(*bm));
+ }
+ }
fsync(fd);
return 0;
}
return 1;
if (!first) {
- first = malloc(1024);
- memcpy(first, second, 1024);
+ first = malloc(1024+sizeof(bitmap_super_t));
+ memcpy(first, second, 1024+sizeof(bitmap_super_t));
*firstp = first;
return 0;
}
unsigned long long dsize;
unsigned long long sb_offset;
struct mdp_superblock_1 *super;
-
+ int uuid[4];
+ struct bitmap_super_s *bsb;
if (st->ss == NULL) {
/*
* Calculate the position of the superblock.
* It is always aligned to a 4K boundary and
- * depeding on minor_version, it can be:
+ * 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.
return 2;
}
*sbp = super;
+
+ /* Now check on the bitmap superblock */
+ if ((__le32_to_cpu(super->feature_map)&MD_FEATURE_BITMAP_OFFSET) == 0)
+ return 0;
+ /* Read the bitmap superblock and make sure it looks
+ * valid. If it doesn't clear the bit. An --assemble --force
+ * should get that written out.
+ */
+ locate_bitmap1(st, fd, super);
+ if (read(fd, ((char*)super)+1024, sizeof(struct bitmap_super_s))
+ != sizeof(struct bitmap_super_s))
+ goto no_bitmap;
+
+ uuid_from_super1(uuid, super);
+ bsb = (struct bitmap_super_s *)(((char*)super)+1024);
+ if (__le32_to_cpu(bsb->magic) != BITMAP_MAGIC ||
+ memcmp(bsb->uuid, uuid, 16) != 0)
+ goto no_bitmap;
+ return 0;
+
+ no_bitmap:
+ super->feature_map = __cpu_to_le32(__le32_to_cpu(super->feature_map) & ~1);
return 0;
}
}
-void locate_bitmap1(struct supertype *st, int fd, void *sbv)
+static void locate_bitmap1(struct supertype *st, int fd, void *sbv)
{
unsigned long long offset;
struct mdp_superblock_1 *sb;
lseek64(fd, offset<<9, 0);
}
-int write_bitmap1(struct supertype *st, int fd, void *sbv)
+static int write_bitmap1(struct supertype *st, int fd, void *sbv)
{
struct mdp_superblock_1 *sb = sbv;
bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+1024);