]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
When updating uuid, update the bitmap as well - internal bitmaps.
authorNeil Brown <neilb@suse.de>
Tue, 16 May 2006 05:52:51 +0000 (05:52 +0000)
committerNeil Brown <neilb@suse.de>
Tue, 16 May 2006 05:52:51 +0000 (05:52 +0000)
Otherwise when you "--update==uuid" an array with an internal
bitmap, it will break, badly.

Signed-off-by: Neil Brown <neilb@suse.de>
super0.c
super1.c

index 9c313ca9847d5a397d2317dba658f48f576aba7a..49ad19108b965c08795a0d35464a53aa50974494 100644 (file)
--- a/super0.c
+++ b/super0.c
@@ -430,6 +430,11 @@ static int update_super0(struct mdinfo *info, void *sbv, char *update, char *dev
                sb->set_uuid1 = info->uuid[1];
                sb->set_uuid2 = info->uuid[2];
                sb->set_uuid3 = info->uuid[3];
+               if (sb->state & (1<<MD_SB_BITMAP_PRESENT)) {
+                       struct bitmap_super_s *bm;
+                       bm = (struct bitmap_super_s*)(sb+1);
+                       uuid_from_super0((int*)bm->uuid, sbv);
+               }
        }
        if (strcmp(update, "_reshape_progress")==0)
                sb->reshape_position = info->reshape_progress;
@@ -549,6 +554,12 @@ static int store_super0(struct supertype *st, int fd, void *sbv)
        if (write(fd, super, sizeof(*super)) != sizeof(*super))
                return 4;
 
+       if (super->state & (1<<MD_SB_BITMAP_PRESENT)) {
+               struct bitmap_super_s * bm = (struct bitmap_super_s*)(super+1);
+               if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC)
+                       write(fd, bm, sizeof(*bm));
+       }
+
        fsync(fd);
        return 0;
 }
@@ -596,8 +607,8 @@ static int compare_super0(void **firstp, void *secondv)
        if (second->md_magic != MD_SB_MAGIC)
                return 1;
        if (!first) {
-               first = malloc(MD_SB_BYTES);
-               memcpy(first, second, MD_SB_BYTES);
+               first = malloc(MD_SB_BYTES + sizeof(struct bitmap_super_s));
+               memcpy(first, second, MD_SB_BYTES + sizeof(struct bitmap_super_s));
                *firstp = first;
                return 0;
        }
@@ -632,6 +643,8 @@ static int load_super0(struct supertype *st, int fd, void **sbp, char *devname)
        unsigned long long dsize;
        unsigned long long offset;
        mdp_super_t *super;
+       int uuid[4];
+       struct bitmap_super_s *bsb;
     
 #ifdef BLKGETSIZE64
        if (ioctl(fd, BLKGETSIZE64, &dsize) != 0)
@@ -701,6 +714,27 @@ static int load_super0(struct supertype *st, int fd, void **sbp, char *devname)
                st->max_devs = MD_SB_DISKS;
        }
 
+       /* Now check on the bitmap superblock */
+       if ((super->state & (1<<MD_SB_BITMAP_PRESENT)) == 0)
+               return 0;
+       /* Read the bitmap superblock and make sure it looks
+        * valid.  If it doesn't clear the bit.  An --assemble --force
+        * should get that written out.
+        */
+       if (read(fd, super+1, sizeof(struct bitmap_super_s))
+           != sizeof(struct bitmap_super_s))
+               goto no_bitmap;
+
+       uuid_from_super0(uuid, super);
+       bsb = (struct bitmap_super_s *)(super+1);
+       if (__le32_to_cpu(bsb->magic) != BITMAP_MAGIC ||
+           memcmp(bsb->uuid, uuid, 16) != 0)
+               goto no_bitmap;
+       return 0;
+
+ no_bitmap:
+       super->state &= ~(1<<MD_SB_BITMAP_PRESENT);
+
        return 0;
 }
 
index 77b5485d3dadb83abe1b1e6e7d112549719ebc9f..4b2d8e80cd06cbf13fd1af180836923d2ae3ae58 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -476,8 +476,14 @@ static int update_super1(struct mdinfo *info, void *sbv, char *update, char *dev
                /* make sure resync happens */
                sb->resync_offset = ~0ULL;
        }
-       if (strcmp(update, "uuid") == 0)
+       if (strcmp(update, "uuid") == 0) {
                memcpy(sb->set_uuid, info->uuid, 16);
+               if (__le32_to_cpu(sb->feature_map)&MD_FEATURE_BITMAP_OFFSET) {
+                       struct bitmap_super_s *bm;
+                       bm = (struct bitmap_super_s*)(sbv+1024);
+                       memcpy(bm->uuid, info->uuid, 16);
+               }
+       }
        if (strcmp(update, "_reshape_progress")==0)
                sb->reshape_position = __cpu_to_le64(info->reshape_progress);
 
@@ -569,6 +575,8 @@ static void add_to_super1(void *sbv, mdu_disk_info_t *dk)
                *rp = 0xfffe;
 }
 
+static void locate_bitmap1(struct supertype *st, int fd, void *sbv);
+
 static int store_super1(struct supertype *st, int fd, void *sbv)
 {
        struct mdp_superblock_1 *sb = sbv;
@@ -632,6 +640,14 @@ static int store_super1(struct supertype *st, int fd, void *sbv)
        if (write(fd, sb, sbsize) != sbsize)
                return 4;
 
+       if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) {
+               struct bitmap_super_s *bm = (struct bitmap_super_s*)
+                       ((char*)sb)+1024;
+               if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC) {
+                       locate_bitmap1(st, fd, sbv);
+                       write(fd, bm, sizeof(*bm));
+               }
+       }
        fsync(fd);
        return 0;
 }
@@ -777,8 +793,8 @@ static int compare_super1(void **firstp, void *secondv)
                return 1;
 
        if (!first) {
-               first = malloc(1024);
-               memcpy(first, second, 1024);
+               first = malloc(1024+sizeof(bitmap_super_t));
+               memcpy(first, second, 1024+sizeof(bitmap_super_t));
                *firstp = first;
                return 0;
        }
@@ -801,7 +817,8 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
        unsigned long long dsize;
        unsigned long long sb_offset;
        struct mdp_superblock_1 *super;
-
+       int uuid[4];
+       struct bitmap_super_s *bsb;
 
 
        if (st->ss == NULL) {
@@ -860,7 +877,7 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
        /*
         * Calculate the position of the superblock.
         * It is always aligned to a 4K boundary and
-        * depeding on minor_version, it can be:
+        * depending on minor_version, it can be:
         * 0: At least 8K, but less than 12K, from end of device
         * 1: At start of device
         * 2: 4K from start of device.
@@ -924,6 +941,28 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
                return 2;
        }
        *sbp = super;
+
+       /* Now check on the bitmap superblock */
+       if ((__le32_to_cpu(super->feature_map)&MD_FEATURE_BITMAP_OFFSET) == 0)
+               return 0;
+       /* Read the bitmap superblock and make sure it looks
+        * valid.  If it doesn't clear the bit.  An --assemble --force
+        * should get that written out.
+        */
+       locate_bitmap1(st, fd, super);
+       if (read(fd, ((char*)super)+1024, sizeof(struct bitmap_super_s))
+           != sizeof(struct bitmap_super_s))
+               goto no_bitmap;
+
+       uuid_from_super1(uuid, super);
+       bsb = (struct bitmap_super_s *)(((char*)super)+1024);
+       if (__le32_to_cpu(bsb->magic) != BITMAP_MAGIC ||
+           memcmp(bsb->uuid, uuid, 16) != 0)
+               goto no_bitmap;
+       return 0;
+
+ no_bitmap:
+       super->feature_map = __cpu_to_le32(__le32_to_cpu(super->feature_map) & ~1);
        return 0;
 }
 
@@ -1041,7 +1080,7 @@ add_internal_bitmap1(struct supertype *st, void *sbv,
 }
 
 
-void locate_bitmap1(struct supertype *st, int fd, void *sbv)
+static void locate_bitmap1(struct supertype *st, int fd, void *sbv)
 {
        unsigned long long offset;
        struct mdp_superblock_1 *sb;
@@ -1061,7 +1100,7 @@ void locate_bitmap1(struct supertype *st, int fd, void *sbv)
        lseek64(fd, offset<<9, 0);
 }
 
-int write_bitmap1(struct supertype *st, int fd, void *sbv)
+static int write_bitmap1(struct supertype *st, int fd, void *sbv)
 {
        struct mdp_superblock_1 *sb = sbv;
        bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+1024);