]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Passes all tests, nearly ready for release.
authorNeil Brown <neilb@suse.de>
Fri, 26 Aug 2005 06:08:28 +0000 (06:08 +0000)
committerNeil Brown <neilb@suse.de>
Fri, 26 Aug 2005 06:08:28 +0000 (06:08 +0000)
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
12 files changed:
Create.c
Grow.c
Manage.c
bitmap.c
mdadm.h
super0.c
super1.c
test
tests/02r1grow
tests/02r5grow
tests/02r6grow
tests/05r1-re-add

index d8fcdfed5de21425a26293d51b92607a5c21b456..34435d51717ad1bdddb4ca7519d2a706553ebdd6 100644 (file)
--- 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 623daf3fe910ec08c3fb16e1f203eaca9f6a6b68..91278e8ddaa4699ec1eb5b370c2fdadb6fd38d0b 100644 (file)
--- 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);
index 8cc977f5138693d0393b947c4be18e38d0d62aa9..4cf40e10d04ae56cc697339d275f28e24baab115 100644 (file)
--- 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.
index 716572c025aff1eb4a1e7ea4e02031095198e660..5252069b09c4ac10f269e9700aed0a07852f3e95 100644 (file)
--- 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 06dd1141b3669568f818223c1eedc1196836891d..6615ea18991290e4046ff8238e0ee3307818fee3 100644 (file)
--- 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;
index 496e3bb0010c103544008d6e0d65978e8b7a1317..ffa5cf7f5d2a7d7f77d6f3c8c07fd5172fbed5ef 100644 (file)
--- 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<<MD_SB_BITMAP_PRESENT)) {
-               int towrite, n;
-               char buf[4096];
-
-               write(fd, ((char*)sb)+MD_SB_BYTES, sizeof(bitmap_super_t));
-               towrite = 64*1024 - MD_SB_BYTES - sizeof(bitmap_super_t);
-               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;
-               }
-               fsync(fd);
-               if (towrite)
-                       rv = -2;
-       }
+       if (rv == 0 && (sb->state & (1<<MD_SB_BITMAP_PRESENT)))
+               rv = st->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);
 
 
index 53de19bc54df7e60179338b2a709042e5e337941..170c52ccc5926fcaccfbf25d2c72716b5cea7cdc 100644 (file)
--- 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 b505fa9d107ad24a7254e77654433c524e957723..3ad0147ebfe6415e4f9d44c0fe6d0155cfc7b9da 100644 (file)
--- 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
index 3198052a34f1e27a5c1e91ff3da6ecfe6e9844f3..af58295b4f1827f8591ad3b6e24545d365bca734 100644 (file)
@@ -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
index 405129d7e70acd8586d3bd663f642f7b60bea91b..2247570b465a1d66f5e0114970b614d529498871 100644 (file)
@@ -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
index fc4d660bcd6c2ea1f2b975d60c4fbc6d4a2ee822..cdcc46a25c1cfd11c4da0d5fe88b2fdfa5aec733 100644 (file)
@@ -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
index 733f8e78412b3d734e1614eee9d3627bf859a497..b2dd82e7012d3142eac02fea27863c8264d6b3f3 100644 (file)
@@ -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