]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Merge https://github.com/makelinux/mdadm
authorNeilBrown <neilb@suse.com>
Mon, 21 Dec 2015 01:57:06 +0000 (12:57 +1100)
committerNeilBrown <neilb@suse.com>
Mon, 21 Dec 2015 01:57:06 +0000 (12:57 +1100)
Fixes https://github.com/neilbrown/mdadm/issues/17

16 files changed:
Assemble.c
Detail.c
Grow.c [changed mode: 0644->0755]
Incremental.c
Makefile
Manage.c
ReadMe.c
bitmap.c
crc32c.c [new file with mode: 0644]
md_u.h
mdadm.c
mdadm.h [changed mode: 0644->0755]
super0.c
super1.c
sysfs.c
util.c

index 90c9918416db7bb0a4ef6c920da073c7971df8f3..a7cd16386d4bc641f6c6484c7280d0d8ae509fe6 100644 (file)
@@ -1302,6 +1302,7 @@ int Assemble(struct supertype *st, char *mddev,
        int bestcnt = 0;
        int devcnt;
        unsigned int okcnt, sparecnt, rebuilding_cnt, replcnt, journalcnt;
+       int journal_clean = 0;
        int i;
        int was_forced = 0;
        int most_recent = 0;
@@ -1592,7 +1593,7 @@ try_again:
                        ) {
                        devices[j].uptodate = 1;
                        if (devices[j].i.disk.state & (1<<MD_DISK_JOURNAL))
-                               content->journal_clean = 1;
+                               journal_clean = 1;
                        if (i < content->array.raid_disks * 2) {
                                if (devices[j].i.recovery_start == MaxSector ||
                                    (content->reshape_active &&
@@ -1664,6 +1665,8 @@ try_again:
 #ifndef MDASSEMBLE
        sysfs_init(content, mdfd, NULL);
 #endif
+       /* after reload context, store journal_clean in context */
+       content->journal_clean = journal_clean;
        for (i=0; i<bestcnt; i++) {
                int j = best[i];
                unsigned int desired_state;
index 7eb6bd5efd17b9782f82c44f3706b2e1fe776e4a..5bd2dc641ff7d9618f3b500930e7c679c080eb94 100644 (file)
--- a/Detail.c
+++ b/Detail.c
@@ -299,7 +299,8 @@ int Detail(char *dev, struct context *c)
        for (d = 0; d < max_disks * 2; d++) {
                disks[d].state = (1<<MD_DISK_REMOVED);
                disks[d].major = disks[d].minor = 0;
-               disks[d].number = disks[d].raid_disk = d;
+               disks[d].number = -1;
+               disks[d].raid_disk = d/2;
        }
 
        next = array.raid_disks*2;
@@ -623,6 +624,9 @@ This is pretty boring
                        else if (disk.raid_disk < 0)
                                printf("   %5d   %5d    %5d        -     ",
                                       disk.number, disk.major, disk.minor);
+                       else if (disk.number < 0)
+                               printf("       -   %5d    %5d    %5d     ",
+                                      disk.major, disk.minor, disk.raid_disk);
                        else
                                printf("   %5d   %5d    %5d    %5d     ",
                                       disk.number, disk.major, disk.minor, disk.raid_disk);
diff --git a/Grow.c b/Grow.c
old mode 100644 (file)
new mode 100755 (executable)
index 80d7b22..6dfb9c9
--- a/Grow.c
+++ b/Grow.c
@@ -328,12 +328,15 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
                if (strcmp(s->bitmap_file, "none")==0) {
                        array.state &= ~(1<<MD_SB_BITMAP_PRESENT);
                        if (ioctl(fd, SET_ARRAY_INFO, &array)!= 0) {
-                               pr_err("failed to remove internal bitmap.\n");
+                               if (array.state & (1<<MD_SB_CLUSTERED))
+                                       pr_err("failed to remove clustered bitmap.\n");
+                               else
+                                       pr_err("failed to remove internal bitmap.\n");
                                return 1;
                        }
                        return 0;
                }
-               pr_err("%s bitmap already present on %s\n", s->bitmap_file, devname);
+               pr_err("bitmap already present on %s\n", devname);
                return 1;
        }
 
@@ -4503,8 +4506,8 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
                 * sometimes they aren't... So allow considerable flexability in matching, and allow
                 * this test to be overridden by an environment variable.
                 */
-               if (info->array.utime > (int)__le64_to_cpu(bsb.mtime) + 2*60*60 ||
-                   info->array.utime < (int)__le64_to_cpu(bsb.mtime) - 10*60) {
+               if(time_after(info->array.utime, (unsigned int)__le64_to_cpu(bsb.mtime) + 2*60*60) ||
+                  time_before(info->array.utime, (unsigned int)__le64_to_cpu(bsb.mtime) - 10*60)) {
                        if (check_env("MDADM_GROW_ALLOW_OLD")) {
                                pr_err("accepting backup with timestamp %lu for array with timestamp %lu\n",
                                        (unsigned long)__le64_to_cpu(bsb.mtime),
index 781d27defbfda382970bedec0506e824c27cb4d1..7afa7d77485a5bca21bc97e389bbf96e9760b273 100644 (file)
@@ -444,6 +444,10 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
                /* add disk needs to know about containers */
                if (st->ss->external)
                        sra->array.level = LEVEL_CONTAINER;
+
+               if (info.array.state & (1 << MD_SB_CLUSTERED))
+                       info.disk.state |= (1 << MD_DISK_CLUSTER_ADD);
+
                err = add_disk(mdfd, st, sra, &info);
                if (err < 0 && errno == EBUSY) {
                        /* could be another device present with the same
index 544e6cbb7875d1b41a61b7605f868b50ae8a3aa9..fde2e63af77d3175e123828f7f02f87cc9042bb4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -133,7 +133,7 @@ OBJS =  mdadm.o config.o policy.o mdstat.o  ReadMe.o util.o maps.o lib.o \
        mdopen.o super0.o super1.o super-ddf.o super-intel.o bitmap.o \
        super-mbr.o super-gpt.o \
        restripe.o sysfs.o sha1.o mapfile.o crc32.o sg_io.o msg.o xmalloc.o \
-       platform-intel.o probe_roms.o
+       platform-intel.o probe_roms.o crc32c.o
 
 CHECK_OBJS = restripe.o sysfs.o maps.o lib.o xmalloc.o dlink.o
 
index 2df303d27cd1c75ba8fe4faf221953e1edae8233..4540facdeef62b78105cd89d702736fd73dea8ca 100644 (file)
--- a/Manage.c
+++ b/Manage.c
@@ -825,7 +825,8 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
                }
 
                /* Make sure device is large enough */
-               if (tst->sb &&
+               if (dv->disposition != 'j' &&  /* skip size check for Journal */
+                   tst->sb &&
                    tst->ss->avail_size(tst, ldsize/512, INVALID_SECTORS) <
                    array_size) {
                        if (dv->disposition == 'M')
@@ -929,8 +930,31 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
        else
                disc.number = raid_slot;
        disc.state = 0;
+
+       /* only add journal to array that supports journaling */
+       if (dv->disposition == 'j') {
+               struct mdinfo mdi;
+               struct mdinfo *mdp;
+
+               mdp = sysfs_read(fd, NULL, GET_ARRAY_STATE);
+
+               if (strncmp(mdp->sysfs_array_state, "readonly", 8) != 0) {
+                       pr_err("%s is not readonly, cannot add journal.\n", devname);
+                       return -1;
+               }
+
+               tst->ss->getinfo_super(tst, &mdi, NULL);
+               if (mdi.journal_device_required == 0) {
+                       pr_err("%s does not support journal device.\n", devname);
+                       return -1;
+               }
+               disc.raid_disk = array->raid_disks;
+       }
+
        if (array->not_persistent==0) {
                int dfd;
+               if (dv->disposition == 'j')
+                       disc.state |= (1 << MD_DISK_JOURNAL) | (1 << MD_DISK_SYNC);
                if (dv->writemostly == 1)
                        disc.state |= 1 << MD_DISK_WRITEMOSTLY;
                dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT);
@@ -1041,10 +1065,20 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
        } else {
                tst->ss->free_super(tst);
                if (ioctl(fd, ADD_NEW_DISK, &disc)) {
-                       pr_err("add new device failed for %s as %d: %s\n",
-                              dv->devname, j, strerror(errno));
+                       if (dv->disposition == 'j')
+                               pr_err("Failed to hot add %s as journal, "
+                                      "please try restart %s.\n", dv->devname, devname);
+                       else
+                               pr_err("add new device failed for %s as %d: %s\n",
+                                      dv->devname, j, strerror(errno));
                        return -1;
                }
+               if (dv->disposition == 'j') {
+                       pr_err("Journal added successfully, making %s read-write\n", devname);
+                       if (Manage_ro(devname, fd, -1))
+                               pr_err("Failed to make %s read-write\n", devname);
+               }
+
        }
        if (verbose >= 0)
                pr_err("added %s\n", dv->devname);
@@ -1277,6 +1311,7 @@ int Manage_subdevs(char *devname, int fd,
         *         try HOT_ADD_DISK
         *         If that fails EINVAL, try ADD_NEW_DISK
         *  'S' - add the device as a spare - don't try re-add
+        *  'j' - add the device as a journal device
         *  'A' - re-add the device
         *  'r' - remove the device: HOT_REMOVE_DISK
         *        device can be 'faulty' or 'detached' in which case all
@@ -1509,6 +1544,7 @@ int Manage_subdevs(char *devname, int fd,
                        goto abort;
                case 'a':
                case 'S': /* --add-spare */
+               case 'j': /* --add-journal */
                case 'A':
                case 'M': /* --re-add missing */
                case 'F': /* --re-add faulty  */
index fb5a671153531c7810dd5ff2ee9825e8fd45c679..566fc8d8410968a9f5c71e52b2f21021e8d7d176 100644 (file)
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -157,6 +157,7 @@ struct option long_options[] = {
     /* Management */
     {"add",       0, 0, Add},
     {"add-spare", 0, 0, AddSpare},
+    {"add-journal", 0, 0, AddJournal},
     {"remove",    0, 0, Remove},
     {"fail",      0, 0, Fail},
     {"set-faulty",0, 0, Fail},
index 803eda38a9c6ddfc9ce175a2b860cfb299433f27..dab674b4cdd0d347bb58b6a30f175ba82d519c43 100644 (file)
--- a/bitmap.c
+++ b/bitmap.c
@@ -221,8 +221,12 @@ int bitmap_file_open(char *filename, struct supertype **stp)
                        pr_err("No bitmap possible with %s metadata\n",
                                st->ss->name);
                        return -1;
-               } else
-                       st->ss->locate_bitmap(st, fd);
+               } else {
+                       if (st->ss->locate_bitmap(st, fd)) {
+                               pr_err("%s doesn't have bitmap\n", filename);
+                               fd = -1;
+                       }
+               }
 
                *stp = st;
        } else {
diff --git a/crc32c.c b/crc32c.c
new file mode 100644 (file)
index 0000000..156cba1
--- /dev/null
+++ b/crc32c.c
@@ -0,0 +1,104 @@
+/*
+ * Oct 28, 2015 Song Liu simplified the code and port it to mdadm
+ *
+ * Aug 8, 2011 Bob Pearson with help from Joakim Tjernlund and George Spelvin
+ * cleaned up code to current version of sparse and added the slicing-by-8
+ * algorithm to the closely similar existing slicing-by-4 algorithm.
+ *
+ * Oct 15, 2000 Matt Domsch <Matt_Domsch@dell.com>
+ * Nicer crc32 functions/docs submitted by linux@horizon.com.  Thanks!
+ * Code was from the public domain, copyright abandoned.  Code was
+ * subsequently included in the kernel, thus was re-licensed under the
+ * GNU GPL v2.
+ *
+ * Oct 12, 2000 Matt Domsch <Matt_Domsch@dell.com>
+ * Same crc32 function was used in 5 other places in the kernel.
+ * I made one version, and deleted the others.
+ * There are various incantations of crc32().  Some use a seed of 0 or ~0.
+ * Some xor at the end with ~0.  The generic crc32() function takes
+ * seed as an argument, and doesn't xor at the end.  Then individual
+ * users can do whatever they need.
+ *   drivers/net/smc9194.c uses seed ~0, doesn't xor with ~0.
+ *   fs/jffs2 uses seed 0, doesn't xor with ~0.
+ *   fs/partitions/efi.c uses seed ~0, xor's with ~0.
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <sys/types.h>
+#include <asm/types.h>
+#include <stdlib.h>
+
+/*
+ * There are multiple 16-bit CRC polynomials in common use, but this is
+ * *the* standard CRC-32 polynomial, first popularized by Ethernet.
+ * x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0
+ */
+#define CRCPOLY_LE 0xedb88320
+#define CRCPOLY_BE 0x04c11db7
+
+/*
+ * This is the CRC32c polynomial, as outlined by Castagnoli.
+ * x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+x^11+x^10+x^9+
+ * x^8+x^6+x^0
+ */
+#define CRC32C_POLY_LE 0x82F63B78
+
+/**
+ * crc32_le_generic() - Calculate bitwise little-endian Ethernet AUTODIN II
+ *                     CRC32/CRC32C
+ * @crc: seed value for computation.  ~0 for Ethernet, sometimes 0 for other
+ *      uses, or the previous crc32/crc32c value if computing incrementally.
+ * @p: pointer to buffer over which CRC32/CRC32C is run
+ * @len: length of buffer @p
+ * @polynomial: CRC32/CRC32c LE polynomial
+ */
+static inline __u32 crc32_le_generic(__u32 crc, unsigned char const *p,
+                                    size_t len, __u32 polynomial)
+{
+       int i;
+       while (len--) {
+               crc ^= *p++;
+               for (i = 0; i < 8; i++)
+                       crc = (crc >> 1) ^ ((crc & 1) ? polynomial : 0);
+       }
+       return crc;
+}
+
+__u32 crc32_le(__u32 crc, unsigned char const *p, size_t len)
+{
+       return crc32_le_generic(crc, p, len, CRCPOLY_LE);
+}
+
+__u32 crc32c_le(__u32 crc, unsigned char const *p, size_t len)
+{
+       return crc32_le_generic(crc, p, len, CRC32C_POLY_LE);
+}
+
+/**
+ * crc32_be_generic() - Calculate bitwise big-endian Ethernet AUTODIN II CRC32
+ * @crc: seed value for computation.  ~0 for Ethernet, sometimes 0 for
+ *     other uses, or the previous crc32 value if computing incrementally.
+ * @p: pointer to buffer over which CRC32 is run
+ * @len: length of buffer @p
+ * @polynomial: CRC32 BE polynomial
+ */
+static inline __u32 crc32_be_generic(__u32 crc, unsigned char const *p,
+                                    size_t len, __u32 polynomial)
+{
+       int i;
+       while (len--) {
+               crc ^= *p++ << 24;
+               for (i = 0; i < 8; i++)
+                       crc =
+                           (crc << 1) ^ ((crc & 0x80000000) ? polynomial :
+                                         0);
+       }
+       return crc;
+}
+
+__u32 crc32_be(__u32 crc, unsigned char const *p, size_t len)
+{
+       return crc32_be_generic(crc, p, len, CRCPOLY_BE);
+}
diff --git a/md_u.h b/md_u.h
index 76068d647ffe7ca1a6ba6873bd344e6159d060bd..f570a346923ce6c1fef2c88254f5bce592737aae 100644 (file)
--- a/md_u.h
+++ b/md_u.h
@@ -59,7 +59,7 @@ typedef struct mdu_array_info_s {
        int major_version;
        int minor_version;
        int patch_version;
-       int ctime;
+       unsigned int ctime;
        int level;
        int size;
        int nr_disks;
@@ -70,7 +70,7 @@ typedef struct mdu_array_info_s {
        /*
         * Generic state information
         */
-       int utime;              /*  0 Superblock update time                  */
+       unsigned int utime;     /*  0 Superblock update time                  */
        int state;              /*  1 State bits (clean, ...)                 */
        int active_disks;       /*  2 Number of currently active disks        */
        int working_disks;      /*  3 Number of working disks                 */
diff --git a/mdadm.c b/mdadm.c
index f56a8cf856e375fa8a905a057f7d12418ae055f4..feec3b70e4c9d0c65d946816d4c59572189dbc34 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -190,6 +190,7 @@ int main(int argc, char *argv[])
                case 'a':
                case Add:
                case AddSpare:
+               case AddJournal:
                case 'r':
                case Remove:
                case Replace:
@@ -925,6 +926,13 @@ int main(int argc, char *argv[])
                case O(MANAGE,AddSpare): /* add drive - never re-add */
                        devmode = 'S';
                        continue;
+               case O(MANAGE,AddJournal): /* add journal */
+                       if (s.journaldisks && (s.level < 4 || s.level > 6)) {
+                               pr_err("--add-journal is only supported for RAID level 4/5/6.\n");
+                               exit(2);
+                       }
+                       devmode = 'j';
+                       continue;
                case O(MANAGE,ReAdd):
                        devmode = 'A';
                        continue;
diff --git a/mdadm.h b/mdadm.h
old mode 100644 (file)
new mode 100755 (executable)
index 5d5e97f..99802c3
--- a/mdadm.h
+++ b/mdadm.h
@@ -188,6 +188,31 @@ struct dlm_lksb {
 #endif
 #endif /* __KLIBC__ */
 
+/*
+  * Check at compile time that something is of a particular type.
+  * Always evaluates to 1 so you may use it easily in comparisons.
+*/
+
+#define typecheck(type,x) \
+({        type __dummy; \
+          typeof(x) __dummy2; \
+          (void)(&__dummy == &__dummy2); \
+          1; \
+})
+
+/*
+ *  These inlines deal with timer wrapping correctly.
+ *
+ * time_after(a,b) returns true if the time a is after time b.
+*/
+
+#define time_after(a,b)        \
+        (typecheck(unsigned int, a) && \
+         typecheck(unsigned int, b) && \
+         ((int)((b) - (a)) < 0))
+
+#define time_before(a,b)        time_after(b,a)
+
 /*
  * min()/max()/clamp() macros that also do
  * strict type-checking.. See the
@@ -280,6 +305,9 @@ struct mdinfo {
        #define DS_REMOVE       1024
        #define DS_UNBLOCK      2048
        int prev_state, curr_state, next_state;
+
+       /* info read from sysfs */
+       char            sysfs_array_state[20];
 };
 
 struct createinfo {
@@ -342,6 +370,7 @@ enum special_options {
        ManageOpt,
        Add,
        AddSpare,
+       AddJournal,
        Remove,
        Fail,
        Replace,
@@ -563,6 +592,7 @@ enum sysfs_read_flags {
        GET_SIZE        = (1 << 22),
        GET_STATE       = (1 << 23),
        GET_ERROR       = (1 << 24),
+       GET_ARRAY_STATE = (1 << 25),
 };
 
 /* If fd >= 0, get the array it is open on,
@@ -873,7 +903,7 @@ extern struct superswitch {
        /* Seek 'fd' to start of write-intent-bitmap.  Must be an
         * md-native format bitmap
         */
-       void (*locate_bitmap)(struct supertype *st, int fd);
+       int (*locate_bitmap)(struct supertype *st, int fd);
        /* if add_internal_bitmap succeeded for existing array, this
         * writes it out.
         */
@@ -1484,9 +1514,9 @@ struct dlm_hooks {
 };
 
 extern int get_cluster_name(char **name);
-extern int is_clustered(struct supertype *st);
-extern int cluster_get_dlmlock(struct supertype *st, int *lockid);
-extern int cluster_release_dlmlock(struct supertype *st, int lockid);
+extern int dlm_funs_ready(void);
+extern int cluster_get_dlmlock(int *lockid);
+extern int cluster_release_dlmlock(int lockid);
 extern void set_dlm_hooks(void);
 
 #define _ROUND_UP(val, base)   (((val) + (base) - 1) & ~(base - 1))
index 6ad9d39f1b5c0e1967f1e1ba0aa6c39564fa5daa..7f8001479edc0f58a32adaf128c132c6dfb69a77 100644 (file)
--- a/super0.c
+++ b/super0.c
@@ -1155,16 +1155,16 @@ static int add_internal_bitmap0(struct supertype *st, int *chunkp,
        return 1;
 }
 
-static void locate_bitmap0(struct supertype *st, int fd)
+static int locate_bitmap0(struct supertype *st, int fd)
 {
        unsigned long long dsize;
        unsigned long long offset;
 
        if (!get_dev_size(fd, NULL, &dsize))
-               return;
+               return -1;
 
        if (dsize < MD_RESERVED_SECTORS*512)
-               return;
+               return -1;
 
        offset = MD_NEW_SIZE_SECTORS(dsize>>9);
 
@@ -1173,6 +1173,7 @@ static void locate_bitmap0(struct supertype *st, int fd)
        offset += MD_SB_BYTES;
 
        lseek64(fd, offset, 0);
+       return 0;
 }
 
 static int write_bitmap0(struct supertype *st, int fd, enum bitmap_update update)
index 58e6f9dcb9f0b748ca82dd2294d077dd93c073dc..2df590ee9b311e051a9b364a2db964a6b7ac3f51 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -324,7 +324,7 @@ static void examine_super1(struct supertype *st, char *homehost)
            strncmp(sb->set_name, homehost, l) == 0)
                printf("  (local to host %s)", homehost);
        printf("\n");
-       if (bms->nodes > 0)
+       if (bms->nodes > 0 && (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET))
                printf("   Cluster Name : %-64s\n", bms->cluster_name);
        atime = __le64_to_cpu(sb->ctime) & 0xFFFFFFFFFFULL;
        printf("  Creation Time : %.24s\n", ctime(&atime));
@@ -780,7 +780,7 @@ static void detail_super1(struct supertype *st, char *homehost)
            sb->set_name[l] == ':' &&
            strncmp(sb->set_name, homehost, l) == 0)
                printf("  (local to host %s)", homehost);
-       if (bms->nodes > 0)
+       if (bms->nodes > 0 && (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET))
            printf("\n   Cluster Name : %-64s", bms->cluster_name);
        printf("\n           UUID : ");
        for (i=0; i<16; i++) {
@@ -1100,12 +1100,13 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
        int rv = 0;
        int lockid;
        struct mdp_superblock_1 *sb = st->sb;
+       bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE);
 
-       if (is_clustered(st)) {
-               rv = cluster_get_dlmlock(st, &lockid);
+       if (bms->version == BITMAP_MAJOR_CLUSTERED && dlm_funs_ready()) {
+               rv = cluster_get_dlmlock(&lockid);
                if (rv) {
                        pr_err("Cannot get dlmlock in %s return %d\n", __func__, rv);
-                       cluster_release_dlmlock(st, lockid);
+                       cluster_release_dlmlock(lockid);
                        return rv;
                }
        }
@@ -1368,8 +1369,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
                rv = -1;
 
        sb->sb_csum = calc_sb_1_csum(sb);
-       if (is_clustered(st))
-               cluster_release_dlmlock(st, lockid);
+       if (bms->version == BITMAP_MAJOR_CLUSTERED && dlm_funs_ready())
+               cluster_release_dlmlock(lockid);
 
        return rv;
 }
@@ -1474,13 +1475,14 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
        struct mdp_superblock_1 *sb = st->sb;
        __u16 *rp = sb->dev_roles + dk->number;
        struct devinfo *di, **dip;
+       bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE);
        int rv, lockid;
 
-       if (is_clustered(st)) {
-               rv = cluster_get_dlmlock(st, &lockid);
+       if (bms->version == BITMAP_MAJOR_CLUSTERED && dlm_funs_ready()) {
+               rv = cluster_get_dlmlock(&lockid);
                if (rv) {
                        pr_err("Cannot get dlmlock in %s return %d\n", __func__, rv);
-                       cluster_release_dlmlock(st, lockid);
+                       cluster_release_dlmlock(lockid);
                        return rv;
                }
        }
@@ -1513,14 +1515,14 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
        di->next = NULL;
        *dip = di;
 
-       if (is_clustered(st))
-               cluster_release_dlmlock(st, lockid);
+       if (bms->version == BITMAP_MAJOR_CLUSTERED && dlm_funs_ready())
+               cluster_release_dlmlock(lockid);
 
        return 0;
 }
 #endif
 
-static void locate_bitmap1(struct supertype *st, int fd);
+static int locate_bitmap1(struct supertype *st, int fd);
 
 static int store_super1(struct supertype *st, int fd)
 {
@@ -1529,13 +1531,14 @@ static int store_super1(struct supertype *st, int fd)
        struct align_fd afd;
        int sbsize;
        unsigned long long dsize;
+       bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE);
        int rv, lockid;
 
-       if (is_clustered(st)) {
-               rv = cluster_get_dlmlock(st, &lockid);
+       if (bms->version == BITMAP_MAJOR_CLUSTERED && dlm_funs_ready()) {
+               rv = cluster_get_dlmlock(&lockid);
                if (rv) {
                        pr_err("Cannot get dlmlock in %s return %d\n", __func__, rv);
-                       cluster_release_dlmlock(st, lockid);
+                       cluster_release_dlmlock(lockid);
                        return rv;
                }
        }
@@ -1599,8 +1602,8 @@ static int store_super1(struct supertype *st, int fd)
                }
        }
        fsync(fd);
-       if (is_clustered(st))
-               cluster_release_dlmlock(st, lockid);
+       if (bms->version == BITMAP_MAJOR_CLUSTERED && dlm_funs_ready())
+               cluster_release_dlmlock(lockid);
 
        return 0;
 }
@@ -1625,10 +1628,7 @@ static unsigned long choose_bm_space(unsigned long devsize)
 static void free_super1(struct supertype *st);
 
 #define META_BLOCK_SIZE 4096
-unsigned long crc32(
-       unsigned long crc,
-       const unsigned char *buf,
-       unsigned len);
+__u32 crc32c_le(__u32 crc, unsigned char const *p, size_t len);
 
 static int write_empty_r5l_meta_block(struct supertype *st, int fd)
 {
@@ -1652,9 +1652,9 @@ static int write_empty_r5l_meta_block(struct supertype *st, int fd)
        mb->seq = __cpu_to_le64(random32());
        mb->position = __cpu_to_le64(0);
 
-       crc = crc32(0xffffffff, sb->set_uuid, sizeof(sb->set_uuid));
-       crc = crc32(crc, (void *)mb, META_BLOCK_SIZE);
-       mb->checksum = __cpu_to_le32(crc);
+       crc = crc32c_le(0xffffffff, sb->set_uuid, sizeof(sb->set_uuid));
+       crc = crc32c_le(crc, (void *)mb, META_BLOCK_SIZE);
+       mb->checksum = crc;
 
        if (lseek64(fd, (sb->data_offset) * 512, 0) < 0LL) {
                pr_err("cannot seek to offset of the meta block\n");
@@ -1716,7 +1716,8 @@ static int write_init_super1(struct supertype *st)
                if (rfd >= 0)
                        close(rfd);
 
-               sb->events = 0;
+               if (!(di->disk.state & (1<<MD_DISK_JOURNAL)))
+                       sb->events = 0;
 
                refst = dup_super(st);
                if (load_super1(refst, di->fd, NULL)==0) {
@@ -2307,24 +2308,30 @@ add_internal_bitmap1(struct supertype *st,
        return 1;
 }
 
-static void locate_bitmap1(struct supertype *st, int fd)
+static int locate_bitmap1(struct supertype *st, int fd)
 {
        unsigned long long offset;
        struct mdp_superblock_1 *sb;
        int mustfree = 0;
+       int ret;
 
        if (!st->sb) {
                if (st->ss->load_super(st, fd, NULL))
-                       return; /* no error I hope... */
+                       return -1; /* no error I hope... */
                mustfree = 1;
        }
        sb = st->sb;
 
+       if ((__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET))
+               ret = 0;
+       else
+               ret = -1;
        offset = __le64_to_cpu(sb->super_offset);
        offset += (int32_t) __le32_to_cpu(sb->bitmap_offset);
        if (mustfree)
                free(sb);
        lseek64(fd, offset<<9, 0);
+       return ret;
 }
 
 static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update)
@@ -2418,15 +2425,6 @@ static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update
 
 static void free_super1(struct supertype *st)
 {
-       int rv, lockid;
-       if (is_clustered(st)) {
-               rv = cluster_get_dlmlock(st, &lockid);
-               if (rv) {
-                       pr_err("Cannot get dlmlock in %s return %d\n", __func__, rv);
-                       cluster_release_dlmlock(st, lockid);
-                       return;
-               }
-       }
 
        if (st->sb)
                free(st->sb);
@@ -2438,8 +2436,6 @@ static void free_super1(struct supertype *st)
                free(di);
        }
        st->sb = NULL;
-       if (is_clustered(st))
-               cluster_release_dlmlock(st, lockid);
 }
 
 #ifndef MDASSEMBLE
diff --git a/sysfs.c b/sysfs.c
index f1fd610bf5875fb6a669e942c60aaf3690176baf..260034327e3ae852f0683722b052d102b6bb460e 100644 (file)
--- a/sysfs.c
+++ b/sysfs.c
@@ -230,6 +230,13 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
                        goto abort;
        }
 
+       if (options & GET_ARRAY_STATE) {
+               strcpy(base, "array_state");
+               if (load_sys(fname, sra->sysfs_array_state))
+                       goto abort;
+       } else
+               sra->sysfs_array_state[0] = 0;
+
        if (! (options & GET_DEVS))
                return sra;
 
diff --git a/util.c b/util.c
index 8217e117fb546f6430a7b1b240619e79683f6589..f1b0b952ab535c25f77236c8e9d020d0802c8091 100644 (file)
--- a/util.c
+++ b/util.c
@@ -92,13 +92,9 @@ struct dlm_lock_resource {
        struct dlm_lksb lksb;
 };
 
-int is_clustered(struct supertype *st)
+int dlm_funs_ready(void)
 {
-       /* is it a cluster md or not */
-       if (is_dlm_hooks_ready && st->cluster_name)
-               return 1;
-       else
-               return 0;
+       return is_dlm_hooks_ready ? 1 : 0;
 }
 
 /* Using poll(2) to wait for and dispatch ASTs */
@@ -128,17 +124,24 @@ static void dlm_ast(void *arg)
        ast_called = 1;
 }
 
+static char *cluster_name = NULL;
 /* Create the lockspace, take bitmapXXX locks on all the bitmaps. */
-int cluster_get_dlmlock(struct supertype *st, int *lockid)
+int cluster_get_dlmlock(int *lockid)
 {
        int ret = -1;
        char str[64];
        int flags = LKF_NOQUEUE;
 
+       ret = get_cluster_name(&cluster_name);
+       if (ret) {
+               pr_err("The md can't get cluster name\n");
+               return -1;
+       }
+
        dlm_lock_res = xmalloc(sizeof(struct dlm_lock_resource));
-       dlm_lock_res->ls = dlm_hooks->create_lockspace(st->cluster_name, O_RDWR);
+       dlm_lock_res->ls = dlm_hooks->create_lockspace(cluster_name, O_RDWR);
        if (!dlm_lock_res->ls) {
-               pr_err("%s failed to create lockspace\n", st->cluster_name);
+               pr_err("%s failed to create lockspace\n", cluster_name);
                 goto out;
        }
 
@@ -146,7 +149,7 @@ int cluster_get_dlmlock(struct supertype *st, int *lockid)
        if (flags & LKF_CONVERT)
                dlm_lock_res->lksb.sb_lkid = *lockid;
 
-       snprintf(str, 64, "bitmap%04d", st->nodes);
+       snprintf(str, 64, "bitmap%s", cluster_name);
        /* if flags with LKF_CONVERT causes below return ENOENT which means
         * "No such file or directory" */
        ret = dlm_hooks->ls_lock(dlm_lock_res->ls, LKM_PWMODE, &dlm_lock_res->lksb,
@@ -171,10 +174,13 @@ out:
        return ret;
 }
 
-int cluster_release_dlmlock(struct supertype *st, int lockid)
+int cluster_release_dlmlock(int lockid)
 {
        int ret = -1;
 
+       if (!cluster_name)
+               return -1;
+
        /* if flags with LKF_CONVERT causes below return EINVAL which means
         * "Invalid argument" */
        ret = dlm_hooks->ls_unlock(dlm_lock_res->ls, lockid, 0,
@@ -195,7 +201,7 @@ int cluster_release_dlmlock(struct supertype *st, int lockid)
                 goto out;
        }
 
-       ret = dlm_hooks->release_lockspace(st->cluster_name, dlm_lock_res->ls, 1);
+       ret = dlm_hooks->release_lockspace(cluster_name, dlm_lock_res->ls, 1);
        if (ret) {
                pr_err("error %d happened when release lockspace\n", errno);
                /* XXX make sure the lockspace is released eventually */