X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=bitmap.c;h=18101664fa1728e997bdb27826141d5a1f40cca7;hb=78b958e2052ccd069fa6ccc2367cda758d55540e;hp=768c17fc0bb480b79917490e6a4a6a77263d2994;hpb=97a6748ce2fc70f35b599bd16b76d16a1e48bc0d;p=thirdparty%2Fmdadm.git diff --git a/bitmap.c b/bitmap.c index 768c17fc..18101664 100644 --- a/bitmap.c +++ b/bitmap.c @@ -115,6 +115,15 @@ unsigned long long bitmap_bits(unsigned long long array_size, return (array_size * 512 + chunksize - 1) / chunksize; } +unsigned long bitmap_sectors(struct bitmap_super_s *bsb) +{ + unsigned long long bits = bitmap_bits(__le64_to_cpu(bsb->sync_size), + __le32_to_cpu(bsb->chunksize)); + int bits_per_sector = 8*512; + return (bits + bits_per_sector - 1) / bits_per_sector; +} + + bitmap_info_t *bitmap_fd_read(int fd, int brief) { /* Note: fd might be open O_DIRECT, so we must be @@ -122,11 +131,13 @@ bitmap_info_t *bitmap_fd_read(int fd, int brief) */ unsigned long long total_bits = 0, read_bits = 0, dirty_bits = 0; bitmap_info_t *info; - char *buf, *unaligned; + void *buf; int n, skip; - unaligned = malloc(8192*2); - buf = (char*) ((unsigned long)unaligned | 8191)+1; + if (posix_memalign(&buf, 512, 8192) != 0) { + fprintf(stderr, Name ": failed to allocate 8192 bytes\n"); + return NULL; + } n = read(fd, buf, 8192); info = malloc(sizeof(*info)); @@ -145,14 +156,13 @@ bitmap_info_t *bitmap_fd_read(int fd, int brief) fprintf(stderr, Name ": failed to read superblock of bitmap " "file: %s\n", strerror(errno)); free(info); - free(unaligned); return NULL; } memcpy(&info->sb, buf, sizeof(info->sb)); skip = sizeof(info->sb); sb_le_to_cpu(&info->sb); /* convert superblock to CPU byte ordering */ - + if (brief || info->sb.sync_size == 0) goto out; @@ -219,8 +229,8 @@ bitmap_info_t *bitmap_file_read(char *filename, int brief, struct supertype **st if (!st) { /* just look at device... */ lseek(fd, 0, 0); - } else { - st->ss->locate_bitmap(st, fd, NULL); + } else { + st->ss->locate_bitmap(st, fd); } ioctl(fd, BLKFLSBUF, 0); /* make sure we read current data */ *stp = st; @@ -260,6 +270,7 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st) bitmap_info_t *info; int rv = 1; char buf[64]; + int swap; info = bitmap_file_read(filename, brief, &st); if (!info) @@ -279,14 +290,22 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st) } rv = 0; - if (st && st->ss->swapuuid) { - printf(" UUID : %08x.%08x.%08x.%08x\n", + if (st) + swap = st->ss->swapuuid; + else +#if __BYTE_ORDER == BIG_ENDIAN + swap = 0; +#else + swap = 1; +#endif + if (swap) { + printf(" UUID : %08x:%08x:%08x:%08x\n", swapl(*(__u32 *)(sb->uuid+0)), swapl(*(__u32 *)(sb->uuid+4)), swapl(*(__u32 *)(sb->uuid+8)), swapl(*(__u32 *)(sb->uuid+12))); } else { - printf(" UUID : %08x.%08x.%08x.%08x\n", + printf(" UUID : %08x:%08x:%08x:%08x\n", *(__u32 *)(sb->uuid+0), *(__u32 *)(sb->uuid+4), *(__u32 *)(sb->uuid+8), @@ -345,11 +364,12 @@ int CreateBitmap(char *filename, int force, char uuid[16], if (chunksize == UnSet) { /* We don't want more than 2^21 chunks, as 2^11 fill up one * 4K page (2 bytes per chunk), and 2^10 address of those - * fill up a 4K indexing page. 2^20 might be safer... + * fill up a 4K indexing page. 2^20 might be safer, especially + * on 64bit hosts, so use that. */ chunksize = DEFAULT_BITMAP_CHUNK; - /* <<21 for 2^21 chunks, >>9 to convert bytes to sectors */ - while (array_size > (chunksize << (21-9))) + /* <<20 for 2^20 chunks, >>9 to convert bytes to sectors */ + while (array_size > (chunksize << (20-9))) chunksize <<= 1; } @@ -388,7 +408,7 @@ int CreateBitmap(char *filename, int force, char uuid[16], } bytes -= sizeof(block); } - + rv = 0; fflush(fp); /* make the file be the right size (well, to the nearest byte) */ @@ -401,7 +421,7 @@ out: return rv; } -int bitmap_update_uuid(int fd, int *uuid) +int bitmap_update_uuid(int fd, int *uuid, int swap) { struct bitmap_super_s bm; if (lseek(fd, 0, 0) != 0) @@ -410,7 +430,7 @@ int bitmap_update_uuid(int fd, int *uuid) return 1; if (bm.magic != __cpu_to_le32(BITMAP_MAGIC)) return 1; - memcpy(bm.uuid, uuid, 16); + copy_uuid(bm.uuid, uuid, swap); if (lseek(fd, 0, 0) != 0) return 2; if (write(fd, &bm, sizeof(bm)) != sizeof(bm)) {