From dcec9ee54779586f287f5db98ab1be3f0f02dd3f Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Tue, 11 Oct 2005 04:44:44 +0000 Subject: [PATCH] Create version-4 bitmaps if kernel supports it. Version-3 bitmaps are host-endian. Version-4 are little-endian and so more portable. Signed-off-by: Neil Brown --- Build.c | 10 +++++++++- Create.c | 20 +++++++++++++++----- Grow.c | 14 ++++++++++++-- bitmap.c | 8 +++++--- bitmap.h | 8 +++++++- mdadm.h | 5 +++-- super0.c | 4 ++-- super1.c | 4 ++-- 8 files changed, 55 insertions(+), 18 deletions(-) diff --git a/Build.c b/Build.c index 689aad0e..2fcc47e1 100644 --- 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); diff --git a/Create.c b/Create.c index 34435d51..148ab0e7 100644 --- 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 91278e8d..aa14638a 100644 --- 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); diff --git a/bitmap.c b/bitmap.c index 82da00a1..bc29768f 100644 --- 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; diff --git a/bitmap.h b/bitmap.h index 02a4e97a..055661d1 100644 --- 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 3557c027..85a853b6 100644 --- 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); diff --git a/super0.c b/super0.c index 95968d30..4ab40af9 100644 --- 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); diff --git a/super1.c b/super1.c index 4479dffb..46ce82d9 100644 --- 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); -- 2.39.2