From f5e166fee3be2ccdce3def28edc7a771fc84df9f Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Tue, 7 Jun 2005 23:03:46 +0000 Subject: [PATCH] Support --grow --bitmap=internal Adding a filebased bitmap is not yet supported, and this code is still under development. Signed-off-by: Neil Brown --- Grow.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Manage.c | 4 +++ mdadm.c | 16 ++++++++--- mdadm.h | 2 ++ 4 files changed, 101 insertions(+), 4 deletions(-) diff --git a/Grow.c b/Grow.c index 41c7dc0..817a17a 100644 --- a/Grow.c +++ b/Grow.c @@ -191,3 +191,86 @@ int Grow_Add_device(char *devname, int fd, char *newdev) return 0; } + +int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay) +{ + /* + * First check that array doesn't have a bitmap + * Then create the bitmap + * Then add it + * + * For internal bitmaps, we need to check the version, + * find all the active devices, and write the bitmap block + * to all devices + */ + mdu_bitmap_file_t bmf; + mdu_array_info_t array; + struct supertype *st; + + if (ioctl(fd, GET_BITMAP_FILE, &bmf) != 0) { + if (errno == ENOMEM) + fprintf(stderr, Name ": Memory allocation failure.\n"); + else + fprintf(stderr, Name ": bitmaps not supported by this kernel.\n"); + return 1; + } + if (bmf.pathname[0]) { + fprintf(stderr, Name ": %s already has a bitmap (%s)\n", + devname, bmf.pathname); + return 1; + } + if (ioctl(fd, GET_ARRAY_INFO, &array) != 0) { + fprintf(stderr, Name ": cannot get array status for %s\n", devname); + return 1; + } + if (array.state & (1<ss->load_super(st, fd2, &super, NULL)==0) { + st->ss->add_internal_bitmap(super, + chunk, delay, + array.size); + st->ss->write_bitmap(st, fd2, super); + } + close(fd2); + } + } + array.state |= (1<= 0) + (raiddisks != 0) + (layout != UnSet) > 1) { - fprintf(stderr, Name ": can change at most one of size, raiddisks, and layout\n"); + } else if ((size >= 0) + (raiddisks != 0) + (layout != UnSet) + (bitmap_file != NULL)> 1) { + fprintf(stderr, Name ": can change at most one of size, raiddisks, bitmap, and layout\n"); rv = 1; break; } else if (layout != UnSet) rv = Manage_reconfig(devlist->devname, mdfd, layout); else if (size >= 0 || raiddisks) rv = Manage_resize(devlist->devname, mdfd, size, raiddisks); - else + else if (bitmap_file) { + if (delay == 0) delay = DEFAULT_BITMAP_DELAY; + rv = Grow_addbitmap(devlist->devname, mdfd, bitmap_file, + bitmap_chunk, delay); + } else fprintf(stderr, Name ": no changes to --grow\n"); break; } diff --git a/mdadm.h b/mdadm.h index fb1773d..3f8424e 100644 --- a/mdadm.h +++ b/mdadm.h @@ -187,6 +187,7 @@ extern struct superswitch { __u64 (*avail_size)(__u64 size); int (*add_internal_bitmap)(void *sbv, int chunk, int delay, unsigned long long size); void (*locate_bitmap)(struct supertype *st, int fd); + int (*write_bitmap)(struct supertype *st, int fd, void *sbv); int major; } super0, super1, *superlist[]; @@ -206,6 +207,7 @@ extern int Manage_reconfig(char *devname, int fd, int layout); extern int Manage_subdevs(char *devname, int fd, mddev_dev_t devlist); 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); extern int Assemble(struct supertype *st, char *mddev, int mdfd,