]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Create n bitmaps for clustered mode
authorGuoqing Jiang <gqjiang@suse.com>
Wed, 10 Jun 2015 05:42:04 +0000 (13:42 +0800)
committerNeilBrown <neilb@suse.de>
Tue, 16 Jun 2015 21:54:03 +0000 (07:54 +1000)
For a clustered MD, create bitmaps equal to number of nodes so
each node has an independent bitmap.

Only the first bitmap is has the bits set so that the first node
that assembles the device also performs the sync.

The bitmaps are aligned to 4k boundaries.

On-disk format:

0                    4k                     8k                    12k
-------------------------------------------------------------------
| idle                | md super            | bm super [0] + bits |
| bm bits[0, contd]   | bm super[1] + bits  | bm bits[1, contd]   |
| bm super[2] + bits  | bm bits [2, contd]  | bm super[3] + bits  |
| bm bits [3, contd]  |                     |                     |

Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
Signed-off-by: Guoqing Jiang <gqjiang@suse.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Create.c
bitmap.c
bitmap.h
mdadm.8.in
super1.c

index ef28da0c4a4cb9c2e600d5698fb0f9c536f0d15a..19f3054a5209cb76681b7b034454aa7d3cce5edc 100644 (file)
--- a/Create.c
+++ b/Create.c
@@ -750,7 +750,8 @@ int Create(struct supertype *st, char *mddev,
 #endif
        }
 
-       if (s->bitmap_file && strcmp(s->bitmap_file, "internal")==0) {
+       if (s->bitmap_file && (strcmp(s->bitmap_file, "internal")==0 ||
+                              strcmp(s->bitmap_file, "clustered")==0)) {
                if ((vers%100) < 2) {
                        pr_err("internal bitmaps not supported by this kernel.\n");
                        goto abort_locked;
index b1d54a6f7a54feec4a9219fb6fc9b157e8f1b79f..920033ad38893e56e18933967871e255cf485c43 100644 (file)
--- a/bitmap.c
+++ b/bitmap.c
@@ -32,6 +32,8 @@ inline void sb_le_to_cpu(bitmap_super_t *sb)
        sb->daemon_sleep = __le32_to_cpu(sb->daemon_sleep);
        sb->sync_size = __le64_to_cpu(sb->sync_size);
        sb->write_behind = __le32_to_cpu(sb->write_behind);
+       sb->nodes = __le32_to_cpu(sb->nodes);
+       sb->sectors_reserved = __le32_to_cpu(sb->sectors_reserved);
 }
 
 inline void sb_cpu_to_le(bitmap_super_t *sb)
index c8725a30eb338602ea37e56fe1a2dc6a4c731a07..adbf0b4b48bc097ee3df7e3eb6de02715e995e19 100644 (file)
--- a/bitmap.h
+++ b/bitmap.h
@@ -154,8 +154,11 @@ typedef struct bitmap_super_s {
        __u32 chunksize;    /* 52  the bitmap chunk size in bytes */
        __u32 daemon_sleep; /* 56  seconds between disk flushes */
        __u32 write_behind; /* 60  number of outstanding write-behind writes */
-
-       __u8  pad[256 - 64]; /* set to zero */
+       __u32 sectors_reserved; /* 64 number of 512-byte sectors that are
+                                * reserved for the bitmap. */
+       __u32 nodes;        /* 68 the maximum number of nodes in cluster. */
+       __u8 cluster_name[64]; /* 72 cluster name to which this md belongs */
+       __u8  pad[256 - 136]; /* set to zero */
 } bitmap_super_t;
 
 /* notes:
index b4a21d95072d8df59ea2c279d78f6be2357013e0..2a89458dfd027cc6711331f0601287edd01f6967 100644 (file)
@@ -694,7 +694,12 @@ and so is replicated on all devices.  If the word
 .B "none"
 is given with
 .B \-\-grow
-mode, then any bitmap that is present is removed.
+mode, then any bitmap that is present is removed. If the word
+.B "clustered"
+is given, the array is created for a clustered environment. One bitmap
+is created for each node as defined by the
+.B \-\-nodes
+parameter and are stored internally.
 
 To help catch typing errors, the filename must contain at least one
 slash ('/') if it is a real file (not 'internal' or 'none').
index f0508fe730333cc858b41b4ce66cbc3f8bc4a432..7928a3d2853bfd39df188d62e9aab61ec70f2c22 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -2177,6 +2177,7 @@ static int write_bitmap1(struct supertype *st, int fd)
        void *buf;
        int towrite, n;
        struct align_fd afd;
+       unsigned int i = 0;
 
        init_afd(&afd, fd);
 
@@ -2185,27 +2186,41 @@ static int write_bitmap1(struct supertype *st, int fd)
        if (posix_memalign(&buf, 4096, 4096))
                return -ENOMEM;
 
-       memset(buf, 0xff, 4096);
-       memcpy(buf, (char *)bms, sizeof(bitmap_super_t));
-
-       towrite = __le64_to_cpu(bms->sync_size) / (__le32_to_cpu(bms->chunksize)>>9);
-       towrite = (towrite+7) >> 3; /* bits to bytes */
-       towrite += sizeof(bitmap_super_t);
-       towrite = ROUND_UP(towrite, 512);
-       while (towrite > 0) {
-               n = towrite;
-               if (n > 4096)
-                       n = 4096;
-               n = awrite(&afd, buf, n);
-               if (n > 0)
-                       towrite -= n;
+       do {
+               /* Only the bitmap[0] should resync
+                * whole device on initial assembly
+                */
+               if (i)
+                       memset(buf, 0x00, 4096);
                else
+                       memset(buf, 0xff, 4096);
+               memcpy(buf, (char *)bms, sizeof(bitmap_super_t));
+
+               towrite = __le64_to_cpu(bms->sync_size) / (__le32_to_cpu(bms->chunksize)>>9);
+               towrite = (towrite+7) >> 3; /* bits to bytes */
+               towrite += sizeof(bitmap_super_t);
+               /* we need the bitmaps to be at 4k boundary */
+               towrite = ROUND_UP(towrite, 4096);
+               while (towrite > 0) {
+                       n = towrite;
+                       if (n > 4096)
+                               n = 4096;
+                       n = awrite(&afd, buf, n);
+                       if (n > 0)
+                               towrite -= n;
+                       else
+                               break;
+                       if (i)
+                               memset(buf, 0x00, 4096);
+                       else
+                               memset(buf, 0xff, 4096);
+               }
+               fsync(fd);
+               if (towrite) {
+                       rv = -2;
                        break;
-               memset(buf, 0xff, 4096);
-       }
-       fsync(fd);
-       if (towrite)
-               rv = -2;
+               }
+       } while (++i < __le32_to_cpu(bms->nodes));
 
        free(buf);
        return rv;