]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Create version-4 bitmaps if kernel supports it.
authorNeil Brown <neilb@suse.de>
Tue, 11 Oct 2005 04:44:44 +0000 (04:44 +0000)
committerNeil Brown <neilb@suse.de>
Tue, 11 Oct 2005 04:44:44 +0000 (04:44 +0000)
Version-3 bitmaps are host-endian.  Version-4 are little-endian
and so more portable.

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

diff --git a/Build.c b/Build.c
index 689aad0e7344cbe1320106e105f8071017fd7443..2fcc47e153f2d3c29c428cf308d27fe966a747f2 100644 (file)
--- a/Build.c
+++ b/Build.c
@@ -202,13 +202,21 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
                if (bitmap_file) {
                        bitmap_fd = open(bitmap_file, O_RDWR);
                        if (bitmap_fd < 0) {
+                               int major = BITMAP_MAJOR_HI;
                                if (bitmap_chunk == UnSet) {
                                        fprintf(stderr, Name ": %s cannot be openned.",
                                                bitmap_file);
                                        return 1;
                                }
+                               if (vers < 9003) {
+                                       major = BITMAP_MAJOR_HOSTENDIAN;
+#ifdef __BIG_ENDIAN
+                                       fprintf(stderr, Name ": Warning - bitmaps created on this kernel are not portable\n"
+                                               "  between different architectured.  Consider upgrading the Linux kernel.\n");
+#endif
+                               }
                                if (CreateBitmap(bitmap_file, 1, NULL, bitmap_chunk,
-                                                delay, write_behind, size>>9)) {
+                                                delay, write_behind, size>>9, major)) {
                                        return 1;
                                }
                                bitmap_fd = open(bitmap_file, O_RDWR);
index 34435d51717ad1bdddb4ca7519d2a706553ebdd6..148ab0e7bb15eb826bf4fd05fdfbca4ed52dce49 100644 (file)
--- a/Create.c
+++ b/Create.c
@@ -71,7 +71,8 @@ int Create(struct supertype *st, char *mddev, int mdfd,
        int bitmap_fd;
 
        mdu_array_info_t array;
-       
+       int major = BITMAP_MAJOR_HI;
+
        vers = md_get_version(mdfd);
        if (vers < 9000) {
                fprintf(stderr, Name ": Create requires md driver version 0.90.0 or later\n");
@@ -350,13 +351,21 @@ int Create(struct supertype *st, char *mddev, int mdfd,
        if (!st->ss->init_super(st, &super, &array, name))
                return 1;
 
+       if (bitmap_file && vers < 9003) {
+               major = BITMAP_MAJOR_HOSTENDIAN;
+#ifdef __BIG_ENDIAN
+               fprintf(stderr, Name ": Warning - bitmaps created on this kernel are not portable\n"
+                       "  between different architectured.  Consider upgrading the Linux kernel.\n");
+#endif
+       }
+
        if (bitmap_file && strcmp(bitmap_file, "internal")==0) {
                if ((vers%100) < 2) {
                        fprintf(stderr, Name ": internal bitmaps not supported by this kernel.\n");
                        return 1;
                }
                if (!st->ss->add_internal_bitmap(st, super, bitmap_chunk, delay, write_behind,
-                                                &array.size, 1)) {
+                                                &array.size, 1, major)) {
                        fprintf(stderr, Name ": Given bitmap chunk size not supported.\n");
                        return 1;
                }
@@ -387,14 +396,15 @@ 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 */)) {
+                                delay, write_behind,
+                                array.size*2ULL /* FIXME wrong for raid10 */,
+                                major)) {
                        return 1;
                }
                bitmap_fd = open(bitmap_file, O_RDWR);
                if (bitmap_fd < 0) {
                        fprintf(stderr, Name ": weird: %s cannot be openned\n",
-                              bitmap_file);
+                               bitmap_file);
                        return 1;
                }
                if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) {
diff --git a/Grow.c b/Grow.c
index 91278e8ddaa4699ec1eb5b370c2fdadb6fd38d0b..aa14638a1c14fb6a44df267ca99758e49d6f35ab 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -206,6 +206,16 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
        mdu_bitmap_file_t bmf;
        mdu_array_info_t array;
        struct supertype *st;
+       int major = BITMAP_MAJOR_HI;
+       int vers = md_get_version(fd);
+
+       if (vers < 9003) {
+               major = BITMAP_MAJOR_HOSTENDIAN;
+#ifdef __BIG_ENDIAN
+               fprintf(stderr, Name ": Warning - bitmaps created on this kernel are not portable\n"
+                       "  between different architectured.  Consider upgrading the Linux kernel.\n");
+#endif
+       }
 
        if (ioctl(fd, GET_BITMAP_FILE, &bmf) != 0) {
                if (errno == ENOMEM) 
@@ -275,7 +285,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);
+                                                                   &array.size, 0, major);
                                        st->ss->write_bitmap(st, fd2, super);
                                }
                                close(fd2);
@@ -322,7 +332,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)) {
+                                delay, write_behind, array.size*2ULL, major)) {
                        return 1;
                }
                bitmap_fd = open(file, O_RDWR);
index 82da00a195c3c26dd0b59d5f7271c5c55aac9726..bc29768ff364225f61bf8708808627e6d8c8588e 100644 (file)
--- a/bitmap.c
+++ b/bitmap.c
@@ -243,7 +243,8 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
                fprintf(stderr, Name ": invalid bitmap magic 0x%x, the bitmap file appears to be corrupted\n", sb->magic);
        }
        printf("         Version : %d\n", sb->version);
-       if (sb->version != BITMAP_MAJOR) {
+       if (sb->version < BITMAP_MAJOR_LO ||
+           sb->version > BITMAP_MAJOR_HI) {
                fprintf(stderr, Name ": unknown bitmap version %d, either the bitmap file is corrupted or you need to upgrade your tools\n", sb->version);
                goto free_info;
        }
@@ -287,7 +288,8 @@ free_info:
 int CreateBitmap(char *filename, int force, char uuid[16],
                 unsigned long chunksize, unsigned long daemon_sleep,
                 unsigned long write_behind,
-                unsigned long long array_size /* sectors */)
+                unsigned long long array_size /* sectors */,
+                int major)
 {
        /*
         * Create a bitmap file with a superblock and (optionally) a full bitmap
@@ -313,7 +315,7 @@ int CreateBitmap(char *filename, int force, char uuid[16],
 
        memset(&sb, 0, sizeof(sb));
        sb.magic = BITMAP_MAGIC;
-       sb.version = BITMAP_MAJOR;
+       sb.version = major;
        if (uuid != NULL)
                memcpy(sb.uuid, uuid, 16);
        sb.chunksize = chunksize;
index 02a4e97acabc507e7f75697e39116589435e67bd..055661d1da81f8f91f861c5c031b05090493a786 100644 (file)
--- a/bitmap.h
+++ b/bitmap.h
@@ -6,7 +6,13 @@
 #ifndef BITMAP_H
 #define BITMAP_H 1
 
-#define BITMAP_MAJOR 3
+#define BITMAP_MAJOR_LO 3
+/* version 4 insists the bitmap is in little-endian order
+ * with version 3, it is host-endian which is non-portable
+ */
+#define BITMAP_MAJOR_HI 4
+#define        BITMAP_MAJOR_HOSTENDIAN 3
+
 #define BITMAP_MINOR 39
 
 /*
diff --git a/mdadm.h b/mdadm.h
index 3557c02706a36dda24301da37cc8615dd9ea9311..85a853b6e65cc799d4867a3e6f48d0f70642622c 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -190,7 +190,7 @@ 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 (*add_internal_bitmap)(struct supertype *st, void *sbv, int chunk, int delay, int write_behind, int *sizep, 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;
@@ -265,7 +265,8 @@ extern int Kill(char *dev, int force);
 extern int CreateBitmap(char *filename, int force, char uuid[16],
                        unsigned long chunksize, unsigned long daemon_sleep,
                        unsigned long write_behind,
-                       unsigned long long array_size);
+                       unsigned long long array_size,
+                       int major);
 extern int ExamineBitmap(char *filename, int brief, struct supertype *st);
 
 extern int md_get_version(int fd);
index 95968d302498ff9950e2684ab78878a5ea93a64a..4ab40af9533225da0b0bfd0e69056003e14f7d40 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)
+static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int delay, int write_behind, int *sizep, int may_change, int major)
 {
        /*
         * The bitmap comes immediately after the superblock and must be 60K in size
@@ -688,7 +688,7 @@ static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int
 
        memset(bms, sizeof(*bms), 0);
        bms->magic = __cpu_to_le32(BITMAP_MAGIC);
-       bms->version = __cpu_to_le32(BITMAP_MAJOR);
+       bms->version = __cpu_to_le32(major);
        uuid_from_super0((int*)bms->uuid, sb);
        bms->chunksize = __cpu_to_le32(chunk);
        bms->daemon_sleep = __cpu_to_le32(delay);
index 4479dffb26661ebd2d366e421449d1fea814f42b..46ce82d92bb891d08b7e9777646123f5cad61dc5 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 chunk, int delay, int write_behind, int *sizep, int may_change, int major)
 {
        /*
         * If not may_change, then this is a 'Grow', and the bitmap
@@ -883,7 +883,7 @@ add_internal_bitmap1(struct supertype *st, void *sbv,
        sb->feature_map = __cpu_to_le32(__le32_to_cpu(sb->feature_map) | 1);
        memset(bms, sizeof(*bms), 0);
        bms->magic = __cpu_to_le32(BITMAP_MAGIC);
-       bms->version = __cpu_to_le32(BITMAP_MAJOR);
+       bms->version = __cpu_to_le32(major);
        uuid_from_super1((int*)bms->uuid, sb);
        bms->chunksize = __cpu_to_le32(chunk);
        bms->daemon_sleep = __cpu_to_le32(delay);