]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Support bitmaps with raid10
authorNeil Brown <neilb@suse.de>
Tue, 22 Nov 2005 03:37:14 +0000 (03:37 +0000)
committerNeil Brown <neilb@suse.de>
Tue, 22 Nov 2005 03:37:14 +0000 (03:37 +0000)
And a couple of other little things

Signed-off-by: Neil Brown <neilb@suse.de>
Build.c
ChangeLog
Create.c
Grow.c
bitmap.c
mdadm.8
mdadm.c
mdadm.h
super0.c
super1.c

diff --git a/Build.c b/Build.c
index 2fcc47e153f2d3c29c428cf308d27fe966a747f2..bb53a11cfbdddb6fd5551defbf1dd69736d6f0bd 100644 (file)
--- a/Build.c
+++ b/Build.c
@@ -58,6 +58,7 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
        mddev_dev_t dv;
        int bitmap_fd;
        unsigned long long size = ~0ULL;
+       unsigned long long bitmapsize;
 
        /* scan all devices, make sure they really are block devices */
        for (dv = devlist; dv; dv=dv->next) {
@@ -215,8 +216,9 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
                                                "  between different architectured.  Consider upgrading the Linux kernel.\n");
 #endif
                                }
+                               bitmapsize = size>>9; /* FIXME wrong for RAID10 */
                                if (CreateBitmap(bitmap_file, 1, NULL, bitmap_chunk,
-                                                delay, write_behind, size>>9, major)) {
+                                                delay, write_behind, bitmapsize, major)) {
                                        return 1;
                                }
                                bitmap_fd = open(bitmap_file, O_RDWR);
index cb66fc48a1459bf000d4f0b2410cece3b481c5f7..824400e9ee5a726ba6f536b999e8c63df7237c2b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,10 @@
 Changes Prior to this release
+    -   Assorted bug fixes
+    -   Support write-intent-bitmaps on raid10
+    -   Support little-endian (Rather than hostendian) bitmaps.
+    -   Return correct error code from 'mdadm -S'
+
+Changes Prior to 2.1 release
     -   Fix assembling of raid10 array when devices are missing.
          mdadm now correctly detects if a array is workable or not
          depending on which devices are present, and so will correctly
index 148ab0e7bb15eb826bf4fd05fdfbca4ed52dce49..0fd38a5883f94a2b1e98a32105a34323c2afe298 100644 (file)
--- a/Create.c
+++ b/Create.c
@@ -69,6 +69,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
        int vers;
        int rv;
        int bitmap_fd;
+       unsigned long long bitmapsize;
 
        mdu_array_info_t array;
        int major = BITMAP_MAJOR_HI;
@@ -322,6 +323,17 @@ int Create(struct supertype *st, char *mddev, int mdfd,
        else
                array.state = 0; /* not clean, but no errors */
 
+       if (level == 10) {
+               /* for raid10, the bitmap size is the capacity of the array,
+                * which is array.size * raid_disks / ncopies;
+                * .. but convert to sectors.
+                */
+               int ncopies = (layout>>8) * (layout & 255);
+               bitmapsize = (unsigned long long)array.size * raiddisks / ncopies * 2;
+               printf("bms=%llu as=%d rd=%d nc=%d\n", bitmapsize, array.size, raiddisks, ncopies);
+       } else
+               bitmapsize = (unsigned long long)array.size * 2;
+
        /* There is lots of redundancy in these disk counts,
         * raid_disks is the most meaningful value
         *          it describes the geometry of the array
@@ -365,7 +377,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                        return 1;
                }
                if (!st->ss->add_internal_bitmap(st, super, bitmap_chunk, delay, write_behind,
-                                                &array.size, 1, major)) {
+                                                bitmapsize, 1, major)) {
                        fprintf(stderr, Name ": Given bitmap chunk size not supported.\n");
                        return 1;
                }
@@ -397,7 +409,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                st->ss->uuid_from_super(uuid, super);
                if (CreateBitmap(bitmap_file, force, (char*)uuid, bitmap_chunk,
                                 delay, write_behind,
-                                array.size*2ULL /* FIXME wrong for raid10 */,
+                                bitmapsize,
                                 major)) {
                        return 1;
                }
diff --git a/Grow.c b/Grow.c
index aa14638a1c14fb6a44df267ca99758e49d6f35ab..d669a4e2465495a851ca1acb65c771ceac91f72d 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -208,6 +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;
 
        if (vers < 9003) {
                major = BITMAP_MAJOR_HOSTENDIAN;
@@ -254,6 +255,12 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
                        devname);
                return 1;
        }
+       bitmapsize = array.size * 2;
+       if (array.level == 10) {
+               int ncopies = (array.layout&255)*(array.layout>>8);
+               bitmapsize = bitmapsize * array.raid_disks / ncopies;
+       }
+
        st = super_by_version(array.major_version, array.minor_version);
        if (!st) {
                fprintf(stderr, Name ": Cannot understand version %d.%d\n",
@@ -285,7 +292,7 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
                                if (st->ss->load_super(st, fd2, &super, NULL)==0) {
                                        st->ss->add_internal_bitmap(st, super,
                                                                    chunk, delay, write_behind,
-                                                                   &array.size, 0, major);
+                                                                   bitmapsize, 0, major);
                                        st->ss->write_bitmap(st, fd2, super);
                                }
                                close(fd2);
@@ -332,7 +339,7 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
                        return 1;
                }
                if (CreateBitmap(file, 0, (char*)uuid, chunk,
-                                delay, write_behind, array.size*2ULL, major)) {
+                                delay, write_behind, bitmapsize, major)) {
                        return 1;
                }
                bitmap_fd = open(file, O_RDWR);
index bc29768ff364225f61bf8708808627e6d8c8588e..bdfd40556535f35282d83db7b6a08b187436c131 100644 (file)
--- a/bitmap.c
+++ b/bitmap.c
@@ -126,7 +126,7 @@ bitmap_info_t *bitmap_fd_read(int fd, int brief)
 
        info = malloc(sizeof(*info));
        if (info == NULL) {
-               fprintf(stderr, Name ": failed to allocate %d bytes\n",
+               fprintf(stderr, Name ": failed to allocate %zd bytes\n",
                                sizeof(*info));
                return NULL;
        }
@@ -168,7 +168,8 @@ bitmap_info_t *bitmap_fd_read(int fd, int brief)
 
        if (read_bits < total_bits) { /* file truncated... */
                fprintf(stderr, Name ": WARNING: bitmap file is not large "
-                       "enough for array size %llu!\n\n", info->sb.sync_size);
+                       "enough for array size %llu!\n\n",
+                       (unsigned long long)info->sb.sync_size);
                total_bits = read_bits;
        }
 out:
@@ -263,8 +264,8 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
                                        *(__u32 *)(sb->uuid+8),
                                        *(__u32 *)(sb->uuid+12));
        }
-       printf("          Events : %llu\n", sb->events);
-       printf("  Events Cleared : %llu\n", sb->events_cleared);
+       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));
        printf("       Chunksize : %s\n", human_chunksize(sb->chunksize));
        printf("          Daemon : %ds flush period\n", sb->daemon_sleep);
@@ -273,7 +274,7 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
        else
                sprintf(buf, "Normal");
        printf("      Write Mode : %s\n", buf);
-       printf("       Sync Size : %llu%s\n", sb->sync_size/2,
+       printf("       Sync Size : %llu%s\n", (unsigned long long)sb->sync_size/2,
                                        human_size(sb->sync_size * 512));
        if (brief)
                goto free_info;
diff --git a/mdadm.8 b/mdadm.8
index aa39a2365dd73d3274a63de1b663605e1f9ecd89..45326f62d02159e679611615e41075d034c04324 100644 (file)
--- a/mdadm.8
+++ b/mdadm.8
@@ -516,8 +516,8 @@ will not try to be so clever.
 Instruct mdadm to create the device file if needed, possibly allocating
 an unused minor number.  "md" causes a non-partitionable array
 to be used.  "mdp", "part" or "p" causes a partitionable array (2.6 and
-later) to be used.  "yes" requires the named md device to have a
-'standard' format, and the type and minor number will be determined
+later) to be used.  "yes" requires the named md device to haveo
+'standard' format, and the type and minor number will be determined
 from this.  See DEVICE NAMES below.
 
 The argument can also come immediately after
diff --git a/mdadm.c b/mdadm.c
index ad3d1517ddeedb6b65810d6a529055d49f4de82e..8af61e9627df5e5ea241e0f5ab30e8a74ee82935 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -1059,7 +1059,7 @@ int main(int argc, char *argv[])
                                                        put_md_name(name);
                                                }
                                        } while (!last && err);
-                                       if (err) rv |= 1
+                                       if (err) rv |= 1;
                                } else {
                                        fprintf(stderr, Name ": No devices given.\n");
                                        exit(2);
diff --git a/mdadm.h b/mdadm.h
index 85a853b6e65cc799d4867a3e6f48d0f70642622c..2abb0f0c1297ecac79dd4394a415dcf45c5375cc 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -190,7 +190,8 @@ extern struct superswitch {
        int (*load_super)(struct supertype *st, int fd, void **sbp, char *devname);
        struct supertype * (*match_metadata_desc)(char *arg);
        __u64 (*avail_size)(struct supertype *st, __u64 size);
-       int (*add_internal_bitmap)(struct supertype *st, void *sbv, int chunk, int delay, int write_behind, int *sizep, int may_change, int major);
+       int (*add_internal_bitmap)(struct supertype *st, void *sbv, int chunk, int delay, int write_behind,
+                                  unsigned long long size, int may_change, int major);
        void (*locate_bitmap)(struct supertype *st, int fd, void *sbv);
        int (*write_bitmap)(struct supertype *st, int fd, void *sbv);
        int major;
index 4ab40af9533225da0b0bfd0e69056003e14f7d40..6b8c2081799db396dbb3e477cc87572f676e0aff 100644 (file)
--- a/super0.c
+++ b/super0.c
@@ -657,7 +657,7 @@ static __u64 avail_size0(struct supertype *st, __u64 devsize)
        return MD_NEW_SIZE_SECTORS(devsize);
 }
 
-static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int delay, int write_behind, int *sizep, int may_change, int major)
+static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int delay, int write_behind, unsigned long long size, int may_change, int major)
 {
        /*
         * The bitmap comes immediately after the superblock and must be 60K in size
@@ -665,7 +665,6 @@ static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int
         *
         * size is in K,  chunk is in bytes !!!
         */
-       unsigned long long size = *sizep;
        unsigned long long bits;
        unsigned long long max_bits = 60*1024*8;
        unsigned long long min_chunk;
@@ -674,7 +673,7 @@ static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int
 
        
        min_chunk = 4096; /* sub-page chunks don't work yet.. */
-       bits = (size * 1024)/ min_chunk +1;
+       bits = (size * 512)/ min_chunk +1;
        while (bits > max_bits) {
                min_chunk *= 2;
                bits = (bits+1)/2;
@@ -692,7 +691,7 @@ static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int
        uuid_from_super0((int*)bms->uuid, sb);
        bms->chunksize = __cpu_to_le32(chunk);
        bms->daemon_sleep = __cpu_to_le32(delay);
-       bms->sync_size = __cpu_to_le64(size<<1);
+       bms->sync_size = __cpu_to_le64(size);
        bms->write_behind = __cpu_to_le32(write_behind);
 
 
index 46ce82d92bb891d08b7e9777646123f5cad61dc5..a0a3a682d85640618fea123ee472080b9d0acdeb 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -842,7 +842,7 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize)
 
 static int
 add_internal_bitmap1(struct supertype *st, void *sbv,
-                    int chunk, int delay, int write_behind, int *sizep, int may_change, int major)
+                    int chunk, int delay, int write_behind, unsigned long long size, int may_change, int major)
 {
        /*
         * If not may_change, then this is a 'Grow', and the bitmap
@@ -851,10 +851,9 @@ add_internal_bitmap1(struct supertype *st, void *sbv,
         * before the superblock if we like, or may move the start.
         * For now, just squeeze the bitmap into 3k and don't change anything.
         *
-        * size is in K,  chunk is in bytes !!!
+        * size is in sectors,  chunk is in bytes !!!
         */
 
-       unsigned long long size = *sizep;
        unsigned long long bits;
        unsigned long long max_bits = (3*512 - sizeof(bitmap_super_t)) * 8;
        unsigned long long min_chunk;
@@ -868,7 +867,7 @@ add_internal_bitmap1(struct supertype *st, void *sbv,
 
 
        min_chunk = 4096; /* sub-page chunks don't work yet.. */
-       bits = (size*1024)/min_chunk +1;
+       bits = (size*512)/min_chunk +1;
        while (bits > max_bits) {
                min_chunk *= 2;
                bits = (bits+1)/2;
@@ -887,7 +886,7 @@ add_internal_bitmap1(struct supertype *st, void *sbv,
        uuid_from_super1((int*)bms->uuid, sb);
        bms->chunksize = __cpu_to_le32(chunk);
        bms->daemon_sleep = __cpu_to_le32(delay);
-       bms->sync_size = __cpu_to_le64(size<<1);
+       bms->sync_size = __cpu_to_le64(size);
        bms->write_behind = __cpu_to_le32(write_behind);
 
        return 1;