]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Stuff like..
authorNeil Brown <neilb@suse.de>
Mon, 30 Jan 2006 23:23:45 +0000 (23:23 +0000)
committerNeil Brown <neilb@suse.de>
Mon, 30 Jan 2006 23:23:45 +0000 (23:23 +0000)
- 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 <neilb@suse.de>
Detail.c
Grow.c
mdadm.c
mdadm.h
super1.c
util.c

index 6836f09495d0e0e0485c196e27830a7977fa6004..704fffe14e736b3d9ab2c93cf6412f799cd4615d 100644 (file)
--- 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<<MD_SB_BITMAP_PRESENT))
+                       printf("  Intent Bitmap : Internal\n\n");
                atime = array.utime;
                printf("    Update Time : %.24s\n", ctime(&atime));
                printf("          State : %s%s%s\n",
diff --git a/Grow.c b/Grow.c
index e218eb1ec39f1ccbe54354e8f412134068a1b99b..9e8e217293f09b41b04259b5190b4edb2dd7a6c3 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -192,7 +192,7 @@ 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, int write_behind)
+int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int write_behind, int force)
 {
        /*
         * First check that array doesn't have a bitmap
@@ -208,7 +208,7 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
        struct supertype *st;
        int major = BITMAP_MAJOR_HI;
        int vers = md_get_version(fd);
-       unsigned long long bitmapsize;
+       unsigned long long bitmapsize, array_size;
 
        if (vers < 9003) {
                major = BITMAP_MAJOR_HOSTENDIAN;
@@ -255,7 +255,22 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
                        devname);
                return 1;
        }
-       bitmapsize = array.size * 2;
+       bitmapsize = array.size;
+       bitmapsize <<= 1;
+#ifdef BLKGETSIZE64
+       if (ioctl(fd, BLKGETSIZE64, &array_size) == 0 &&
+           array_size > (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 4174f9262d3e02489673f137e48737b5aabe014f..f5f64b561b577bb56072a9a2fe74a14be34a9e26 100644 (file)
--- 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 f03454df7afc039dffc7372c0a1b029f1b0ab01b..d93117f1c44af8398b2a6aeed6307c9061b8ea91 100644 (file)
--- 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);
index a1e0cbe17cd129da53df49a4cbb047d96d5b8e3a..62494a6e749c4f4634f5ed8764b1de96b2bfb7dc 100644 (file)
--- 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 9204d531f86a569def9fc20fee72550d1b1f93d2..b3dbca47f145330585fefc5a155613b2c39e292e 100644 (file)
--- 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;