From 1bf4e2d962d0d7937bb24799aaa636edc6497fa4 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Fri, 26 Aug 2005 06:08:28 +0000 Subject: [PATCH] Passes all tests, nearly ready for release. Signed-off-by: Neil Brown --- Create.c | 6 +-- Grow.c | 2 +- Manage.c | 2 +- bitmap.c | 6 +-- mdadm.h | 6 +-- super0.c | 37 ++++----------- super1.c | 117 +++++++++++++++++----------------------------- test | 8 ++-- tests/02r1grow | 2 +- tests/02r5grow | 2 +- tests/02r6grow | 2 +- tests/05r1-re-add | 2 +- 12 files changed, 71 insertions(+), 121 deletions(-) diff --git a/Create.c b/Create.c index d8fcdfed..34435d51 100644 --- a/Create.c +++ b/Create.c @@ -210,7 +210,7 @@ int Create(struct supertype *st, char *mddev, int mdfd, ldsize = dsize; ldsize <<= 9; } - freesize = st->ss->avail_size(st, ldsize >> 9, 64*2); + freesize = st->ss->avail_size(st, ldsize >> 9); if (freesize == 0) { fprintf(stderr, Name ": %s is too small: %luK\n", dname, (unsigned long)(ldsize>>10)); @@ -356,7 +356,7 @@ int Create(struct supertype *st, char *mddev, int mdfd, return 1; } if (!st->ss->add_internal_bitmap(st, super, bitmap_chunk, delay, write_behind, - size ? size : maxsize)) { + &array.size, 1)) { fprintf(stderr, Name ": Given bitmap chunk size not supported.\n"); return 1; } @@ -451,7 +451,7 @@ int Create(struct supertype *st, char *mddev, int mdfd, break; case 2: if (disk.state == 1) break; - st->ss->write_init_super(st, super, &disk, dv->devname, 64*2); + st->ss->write_init_super(st, super, &disk, dv->devname); if (ioctl(mdfd, ADD_NEW_DISK, &disk)) { fprintf(stderr, Name ": ADD_NEW_DISK for %s failed: %s\n", diff --git a/Grow.c b/Grow.c index 623daf3f..91278e8d 100644 --- a/Grow.c +++ b/Grow.c @@ -275,7 +275,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); + &array.size, 0); st->ss->write_bitmap(st, fd2, super); } close(fd2); diff --git a/Manage.c b/Manage.c index 8cc977f5..4cf40e10 100644 --- a/Manage.c +++ b/Manage.c @@ -311,7 +311,7 @@ int Manage_subdevs(char *devname, int fd, if (dv->writemostly) disc.state |= 1 << MD_DISK_WRITEMOSTLY; st->ss->add_to_super(dsuper, &disc); - if (st->ss->write_init_super(st, dsuper, &disc, dv->devname, 0 /* FIXME */)) + if (st->ss->write_init_super(st, dsuper, &disc, dv->devname)) return 1; } else if (dv->re_add) { /* this had better be raid1. diff --git a/bitmap.c b/bitmap.c index 716572c0..5252069b 100644 --- a/bitmap.c +++ b/bitmap.c @@ -285,9 +285,9 @@ 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) + unsigned long chunksize, unsigned long daemon_sleep, + unsigned long write_behind, + unsigned long long array_size /* sectors */) { /* * Create a bitmap file with a superblock and (optionally) a full bitmap diff --git a/mdadm.h b/mdadm.h index 06dd1141..6615ea18 100644 --- a/mdadm.h +++ b/mdadm.h @@ -185,12 +185,12 @@ extern struct superswitch { int (*init_super)(struct supertype *st, void **sbp, mdu_array_info_t *info, char *name); void (*add_to_super)(void *sbv, mdu_disk_info_t *dinfo); int (*store_super)(struct supertype *st, int fd, void *sbv); - int (*write_init_super)(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo, char *devname, int reserve); + int (*write_init_super)(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo, char *devname); int (*compare_super)(void **firstp, void *secondv); 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 reserve); - int (*add_internal_bitmap)(struct supertype *st, void *sbv, int chunk, int delay, int write_behind, unsigned long long size); + __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); void (*locate_bitmap)(struct supertype *st, int fd); int (*write_bitmap)(struct supertype *st, int fd, void *sbv); int major; diff --git a/super0.c b/super0.c index 496e3bb0..ffa5cf7f 100644 --- a/super0.c +++ b/super0.c @@ -472,7 +472,7 @@ static int store_super0(struct supertype *st, int fd, void *sbv) return 0; } -static int write_init_super0(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo, char *devname, int reserve) +static int write_init_super0(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo, char *devname) { mdp_super_t *sb = sbv; int fd = open(devname, O_RDWR|O_EXCL); @@ -490,27 +490,8 @@ static int write_init_super0(struct supertype *st, void *sbv, mdu_disk_info_t *d sb->sb_csum = calc_sb0_csum(sb); rv = store_super0(st, fd, sb); - if (sb->state & (1< 0) { - n = towrite; - if (n > sizeof(buf)) - n = sizeof(buf); - n = write(fd, buf, n); - if (n > 0) - towrite -= n; - else - break; - } - fsync(fd); - if (towrite) - rv = -2; - } + if (rv == 0 && (sb->state & (1<ss->write_bitmap(st, fd, sbv); close(fd); if (rv) @@ -664,15 +645,14 @@ static struct supertype *match_metadata_desc0(char *arg) return NULL; } -static __u64 avail_size0(struct supertype *st, __u64 devsize, int reserve) +static __u64 avail_size0(struct supertype *st, __u64 devsize) { if (devsize < MD_RESERVED_SECTORS*2) return 0ULL; - if (reserve > 64*2) return 0ULL; return MD_NEW_SIZE_SECTORS(devsize); } -static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int delay, int write_behind, unsigned long long size) +static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int delay, int write_behind, int *sizep, int may_change) { /* * The bitmap comes immediately after the superblock and must be 60K in size @@ -680,8 +660,8 @@ static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int * * size is in K, chunk is in bytes !!! */ - - unsigned long long bits = size; + unsigned long long size = *sizep; + unsigned long long bits; unsigned long long max_bits = 60*1024*8; unsigned long long min_chunk; mdp_super_t *sb = sbv; @@ -689,6 +669,7 @@ static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int min_chunk = 4096; /* sub-page chunks don't work yet.. */ + bits = (size * 1024)/ min_chunk +1; while (bits > max_bits) { min_chunk *= 2; bits = (bits+1)/2; @@ -706,7 +687,7 @@ static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int uuid_from_super0((int*)bms->uuid, sb); bms->chunksize = __cpu_to_le32(chunk); bms->daemon_sleep = __cpu_to_le32(delay); - bms->sync_size = __cpu_to_le64(size); + bms->sync_size = __cpu_to_le64(size<<1); bms->write_behind = __cpu_to_le32(write_behind); diff --git a/super1.c b/super1.c index 53de19bc..170c52cc 100644 --- a/super1.c +++ b/super1.c @@ -526,8 +526,7 @@ static int store_super1(struct supertype *st, int fd, void *sbv) static int load_super1(struct supertype *st, int fd, void **sbp, char *devname); static int write_init_super1(struct supertype *st, void *sbv, - mdu_disk_info_t *dinfo, char *devname, - int reserve) + mdu_disk_info_t *dinfo, char *devname) { struct mdp_superblock_1 *sb = sbv; struct mdp_superblock_1 *refsb = NULL; @@ -595,18 +594,18 @@ static int write_init_super1(struct supertype *st, void *sbv, sb_offset &= ~(4*2-1); sb->super_offset = __cpu_to_le64(sb_offset); sb->data_offset = __cpu_to_le64(0); - sb->data_size = __cpu_to_le64(sb_offset - reserve); + sb->data_size = __cpu_to_le64(sb_offset); break; case 1: sb->super_offset = __cpu_to_le64(0); - sb->data_offset = __cpu_to_le64(2 + reserve); - sb->data_size = __cpu_to_le64(size - 2 - reserve); + sb->data_offset = __cpu_to_le64(4*2); /* leave 4k for super and bitmap */ + sb->data_size = __cpu_to_le64(size - 4*2); break; case 2: sb_offset = 4*2; sb->super_offset = __cpu_to_le64(sb_offset); - sb->data_offset = __cpu_to_le64(sb_offset+2 + reserve); - sb->data_size = __cpu_to_le64(size - 4*2 - 2 - reserve); + sb->data_offset = __cpu_to_le64(sb_offset+4*2); + sb->data_size = __cpu_to_le64(size - 4*2 - 4*2); break; default: return -EINVAL; @@ -618,29 +617,8 @@ static int write_init_super1(struct supertype *st, void *sbv, if (rv) fprintf(stderr, Name ": failed to write superblock to %s\n", devname); - if (__le32_to_cpu(sb->feature_map) & 1) { - /* write the bitmap */ - int towrite, n; - char buf[4096]; - - st->ss->locate_bitmap(st, fd); - write(fd, ((char*)sb)+1024, sizeof(bitmap_super_t)); - towrite = 62*1024; - memset(buf, 0xff, sizeof(buf)); - while (towrite > 0) { - n=towrite; - if (n > sizeof(buf)) - n = sizeof(buf); - n = write(fd, buf, n); - if (n > 0) - towrite -= n; - else - break; - } - if (towrite) - rv = -2; - } - fsync(fd); + if (rv == 0 && (__le32_to_cpu(sb->feature_map) & 1)) + rv = st->ss->write_bitmap(st, fd, sbv); close(fd); return rv; } @@ -835,42 +813,54 @@ static struct supertype *match_metadata_desc1(char *arg) * superblock type st, and reserving 'reserve' sectors for * a possible bitmap */ -static __u64 avail_size1(struct supertype *st, __u64 devsize, int reserve) +static __u64 avail_size1(struct supertype *st, __u64 devsize) { if (devsize < 24) return 0; switch(st->minor_version) { case 0: - /* at end, with reserve before it */ - return ((devsize - 8*2 ) & ~(4*2-1)) - reserve; + /* at end */ + return ((devsize - 8*2 ) & ~(4*2-1)); case 1: - /* at start, 1K for superblock */ - return devsize - 2 - reserve; + /* at start, 4K for superblock and possible bitmap */ + return devsize - 4*2; case 2: - /* 4k from start, 1K for superblock */ - return devsize - (4+1)*2 - reserve; + /* 4k from start, 4K for superblock and possible bitmap */ + return devsize - (4+4)*2; } return 0; } -static int add_internal_bitmap1(struct supertype *st, void *sbv, int chunk, int delay, int write_behind, unsigned long long size) +static int +add_internal_bitmap1(struct supertype *st, void *sbv, + int chunk, int delay, int write_behind, int *sizep, int may_change) { /* - * The bitmap comes immediately before of after the superblock and must be 62K in size - * at most. The default size is between 31K and 62K + * If not may_change, then this is a 'Grow', and the bitmap + * must fit after the superblock. + * If may_change, then this is create, and we can put the bitmap + * before the superblock if we like, or may move the start. + * For now, just squeeze the bitmap into 3k and don't change anything. * * size is in K, chunk is in bytes !!! */ - unsigned long long bits = size; - unsigned long long max_bits = 62*1024*8; + unsigned long long size = *sizep; + unsigned long long bits; + unsigned long long max_bits = (3*512 - sizeof(bitmap_super_t)) * 8; unsigned long long min_chunk; struct mdp_superblock_1 *sb = sbv; bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + 1024); + if (st->minor_version && !may_change && + __le64_to_cpu(sb->data_offset) - __le64_to_cpu(sb->super_offset) < 8) + return 0; /* doesn't fit */ + + min_chunk = 4096; /* sub-page chunks don't work yet.. */ + bits = (size*1024)/min_chunk +1; while (bits > max_bits) { min_chunk *= 2; bits = (bits+1)/2; @@ -880,10 +870,7 @@ static int add_internal_bitmap1(struct supertype *st, void *sbv, int chunk, int else if (chunk < min_chunk) return 0; /* chunk size too small */ - if (st->minor_version == 0) - sb->bitmap_offset = __cpu_to_le32(-64*2); - else - sb->bitmap_offset = __cpu_to_le32(2); + sb->bitmap_offset = __cpu_to_le32(2); sb->feature_map = __cpu_to_le32(__le32_to_cpu(sb->feature_map) | 1); memset(bms, sizeof(*bms), 0); @@ -892,7 +879,7 @@ static int add_internal_bitmap1(struct supertype *st, void *sbv, int chunk, int uuid_from_super1((int*)bms->uuid, sb); bms->chunksize = __cpu_to_le32(chunk); bms->daemon_sleep = __cpu_to_le32(delay); - bms->sync_size = __cpu_to_le64(size); + bms->sync_size = __cpu_to_le64(size<<1); bms->write_behind = __cpu_to_le32(write_behind); return 1; @@ -901,40 +888,21 @@ static int add_internal_bitmap1(struct supertype *st, void *sbv, int chunk, int void locate_bitmap1(struct supertype *st, int fd) { - unsigned long long dsize; - unsigned long size; unsigned long long offset; + struct mdp_superblock_1 *sb; - switch(st->minor_version){ - case 0: -#ifdef BLKGETSIZE64 - if (ioctl(fd, BLKGETSIZE64, &dsize) != 0) -#endif - { - if (ioctl(fd, BLKGETSIZE, &size)) - return; - else - dsize = ((unsigned long long)size)<<9; - } - - offset = (dsize - 8192) & ~4095ULL; + if (st->ss->load_super(st, fd, (void**)&sb, NULL)) + return; /* no error I hope... */ + offset = __le64_to_cpu(sb->super_offset); + offset += (long) __le32_to_cpu(sb->bitmap_offset); - offset -= 65536; - break; - - case 1: - offset = 1024; - break; - case 2: - offset = 4096+1024; - } - lseek64(fd, offset, 0); + lseek64(fd, offset<<9, 0); } 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); int rv = 0; int towrite, n; @@ -943,7 +911,8 @@ int write_bitmap1(struct supertype *st, int fd, void *sbv) locate_bitmap1(st, fd); write(fd, ((char*)sb)+1024, sizeof(bitmap_super_t)); - towrite = 62*1024 - sizeof(bitmap_super_t); + towrite = __le64_to_cpu(bms->sync_size) / (__le32_to_cpu(bms->chunksize)>>9); + towrite = (towrite+7) >> 3; /* bits to bytes */ memset(buf, 0xff, sizeof(buf)); while (towrite > 0) { n = towrite; diff --git a/test b/test index b505fa9d..3ad0147e 100644 --- a/test +++ b/test @@ -24,12 +24,12 @@ md0=/dev/md0 md1=/dev/md1 md2=/dev/md2 # We test mdadm on loop-back block devices. # dir for storing files should be settable by command line maybe -targetdir=/tmp +targetdir=/var/tmp size=20000 mdsize0=19904 -mdsize1=19928 -mdsize11=19935 -mdsize12=19931 +mdsize1=19992 +mdsize11=19996 +mdsize12=19992 cleanup() { $mdadm -Ss diff --git a/tests/02r1grow b/tests/02r1grow index 3198052a..af58295b 100644 --- a/tests/02r1grow +++ b/tests/02r1grow @@ -27,7 +27,7 @@ testdev $md0 1 $[size/2] 1 mdadm --grow $md0 --size max check resync check wait -testdev $md0 1 $[size-1-64] 1 +testdev $md0 1 $[size-4] 1 mdadm --grow $md0 --size $[size/2] check nosync diff --git a/tests/02r5grow b/tests/02r5grow index 405129d7..2247570b 100644 --- a/tests/02r5grow +++ b/tests/02r5grow @@ -27,7 +27,7 @@ testdev $md0 3 $[size/2] 128 mdadm --grow $md0 --size max check resync check wait -testdev $md0 3 $[size-1-64] 128 +testdev $md0 3 $[size-4] 128 mdadm --grow $md0 --size $[size/2] check nosync diff --git a/tests/02r6grow b/tests/02r6grow index fc4d660b..cdcc46a2 100644 --- a/tests/02r6grow +++ b/tests/02r6grow @@ -27,7 +27,7 @@ testdev $md0 2 $[size/2] 128 mdadm --grow $md0 --size max check resync check wait -testdev $md0 2 $[size-1-64] 128 +testdev $md0 2 $[size-4] 128 mdadm --grow $md0 --size $[size/2] check nosync diff --git a/tests/05r1-re-add b/tests/05r1-re-add index 733f8e78..b2dd82e7 100644 --- a/tests/05r1-re-add +++ b/tests/05r1-re-add @@ -15,7 +15,7 @@ mdadm $md0 -f $dev2 sleep 1 mdadm $md0 -r $dev2 mdadm $md0 -a $dev2 - cat /proc/mdstat +#cat /proc/mdstat check nosync mdadm $md0 -f $dev2 -- 2.39.2