X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=blobdiff_plain;f=super1.c;h=d1b8a9478ef86da4375177c59312c3c3ef19dbf6;hp=4cfd786009a6c9a8b24c944d0fea9f44f04b3321;hb=8844e291492b82f4bae6129673fb383a309514c0;hpb=9c3220067be02b5ef4da6e51ec91f928572d5223 diff --git a/super1.c b/super1.c index 4cfd7860..d1b8a947 100644 --- a/super1.c +++ b/super1.c @@ -141,13 +141,71 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) return __cpu_to_le32(csum); } +static char abuf[4096+4096]; +static int aread(int fd, void *buf, int len) +{ + /* aligned read. + * On devices with a 4K sector size, we need to read + * the full sector and copy relevant bits into + * the buffer + */ + int bsize; + char *b; + int n; + if (ioctl(fd, BLKSSZGET, &bsize) != 0 || + bsize <= len) + return read(fd, buf, len); + if (bsize > 4096) + return -1; + b = (char*)(((long)(abuf+4096))&~4095UL); + + n = read(fd, b, bsize); + if (n <= 0) + return n; + lseek(fd, len - n, 1); + if (n > len) + n = len; + memcpy(buf, b, n); + return n; +} + +static int awrite(int fd, void *buf, int len) +{ + /* aligned write. + * On devices with a 4K sector size, we need to write + * the full sector. We pre-read if the sector is larger + * than the write. + * The address must be sector-aligned. + */ + int bsize; + char *b; + int n; + if (ioctl(fd, BLKSSZGET, &bsize) != 0 || + bsize <= len) + return write(fd, buf, len); + if (bsize > 4096) + return -1; + b = (char*)(((long)(abuf+4096))&~4095UL); + + n = read(fd, b, bsize); + if (n <= 0) + return n; + lseek(fd, -n, 1); + memcpy(b, buf, len); + n = write(fd, b, bsize); + if (n <= 0) + return n; + lseek(fd, len - n, 1); + return len; +} + #ifndef MDASSEMBLE static void examine_super1(struct supertype *st, char *homehost) { struct mdp_superblock_1 *sb = st->sb; time_t atime; int d; - int faulty; + int role; int i; char *c; int l = homehost ? strlen(homehost) : 0; @@ -298,6 +356,8 @@ static void examine_super1(struct supertype *st, char *homehost) default: break; } printf("\n"); +#if 0 + /* This turns out to just be confusing */ printf(" Array Slot : %d (", __le32_to_cpu(sb->dev_number)); for (i= __le32_to_cpu(sb->max_dev); i> 0 ; i--) if (__le16_to_cpu(sb->dev_roles[i-1]) != 0xffff) @@ -310,6 +370,18 @@ static void examine_super1(struct supertype *st, char *homehost) else printf("%d", role); } printf(")\n"); +#endif + printf(" Device Role : "); + d = __le32_to_cpu(sb->dev_number); + if (d < sb->raid_disks) + role = __le16_to_cpu(sb->dev_roles[d]); + else + role = 0xFFFF; + if (role >= 0xFFFE) + printf("spare\n"); + else + printf("Active device %d\n", role); + printf(" Array State : "); for (d=0; d<__le32_to_cpu(sb->raid_disks); d++) { int cnt = 0; @@ -324,10 +396,11 @@ static void examine_super1(struct supertype *st, char *homehost) } } if (cnt > 1) printf("?"); - else if (cnt == 1 && me) printf("U"); - else if (cnt == 1) printf("u"); - else printf ("_"); + else if (cnt == 1) printf("A"); + else printf ("."); } +#if 0 + /* This is confusing too */ faulty = 0; for (i=0; i< __le32_to_cpu(sb->max_dev); i++) { int role = __le16_to_cpu(sb->dev_roles[i]); @@ -335,6 +408,8 @@ static void examine_super1(struct supertype *st, char *homehost) faulty++; } if (faulty) printf(" %d failed", faulty); +#endif + printf(" ('A' == active, '.' == missing)"); printf("\n"); } @@ -353,9 +428,11 @@ static void brief_examine_super1(struct supertype *st) else if (sb->set_name[0]) nm = sb->set_name; else - nm = "??"; + nm = NULL; - printf("ARRAY /dev/md/%s level=%s ", nm, c?c:"-unknown-"); + printf("ARRAY%s%s level=%s ", + nm ? " /dev/md/":"", nm, + c?c:"-unknown-"); sb_offset = __le64_to_cpu(sb->super_offset); if (sb_offset <= 4) printf("metadata=1.1 "); @@ -794,7 +871,7 @@ struct devinfo { }; #ifndef MDASSEMBLE /* Add a device to the superblock being created */ -static void add_to_super1(struct supertype *st, mdu_disk_info_t *dk, +static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk, int fd, char *devname) { struct mdp_superblock_1 *sb = st->sb; @@ -808,6 +885,10 @@ static void add_to_super1(struct supertype *st, mdu_disk_info_t *dk, else *rp = 0xfffe; + if (dk->number >= __le32_to_cpu(sb->max_dev) && + __le32_to_cpu(sb->max_dev) < 384) + sb->max_dev = __cpu_to_le32(dk->number+1); + sb->dev_number = __cpu_to_le32(dk->number); sb->sb_csum = calc_sb_1_csum(sb); @@ -820,6 +901,8 @@ static void add_to_super1(struct supertype *st, mdu_disk_info_t *dk, di->disk = *dk; di->next = NULL; *dip = di; + + return 0; } #endif @@ -879,7 +962,7 @@ static int store_super1(struct supertype *st, int fd) sbsize = sizeof(*sb) + 2 * __le32_to_cpu(sb->max_dev); sbsize = (sbsize+511)&(~511UL); - if (write(fd, sb, sbsize) != sbsize) + if (awrite(fd, sb, sbsize) != sbsize) return 4; if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) { @@ -887,8 +970,8 @@ static int store_super1(struct supertype *st, int fd) (((char*)sb)+1024); if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC) { locate_bitmap1(st, fd); - if (write(fd, bm, ROUND_UP(sizeof(*bm),512)) != - ROUND_UP(sizeof(*bm),512)) + if (awrite(fd, bm, sizeof(*bm)) != + sizeof(*bm)) return 5; } } @@ -1185,7 +1268,7 @@ static int load_super1(struct supertype *st, int fd, char *devname) return 1; } - if (read(fd, super, 1024) != 1024) { + if (aread(fd, super, 1024) != 1024) { if (devname) fprintf(stderr, Name ": Cannot read superblock on %s\n", devname); @@ -1230,7 +1313,7 @@ static int load_super1(struct supertype *st, int fd, char *devname) * should get that written out. */ locate_bitmap1(st, fd); - if (read(fd, ((char*)super)+1024, 512) + if (aread(fd, ((char*)super)+1024, 512) != 512) goto no_bitmap; @@ -1468,8 +1551,7 @@ static int write_bitmap1(struct supertype *st, int fd) int rv = 0; int towrite, n; - char abuf[4096+512]; - char *buf = (char*)(((long)(abuf+512))&~511UL); + char *buf = (char*)(((long)(abuf+4096))&~4095UL); locate_bitmap1(st, fd); @@ -1570,4 +1652,5 @@ struct superswitch super1 = { #else .swapuuid = 1, #endif + .name = "1.0", };