return newcsum;
}
+
+void super0_swap_endian(struct mdp_superblock_s *sb)
+{
+ /* as super0 superblocks are host-endian, it is sometimes
+ * useful to be able to swap the endianness
+ * as (almost) everything is u32's we byte-swap every 4byte
+ * number.
+ * We then also have to swap the events_hi and events_lo
+ */
+ char *sbc = (char *)sb;
+ __u32 t32;
+ int i;
+
+ for (i=0; i < MD_SB_BYTES ; i+=4) {
+ char t = sbc[i];
+ sbc[i] = sbc[i+3];
+ sbc[i+3] = t;
+ t=sbc[i+1];
+ sbc[i+1]=sbc[i+2];
+ sbc[i+2]=t;
+ }
+ t32 = sb->events_hi;
+ sb->events_hi = sb->events_lo;
+ sb->events_lo = t32;
+
+ t32 = sb->cp_events_hi;
+ sb->cp_events_hi = sb->cp_events_lo;
+ sb->cp_events_lo = t32;
+
+}
+
#ifndef MDASSEMBLE
+
static void examine_super0(void *sbv)
{
mdp_super_t *sb = sbv;
mdp_disk_t *dp;
char *dv;
char nb[5];
+ int wonly;
if (d>=0) dp = &sb->disks[d];
else dp = &sb->this_disk;
snprintf(nb, sizeof(nb), "%4d", d);
printf("%4s %5d %5d %5d %5d ", d < 0 ? "this" : nb,
dp->number, dp->major, dp->minor, dp->raid_disk);
+ wonly = dp->state & (1<<MD_DISK_WRITEMOSTLY);
+ dp->state &= ~(1<<MD_DISK_WRITEMOSTLY);
if (dp->state & (1<<MD_DISK_FAULTY)) printf(" faulty");
if (dp->state & (1<<MD_DISK_ACTIVE)) printf(" active");
if (dp->state & (1<<MD_DISK_SYNC)) printf(" sync");
if (dp->state & (1<<MD_DISK_REMOVED)) printf(" removed");
+ if (wonly) printf(" write-mostly");
if (dp->state == 0) printf(" spare");
if ((dv=map_dev(dp->major, dp->minor)))
printf(" %s", dv);
}
}
-static void getinfo_super0(struct mdinfo *info, void *sbv)
+static void getinfo_super0(struct mdinfo *info, mddev_ident_t ident, void *sbv)
{
mdp_super_t *sb = sbv;
int working = 0;
info->events = md_event(sb);
uuid_from_super0(info->uuid, sbv);
-
+
+ ident->name[0] = 0;
/* work_disks is calculated rather than read directly */
for (i=0; i < MD_SB_DISKS; i++)
if ((sb->disks[i].state & (1<<MD_DISK_SYNC)) &&
}
if (strcmp(update, "assemble")==0) {
int d = info->disk.number;
+ int wonly = sb->disks[d].state & (1<<MD_DISK_WRITEMOSTLY);
+ sb->disks[d].state &= ~(1<<MD_DISK_WRITEMOSTLY);
if (sb->disks[d].state != info->disk.state) {
- sb->disks[d].state = info->disk.state;
+ sb->disks[d].state = info->disk.state & wonly;
rv = 1;
}
}
-static int init_super0(struct supertype *st, void **sbp, mdu_array_info_t *info)
+static int init_super0(struct supertype *st, void **sbp, mdu_array_info_t *info, char *ignored_name)
{
mdp_super_t *sb = malloc(MD_SB_BYTES + sizeof(bitmap_super_t));
int spares;
static int write_init_super0(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo, char *devname)
{
mdp_super_t *sb = sbv;
- int fd = open(devname, O_RDWR, O_EXCL);
+ int fd = open(devname, O_RDWR|O_EXCL);
int rv;
if (fd < 0) {
if (sb->state & (1<<MD_SB_BITMAP_PRESENT)) {
int towrite, n;
char buf[4096];
+
write(fd, ((char*)sb)+MD_SB_BYTES, sizeof(bitmap_super_t));
towrite = 64*1024 - MD_SB_BYTES - sizeof(bitmap_super_t);
memset(buf, 0xff, sizeof(buf));
else
break;
}
+ fsync(fd);
if (towrite)
rv = -2;
}
uuid_from_super0(uuid1, first);
uuid_from_super0(uuid2, second);
- if (!same_uuid(uuid1, uuid2))
+ if (!same_uuid(uuid1, uuid2, 0))
return 2;
if (first->major_version != second->major_version ||
first->minor_version != second->minor_version ||
return 1;
}
+ if (st->ss && st->minor_version == 9)
+ super0_swap_endian(super);
+
if (super->md_magic != MD_SB_MAGIC) {
if (devname)
fprintf(stderr, Name ": No super block found on %s (Expected magic %08x, got %08x)\n",
)
return st;
+ st->minor_version = 9; /* flag for 'byte-swapped' */
+ if (strcmp(arg, "0.swap")==0)
+ return st;
+
free(st);
return NULL;
}
return MD_NEW_SIZE_SECTORS(devsize);
}
-static int add_internal_bitmap0(void *sbv, int chunk, int delay, unsigned long long size)
+static int add_internal_bitmap0(void *sbv, int chunk, int delay, int write_behind, unsigned long long size)
{
/*
* The bitmap comes immediately after the superblock and must be 60K in size
bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MD_SB_BYTES);
- min_chunk = 1024;
+ min_chunk = 4096; /* sub-page chunks don't work yet.. */
while (bits > max_bits) {
min_chunk *= 2;
bits = (bits+1)/2;
sb->state |= (1<<MD_SB_BITMAP_PRESENT);
memset(bms, sizeof(*bms), 0);
- bms->magic = __le32_to_cpu(BITMAP_MAGIC);
- bms->version = __le32_to_cpu(BITMAP_MAJOR);
+ bms->magic = __cpu_to_le32(BITMAP_MAGIC);
+ bms->version = __cpu_to_le32(BITMAP_MAJOR);
uuid_from_super0((int*)bms->uuid, sb);
- bms->chunksize = __le32_to_cpu(chunk);
- bms->daemon_sleep = __le32_to_cpu(delay);
- bms->sync_size = __le64_to_cpu(size);
+ bms->chunksize = __cpu_to_le32(chunk);
+ bms->daemon_sleep = __cpu_to_le32(delay);
+ bms->sync_size = __cpu_to_le64(size);
+ bms->write_behind = __cpu_to_le32(write_behind);
else
break;
}
+ fsync(fd);
if (towrite)
rv = -2;
return rv;
}
-
struct superswitch super0 = {
#ifndef MDASSEMBLE
.locate_bitmap = locate_bitmap0,
.write_bitmap = write_bitmap0,
.major = 0,
+ .swapuuid = 0,
};