X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=bitmap.c;h=c27688c5815951bd5388cab80ad7d839c7e53866;hb=refs%2Fheads%2Fmdadm-3.2.x;hp=c905b4d3f548bd9fc72b4d8c84f8d8beb6711563;hpb=bf4fb153a4431ad3f91c3e72eebbd661b0455ed7;p=thirdparty%2Fmdadm.git diff --git a/bitmap.c b/bitmap.c index c905b4d3..c27688c5 100644 --- a/bitmap.c +++ b/bitmap.c @@ -20,8 +20,6 @@ #include "mdadm.h" -#define min(a,b) (((a) < (b)) ? (a) : (b)) - inline void sb_le_to_cpu(bitmap_super_t *sb) { sb->magic = __le32_to_cpu(sb->magic); @@ -115,6 +113,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 +129,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; - int n, skip; + void *buf; + unsigned int n, skip; - unaligned = malloc(8192*2); - buf = (char*) ((unsigned long)unaligned | 8191)+1; + if (posix_memalign(&buf, 4096, 8192) != 0) { + fprintf(stderr, Name ": failed to allocate 8192 bytes\n"); + return NULL; + } n = read(fd, buf, 8192); info = malloc(sizeof(*info)); @@ -138,6 +147,7 @@ bitmap_info_t *bitmap_fd_read(int fd, int brief) fprintf(stderr, Name ": failed to allocate %zd bytes\n", sizeof(*info)); #endif + free(buf); return NULL; } @@ -145,15 +155,15 @@ 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); + free(buf); 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) + + if (brief || info->sb.sync_size == 0 || info->sb.chunksize == 0) goto out; /* read the rest of the file counting total bits and dirty bits -- @@ -190,6 +200,7 @@ bitmap_info_t *bitmap_fd_read(int fd, int brief) total_bits = read_bits; } out: + free(buf); info->total_bits = total_bits; info->dirty_bits = dirty_bits; return info; @@ -219,9 +230,13 @@ 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 if (!st->ss->locate_bitmap) { + fprintf(stderr, Name ": No bitmap possible with %s metadata\n", + st->ss->name); + return NULL; + } else + st->ss->locate_bitmap(st, fd); + ioctl(fd, BLKFLSBUF, 0); /* make sure we read current data */ *stp = st; } else { @@ -261,6 +276,7 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st) int rv = 1; char buf[64]; int swap; + __u32 uuid32[4]; info = bitmap_file_read(filename, brief, &st); if (!info) @@ -288,19 +304,20 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st) #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", - *(__u32 *)(sb->uuid+0), - *(__u32 *)(sb->uuid+4), - *(__u32 *)(sb->uuid+8), - *(__u32 *)(sb->uuid+12)); - } + memcpy(uuid32, sb->uuid, 16); + if (swap) + printf(" UUID : %08x:%08x:%08x:%08x\n", + swapl(uuid32[0]), + swapl(uuid32[1]), + swapl(uuid32[2]), + swapl(uuid32[3])); + else + printf(" UUID : %08x:%08x:%08x:%08x\n", + uuid32[0], + uuid32[1], + uuid32[2], + uuid32[3]); + printf(" Events : %llu\n", (unsigned long long)sb->events); printf(" Events Cleared : %llu\n", (unsigned long long)sb->events_cleared); printf(" State : %s\n", bitmap_state(sb->state)); @@ -317,7 +334,7 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st) goto free_info; printf(" Bitmap : %llu bits (chunks), %llu dirty (%2.1f%%)\n", info->total_bits, info->dirty_bits, - 100.0 * info->dirty_bits / (info->total_bits + 1)); + 100.0 * info->dirty_bits / (info->total_bits?:1)); free_info: free(info); return rv; @@ -359,7 +376,7 @@ int CreateBitmap(char *filename, int force, char uuid[16], */ chunksize = DEFAULT_BITMAP_CHUNK; /* <<20 for 2^20 chunks, >>9 to convert bytes to sectors */ - while (array_size > (chunksize << (20-9))) + while (array_size > ((unsigned long long)chunksize << (20-9))) chunksize <<= 1; } @@ -398,7 +415,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) */ @@ -420,18 +437,7 @@ int bitmap_update_uuid(int fd, int *uuid, int swap) return 1; if (bm.magic != __cpu_to_le32(BITMAP_MAGIC)) return 1; - if (swap) { - unsigned char *ac = (unsigned char *)bm.uuid; - unsigned char *bc = (unsigned char *)uuid; - int i; - for (i=0; i<16; i+= 4) { - ac[i+0] = bc[i+3]; - ac[i+1] = bc[i+2]; - ac[i+2] = bc[i+1]; - ac[i+3] = bc[i+0]; - } - } else - 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)) {