X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=super0.c;h=ffa5cf7f5d2a7d7f77d6f3c8c07fd5172fbed5ef;hb=3ddc317ee91ca2bc2b1874d1ddd03e1ae7e229d5;hp=7ff5ff427cab070f3d88f9c4a89caf346c82cc32;hpb=f277ce367125882ea809f981172b8d5c0cc4d5c7;p=thirdparty%2Fmdadm.git diff --git a/super0.c b/super0.c index 7ff5ff42..ffa5cf7f 100644 --- a/super0.c +++ b/super0.c @@ -52,7 +52,39 @@ static unsigned long calc_sb0_csum(mdp_super_t *super) 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; @@ -116,15 +148,19 @@ static void examine_super0(void *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<state &= ~(1<state & (1<state & (1<state & (1<state & (1<state == 0) printf(" spare"); if ((dv=map_dev(dp->major, dp->minor))) printf(" %s", dv); @@ -187,7 +223,7 @@ static void uuid_from_super0(int uuid[4], void * sbv) } } -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; @@ -210,7 +246,8 @@ static void getinfo_super0(struct mdinfo *info, void *sbv) 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<= 0) + fprintf (stderr, Name ": adjusting superblock of %s for 2.2/sparc compatability.\n", + devname); } if (strcmp(update, "super-minor") ==0) { sb->md_minor = info->array.md_minor; - if (verbose) + if (verbose > 0) fprintf(stderr, Name ": updating superblock of %s with minor number %d\n", devname, info->array.md_minor); } @@ -280,8 +318,10 @@ static int update_super0(struct mdinfo *info, void *sbv, char *update, char *dev } if (strcmp(update, "assemble")==0) { int d = info->disk.number; + int wonly = sb->disks[d].state & (1<disks[d].state &= ~(1<disks[d].state != info->disk.state) { - sb->disks[d].state = info->disk.state; + sb->disks[d].state = info->disk.state & wonly; rv = 1; } } @@ -327,7 +367,7 @@ static __u64 event_super0(void *sbv) -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; @@ -435,7 +475,7 @@ static int store_super0(struct supertype *st, int fd, void *sbv) 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) { @@ -450,25 +490,8 @@ static int write_init_super0(struct supertype *st, void *sbv, mdu_disk_info_t *d sb->sb_csum = calc_sb0_csum(sb); rv = store_super0(st, fd, sb); - if (sb->state & (1< 0) { - n = towrite; - if (n > sizeof(buf)) - n = sizeof(buf); - n = write(fd, buf, n); - if (n > 0) - towrite -= n; - else - break; - } - if (towrite) - rv = -2; - } + if (rv == 0 && (sb->state & (1<ss->write_bitmap(st, fd, sbv); close(fd); if (rv) @@ -572,6 +595,9 @@ static int load_super0(struct supertype *st, int fd, void **sbp, char *devname) 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", @@ -611,18 +637,22 @@ static struct supertype *match_metadata_desc0(char *arg) ) return st; + st->minor_version = 9; /* flag for 'byte-swapped' */ + if (strcmp(arg, "0.swap")==0) + return st; + free(st); return NULL; } -static __u64 avail_size0(__u64 devsize) +static __u64 avail_size0(struct supertype *st, __u64 devsize) { if (devsize < MD_RESERVED_SECTORS*2) return 0ULL; 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(struct supertype *st, void *sbv, int chunk, int delay, int write_behind, int *sizep, int may_change) { /* * The bitmap comes immediately after the superblock and must be 60K in size @@ -630,8 +660,8 @@ static int add_internal_bitmap0(void *sbv, int chunk, int delay, unsigned long l * * size is in K, chunk is in bytes !!! */ - - unsigned long long bits = size; + unsigned long long size = *sizep; + unsigned long long bits; unsigned long long max_bits = 60*1024*8; unsigned long long min_chunk; mdp_super_t *sb = sbv; @@ -639,6 +669,7 @@ static int add_internal_bitmap0(void *sbv, int chunk, int delay, unsigned long l min_chunk = 4096; /* sub-page chunks don't work yet.. */ + bits = (size * 1024)/ min_chunk +1; while (bits > max_bits) { min_chunk *= 2; bits = (bits+1)/2; @@ -651,12 +682,13 @@ static int add_internal_bitmap0(void *sbv, int chunk, int delay, unsigned long l sb->state |= (1<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<<1); + bms->write_behind = __cpu_to_le32(write_behind); @@ -737,12 +769,12 @@ int write_bitmap0(struct supertype *st, int fd, void *sbv) else break; } + fsync(fd); if (towrite) rv = -2; return rv; } - struct superswitch super0 = { #ifndef MDASSEMBLE