From 8fac0577f01646cb8a768c0830a884f74c63a18c Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Mon, 30 Jan 2006 23:23:45 +0000 Subject: [PATCH] Stuff like.. - report Intent Bitmap in --detail - report internal bitmap in --examine - pass' --force through to --grow --bitmap - support v.large arrays in --grow --bitmap Signed-off-by: Neil Brown --- Detail.c | 7 +++++++ Grow.c | 25 ++++++++++++++++++++----- mdadm.c | 2 +- mdadm.h | 3 ++- super1.c | 18 ++++++++++-------- util.c | 29 +++++++++++++++++++++++++++++ 6 files changed, 69 insertions(+), 15 deletions(-) diff --git a/Detail.c b/Detail.c index 6836f094..704fffe1 100644 --- a/Detail.c +++ b/Detail.c @@ -132,6 +132,7 @@ int Detail(char *dev, int brief, int test) if (brief) printf("ARRAY %s level=%s num-devices=%d", dev, c?c:"-unknown-",array.raid_disks ); else { + mdu_bitmap_file_t bmf; unsigned long array_size; unsigned long long larray_size; struct mdstat_ent *ms = mdstat_read(0); @@ -176,6 +177,12 @@ int Detail(char *dev, int brief, int test) printf(" Persistence : Superblock is %spersistent\n", array.not_persistent?"not ":""); printf("\n"); + if (ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 && + bmf.pathname[0]) { + printf(" Intent Bitmap : %s\n", bmf.pathname); + printf("\n"); + } else if (array.state & (1< (0x7fffffffULL<<9)) { + /* Array is big enough that we cannot trust array.size + * try other approaches + */ + bitmapsize = get_component_size(fd); + } +#endif + if (bitmapsize == 0) { + fprintf(stderr, Name ": Cannot reliably determine size of array to create bitmap - sorry.\n"); + return 1; + } + if (array.level == 10) { int ncopies = (array.layout&255)*(array.layout>>8); bitmapsize = bitmapsize * array.raid_disks / ncopies; @@ -343,13 +358,13 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int fprintf(stderr, Name ": cannot find UUID for array!\n"); return 1; } - if (CreateBitmap(file, 0, (char*)uuid, chunk, + if (CreateBitmap(file, force, (char*)uuid, chunk, delay, write_behind, bitmapsize, major)) { return 1; } bitmap_fd = open(file, O_RDWR); if (bitmap_fd < 0) { - fprintf(stderr, Name ": weird: %s cannot be openned\n", + fprintf(stderr, Name ": weird: %s cannot be opened\n", file); return 1; } diff --git a/mdadm.c b/mdadm.c index 4174f926..f5f64b56 100644 --- a/mdadm.c +++ b/mdadm.c @@ -1160,7 +1160,7 @@ int main(int argc, char *argv[]) else if (bitmap_file) { if (delay == 0) delay = DEFAULT_BITMAP_DELAY; rv = Grow_addbitmap(devlist->devname, mdfd, bitmap_file, - bitmap_chunk, delay, write_behind); + bitmap_chunk, delay, write_behind, force); } else fprintf(stderr, Name ": no changes to --grow\n"); break; diff --git a/mdadm.h b/mdadm.h index f03454df..d93117f1 100644 --- a/mdadm.h +++ b/mdadm.h @@ -236,7 +236,7 @@ extern int Manage_reconfig(char *devname, int fd, int layout); extern int Manage_subdevs(char *devname, int fd, mddev_dev_t devlist, int verbose); extern int Grow_Add_device(char *devname, int fd, char *newdev); -extern int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int write_behind); +extern int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int write_behind, int force); extern int Assemble(struct supertype *st, char *mddev, int mdfd, @@ -305,6 +305,7 @@ extern unsigned long calc_csum(void *super, int bytes); extern int enough(int level, int raid_disks, int layout, char *avail, int avail_disks); extern int ask(char *mesg); +extern unsigned long long get_component_size(int fd); extern char *human_size(long long bytes); diff --git a/super1.c b/super1.c index a1e0cbe1..62494a6e 100644 --- a/super1.c +++ b/super1.c @@ -195,7 +195,8 @@ static void examine_super1(void *sbv) printf("\n"); if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) { printf("Internal Bitmap : %ld sectors from superblock\n", - __le32_to_cpu(sb->bitmap_offset)); + (long)__le32_to_cpu(sb->bitmap_offset)); + } if (sb->feature_map & __le32_to_cpu(MD_FEATURE_RESHAPE_ACTIVE)) { printf(" Reshape pos'n : %llu%s\n", __le64_to_cpu(sb->reshape_position)/2, human_size(__le64_to_cpu(sb->reshape_position)<<9)); @@ -621,8 +622,8 @@ static int write_init_super1(struct supertype *st, void *sbv, int rfd; int rv; - unsigned long size; - unsigned long long dsize; + unsigned long size, space; + unsigned long long dsize, array_size; long long sb_offset; @@ -685,6 +686,7 @@ static int write_init_super1(struct supertype *st, void *sbv, * Depending on the array size, we might leave extra space * for a bitmap. */ + array_size = __le64_to_cpu(sb->size); switch(st->minor_version) { case 0: sb_offset = dsize; @@ -1016,14 +1018,14 @@ add_internal_bitmap1(struct supertype *st, void *sbv, void locate_bitmap1(struct supertype *st, int fd, void *sbv) { unsigned long long offset; - struct mdp_superblock_1 *sb; + struct mdp_superblock_1 *sb = NULL; - if (!sbv) - if (st->ss->load_super(st, fd, sbv, NULL)) + if (sbv) + sb = sbv; + else + if (st->ss->load_super(st, fd, (void **)&sb, NULL)) return; /* no error I hope... */ - sb = sbv; - offset = __le64_to_cpu(sb->super_offset); offset += (long) __le32_to_cpu(sb->bitmap_offset); if (!sbv) diff --git a/util.c b/util.c index 9204d531..b3dbca47 100644 --- a/util.c +++ b/util.c @@ -676,6 +676,35 @@ struct supertype *guess_super(int fd) return NULL; } +unsigned long long get_component_size(int fd) +{ + /* Find out the component size of the array. + * We cannot trust GET_ARRAY_INFO ioctl as it's + * size field is only 32bits. + * So look in /sys/block/mdXXX/md/component_size + */ + struct stat stb; + char fname[50]; + int n; + if (fstat(fd, &stb)) return 0; + if (major(stb.st_rdev) == 9) + sprintf(fname, "/sys/block/md%d/component_size", + minor(stb.st_rdev)); + else + sprintf(fname, "/sys/block/md_d%d/component_size", + minor(stb.st_rdev)/16); + fd = open(fname, O_RDONLY); + if (fd < 0) + return 0; + n = read(fd, fname, sizeof(fname)); + close(fd); + if (n == sizeof(fname)) + return 0; + fname[n] = 0; + return strtoull(fname, NULL, 10); +} + + #ifdef __TINYC__ /* tinyc doesn't optimize this check in ioctl.h out ... */ unsigned int __invalid_size_argument_for_IOC = 0; -- 2.39.2