]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Enable support for v.large raid1.
authorNeil Brown <neilb@suse.de>
Fri, 27 Jan 2006 06:21:06 +0000 (06:21 +0000)
committerNeil Brown <neilb@suse.de>
Fri, 27 Jan 2006 06:21:06 +0000 (06:21 +0000)
clean up 'long long' usage for size of array, so that
with v-1 superblocks a raid1 larger than 2TB is possible.

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

index 178d62eb2038cbb97992abc1ab1c53472415b6dd..7fbf9c02f08307c33cfd3acee7e86af569006605 100644 (file)
--- a/Create.c
+++ b/Create.c
@@ -32,7 +32,7 @@
 #include       "md_p.h"
 
 int Create(struct supertype *st, char *mddev, int mdfd,
-          int chunk, int level, int layout, unsigned long size, int raiddisks, int sparedisks,
+          int chunk, int level, int layout, unsigned long long size, int raiddisks, int sparedisks,
           char *name,
           int subdevs, mddev_dev_t devlist,
           int runstop, int verbose, int force, int assume_clean,
@@ -74,7 +74,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
        mdu_array_info_t array;
        int major = BITMAP_MAJOR_HI;
 
-       memset(array, 0, sizeof(array));
+       memset(&array, 0, sizeof(array));
 
        vers = md_get_version(mdfd);
        if (vers < 9000) {
@@ -231,7 +231,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
 
                if (size && freesize < size) {
                        fprintf(stderr, Name ": %s is smaller that given size."
-                               " %lluK < %luK + superblock\n", dname, freesize, size);
+                               " %lluK < %lluK + superblock\n", dname, freesize, size);
                        fail = 1;
                        close(fd);
                        continue;
@@ -262,18 +262,18 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                }
                if (level > 0 || level == LEVEL_MULTIPATH || level == LEVEL_FAULTY) {
                        /* size is meaningful */
-                       if (minsize > 0x100000000ULL) {
+                       if (minsize > 0x100000000ULL && st->ss->major == 0) {
                                fprintf(stderr, Name ": devices too large for RAID level %d\n", level); 
                                return 1;
                        }
                        size = minsize;
                        if (verbose > 0)
-                               fprintf(stderr, Name ": size set to %luK\n", size);
+                               fprintf(stderr, Name ": size set to %lluK\n", size);
                }
        }
        if (level > 0 && ((maxsize-size)*100 > maxsize)) {
                if (runstop != 1 || verbose >= 0)
-                       fprintf(stderr, Name ": largest drive (%s) exceed size (%luK) by more than 1%%\n",
+                       fprintf(stderr, Name ": largest drive (%s) exceed size (%lluK) by more than 1%%\n",
                                maxdisc, size);
                warn = 1;
        }
@@ -337,10 +337,10 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                 * .. but convert to sectors.
                 */
                int ncopies = (layout>>8) * (layout & 255);
-               bitmapsize = (unsigned long long)array.size * raiddisks / ncopies * 2;
-               printf("bms=%llu as=%d rd=%d nc=%d\n", bitmapsize, array.size, raiddisks, ncopies);
+               bitmapsize = (unsigned long long)size * raiddisks / ncopies * 2;
+/*             printf("bms=%llu as=%d rd=%d nc=%d\n", bitmapsize, size, raiddisks, ncopies);*/
        } else
-               bitmapsize = (unsigned long long)array.size * 2;
+               bitmapsize = (unsigned long long)size * 2;
 
        /* There is lots of redundancy in these disk counts,
         * raid_disks is the most meaningful value
@@ -368,7 +368,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
        array.chunk_size = chunk*1024;
        array.major_version = st->ss->major;
 
-       if (!st->ss->init_super(st, &super, &array, name))
+       if (!st->ss->init_super(st, &super, &array, size, name))
                return 1;
 
        if (bitmap_file && vers < 9003) {
diff --git a/Kill.c b/Kill.c
index 9f05e8bcfcbfa6851e038c052fb187714a64e2d1..95ab15ca374b0955724c86b7954a0d1ac0e8dd45 100644 (file)
--- a/Kill.c
+++ b/Kill.c
@@ -63,7 +63,7 @@ int Kill(char *dev, int force)
                mdu_array_info_t info;
                info.major_version = -1; /* zero superblock */
                free(super);
-               st->ss->init_super(st, &super, &info, "");
+               st->ss->init_super(st, &super, &info, 0, "");
                if (st->ss->store_super(st, fd, super)) {
                        fprintf(stderr, Name ": Could not zero superblock on %s\n",
                                dev);
diff --git a/mdadm.c b/mdadm.c
index 60e0c3e340dba6f4408f90fc287156995a9a834a..64e895eebc82303ad4a90695a8c2c6321ca4fc10 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -46,7 +46,7 @@ int main(int argc, char *argv[])
        int i;
 
        int chunk = 0;
-       int size = -1;
+       long long size = -1;
        int level = UnSet;
        int layout = UnSet;
        int raiddisks = 0;
@@ -347,7 +347,7 @@ int main(int argc, char *argv[])
                        if (strcmp(optarg, "max")==0)
                                size = 0;
                        else {
-                               size = strtol(optarg, &c, 10);
+                               size = strtoll(optarg, &c, 10);
                                if (!optarg[0] || *c || size < 4) {
                                        fprintf(stderr, Name ": invalid size: %s\n",
                                                optarg);
diff --git a/mdadm.h b/mdadm.h
index b643eada974a796d8d0f757044edbf737abfd589..f03454df7afc039dffc7372c0a1b029f1b0ab01b 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -186,7 +186,7 @@ extern struct superswitch {
        void (*getinfo_super)(struct mdinfo *info, mddev_ident_t ident, void *sbv);
        int (*update_super)(struct mdinfo *info, void *sbv, char *update, char *devname, int verbose);
        __u64 (*event_super)(void *sbv);
-       int (*init_super)(struct supertype *st, void **sbp, mdu_array_info_t *info, char *name);
+       int (*init_super)(struct supertype *st, void **sbp, mdu_array_info_t *info, unsigned long long size, 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);
@@ -254,7 +254,7 @@ extern int Build(char *mddev, int mdfd, int chunk, int level, int layout,
 
 
 extern int Create(struct supertype *st, char *mddev, int mdfd,
-                 int chunk, int level, int layout, unsigned long size, int raiddisks, int sparedisks,
+                 int chunk, int level, int layout, unsigned long long size, int raiddisks, int sparedisks,
                  char *name,
                  int subdevs, mddev_dev_t devlist,
                  int runstop, int verbose, int force, int assume_clean,
index 288485571742d5333e1e4b22a5268ca440ebe88b..aa7cdd986a36dcfb2f1333a420d0c0b0fadeb2d8 100644 (file)
--- a/super0.c
+++ b/super0.c
@@ -378,7 +378,7 @@ static __u64 event_super0(void *sbv)
 
 
 
-static int init_super0(struct supertype *st, void **sbp, mdu_array_info_t *info, char *ignored_name)
+static int init_super0(struct supertype *st, void **sbp, mdu_array_info_t *info, unsigned long long size, char *ignored_name)
 {
        mdp_super_t *sb = malloc(MD_SB_BYTES + sizeof(bitmap_super_t));
        int spares;
@@ -407,6 +407,8 @@ static int init_super0(struct supertype *st, void **sbp, mdu_array_info_t *info,
                sb->set_uuid0 = random();
        sb->ctime = time(0);
        sb->level = info->level;
+       if (size != info->size)
+               return 0;
        sb->size = info->size;
        sb->nr_disks = info->nr_disks;
        sb->raid_disks = info->raid_disks;
@@ -466,7 +468,7 @@ static int store_super0(struct supertype *st, int fd, void *sbv)
                        dsize = ((unsigned long long)size)<<9;
        }
 
-       if (dsize < MD_RESERVED_SECTORS*2)
+       if (dsize < MD_RESERVED_SECTORS*2*512)
                return 2;
        
        offset = MD_NEW_SIZE_SECTORS(dsize>>9);
index bb98bb9fba7c2e62d03bdc6428115d9794ba1b88..190ec60fe09bdbd8f17325d05672595f00ddd419 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -409,7 +409,7 @@ static __u64 event_super1(void *sbv)
        return __le64_to_cpu(sb->events);
 }
 
-static int init_super1(struct supertype *st, void **sbp, mdu_array_info_t *info, char *name)
+static int init_super1(struct supertype *st, void **sbp, mdu_array_info_t *info, unsigned long long size, char *name)
 {
        struct mdp_superblock_1 *sb = malloc(1024 + sizeof(bitmap_super_t));
        int spares;
@@ -448,7 +448,7 @@ static int init_super1(struct supertype *st, void **sbp, mdu_array_info_t *info,
        sb->ctime = __cpu_to_le64((unsigned long long)time(0));
        sb->level = __cpu_to_le32(info->level);
        sb->layout = __cpu_to_le32(info->layout);
-       sb->size = __cpu_to_le64(info->size*2ULL);
+       sb->size = __cpu_to_le64(size*2ULL);
        sb->chunksize = __cpu_to_le32(info->chunk_size>>9);
        sb->raid_disks = __cpu_to_le32(info->raid_disks);
 
@@ -491,13 +491,21 @@ static int store_super1(struct supertype *st, int fd, void *sbv)
        struct mdp_superblock_1 *sb = sbv;
        unsigned long long sb_offset;
        int sbsize;
-       long size;
-
-       if (ioctl(fd, BLKGETSIZE, &size))
-               return 1;
+       unsigned long size;
+       unsigned long long dsize;
 
+#ifdef BLKGETSIZE64
+       if (ioctl(fd, BLKGETSIZE64, &dsize) != 0)
+#endif
+       {
+               if (ioctl(fd, BLKGETSIZE, &size))
+                       return 1;
+               else
+                       dsize = (unsigned long long)size;
+       } else
+               dsize >>= 9;
 
-       if (size < 24)
+       if (dsize < 24)
                return 2;
 
        /*
@@ -510,7 +518,7 @@ static int store_super1(struct supertype *st, int fd, void *sbv)
         */
        switch(st->minor_version) {
        case 0:
-               sb_offset = size;
+               sb_offset = dsize;
                sb_offset -= 8*2;
                sb_offset &= ~(4*2-1);
                break;
@@ -556,7 +564,8 @@ static int write_init_super1(struct supertype *st, void *sbv,
        int rfd;
        int rv;
 
-       long size;
+       unsigned long size;
+       unsigned long long dsize;
        long long sb_offset;
 
 
@@ -592,12 +601,18 @@ static int write_init_super1(struct supertype *st, void *sbv,
                free(refsb);
        }
 
-       if (ioctl(fd, BLKGETSIZE, &size)) {
-               close(fd);
-               return 1;
-       }
+#ifdef BLKGETSIZE64
+       if (ioctl(fd, BLKGETSIZE64, &dsize) != 0)
+#endif
+       {
+               if (ioctl(fd, BLKGETSIZE, &size))
+                       return 1;
+               else
+                       dsize = size;
+       } else
+               dsize >>= 9;
 
-       if (size < 24) {
+       if (dsize < 24) {
                close(fd);
                return 2;
        }
@@ -613,7 +628,7 @@ static int write_init_super1(struct supertype *st, void *sbv,
         */
        switch(st->minor_version) {
        case 0:
-               sb_offset = size;
+               sb_offset = dsize;
                sb_offset -= 8*2;
                sb_offset &= ~(4*2-1);
                sb->super_offset = __cpu_to_le64(sb_offset);
@@ -623,13 +638,13 @@ static int write_init_super1(struct supertype *st, void *sbv,
        case 1:
                sb->super_offset = __cpu_to_le64(0);
                sb->data_offset = __cpu_to_le64(4*2); /* leave 4k for super and bitmap */
-               sb->data_size = __cpu_to_le64(size - 4*2);
+               sb->data_size = __cpu_to_le64(dsize - 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+4*2);
-               sb->data_size = __cpu_to_le64(size - 4*2 - 4*2);
+               sb->data_size = __cpu_to_le64(dsize - 4*2 - 4*2);
                break;
        default:
                return -EINVAL;
@@ -686,6 +701,7 @@ static int compare_super1(void **firstp, void *secondv)
 static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
 {
        unsigned long size;
+       unsigned long long dsize;
        unsigned long long sb_offset;
        struct mdp_superblock_1 *super;
 
@@ -723,17 +739,24 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
                st->ss = NULL;
                return 2;
        }
-       if (ioctl(fd, BLKGETSIZE, &size)) {
-               if (devname)
-                       fprintf(stderr, Name ": cannot find device size for %s: %s\n",
-                               devname, strerror(errno));
-               return 1;
-       }
+#ifdef BLKGETSIZE64
+       if (ioctl(fd, BLKGETSIZE64, &dsize) != 0)
+#endif
+       {
+               if (ioctl(fd, BLKGETSIZE, &size)) {
+                       if (devname)
+                               fprintf(stderr, Name ": cannot find device size for %s: %s\n",
+                                       devname, strerror(errno));
+                       return 1;
+               }
+               dsize = size;
+       } else
+               dsize >>= 9;
 
-       if (size < 24) {
+       if (dsize < 24) {
                if (devname)
-                       fprintf(stderr, Name ": %s is too small for md: size is %lu sectors.\n",
-                               devname, size);
+                       fprintf(stderr, Name ": %s is too small for md: size is %llu sectors.\n",
+                               devname, dsize);
                return 1;
        }
 
@@ -747,7 +770,7 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
         */
        switch(st->minor_version) {
        case 0:
-               sb_offset = size;
+               sb_offset = dsize;
                sb_offset -= 8*2;
                sb_offset &= ~(4*2-1);
                break;