Enable support for v.large raid1.
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>
This commit is contained in:
parent
e5a5d81e4a
commit
5dd497eecb
20
Create.c
20
Create.c
|
@ -32,7 +32,7 @@
|
||||||
#include "md_p.h"
|
#include "md_p.h"
|
||||||
|
|
||||||
int Create(struct supertype *st, char *mddev, int mdfd,
|
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,
|
char *name,
|
||||||
int subdevs, mddev_dev_t devlist,
|
int subdevs, mddev_dev_t devlist,
|
||||||
int runstop, int verbose, int force, int assume_clean,
|
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;
|
mdu_array_info_t array;
|
||||||
int major = BITMAP_MAJOR_HI;
|
int major = BITMAP_MAJOR_HI;
|
||||||
|
|
||||||
memset(array, 0, sizeof(array));
|
memset(&array, 0, sizeof(array));
|
||||||
|
|
||||||
vers = md_get_version(mdfd);
|
vers = md_get_version(mdfd);
|
||||||
if (vers < 9000) {
|
if (vers < 9000) {
|
||||||
|
@ -231,7 +231,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
||||||
|
|
||||||
if (size && freesize < size) {
|
if (size && freesize < size) {
|
||||||
fprintf(stderr, Name ": %s is smaller that given 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;
|
fail = 1;
|
||||||
close(fd);
|
close(fd);
|
||||||
continue;
|
continue;
|
||||||
|
@ -262,18 +262,18 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
||||||
}
|
}
|
||||||
if (level > 0 || level == LEVEL_MULTIPATH || level == LEVEL_FAULTY) {
|
if (level > 0 || level == LEVEL_MULTIPATH || level == LEVEL_FAULTY) {
|
||||||
/* size is meaningful */
|
/* 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);
|
fprintf(stderr, Name ": devices too large for RAID level %d\n", level);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
size = minsize;
|
size = minsize;
|
||||||
if (verbose > 0)
|
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 (level > 0 && ((maxsize-size)*100 > maxsize)) {
|
||||||
if (runstop != 1 || verbose >= 0)
|
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);
|
maxdisc, size);
|
||||||
warn = 1;
|
warn = 1;
|
||||||
}
|
}
|
||||||
|
@ -337,10 +337,10 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
||||||
* .. but convert to sectors.
|
* .. but convert to sectors.
|
||||||
*/
|
*/
|
||||||
int ncopies = (layout>>8) * (layout & 255);
|
int ncopies = (layout>>8) * (layout & 255);
|
||||||
bitmapsize = (unsigned long long)array.size * raiddisks / ncopies * 2;
|
bitmapsize = (unsigned long long)size * raiddisks / ncopies * 2;
|
||||||
printf("bms=%llu as=%d rd=%d nc=%d\n", bitmapsize, array.size, raiddisks, ncopies);
|
/* printf("bms=%llu as=%d rd=%d nc=%d\n", bitmapsize, size, raiddisks, ncopies);*/
|
||||||
} else
|
} else
|
||||||
bitmapsize = (unsigned long long)array.size * 2;
|
bitmapsize = (unsigned long long)size * 2;
|
||||||
|
|
||||||
/* There is lots of redundancy in these disk counts,
|
/* There is lots of redundancy in these disk counts,
|
||||||
* raid_disks is the most meaningful value
|
* 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.chunk_size = chunk*1024;
|
||||||
array.major_version = st->ss->major;
|
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;
|
return 1;
|
||||||
|
|
||||||
if (bitmap_file && vers < 9003) {
|
if (bitmap_file && vers < 9003) {
|
||||||
|
|
2
Kill.c
2
Kill.c
|
@ -63,7 +63,7 @@ int Kill(char *dev, int force)
|
||||||
mdu_array_info_t info;
|
mdu_array_info_t info;
|
||||||
info.major_version = -1; /* zero superblock */
|
info.major_version = -1; /* zero superblock */
|
||||||
free(super);
|
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)) {
|
if (st->ss->store_super(st, fd, super)) {
|
||||||
fprintf(stderr, Name ": Could not zero superblock on %s\n",
|
fprintf(stderr, Name ": Could not zero superblock on %s\n",
|
||||||
dev);
|
dev);
|
||||||
|
|
4
mdadm.c
4
mdadm.c
|
@ -46,7 +46,7 @@ int main(int argc, char *argv[])
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
int chunk = 0;
|
int chunk = 0;
|
||||||
int size = -1;
|
long long size = -1;
|
||||||
int level = UnSet;
|
int level = UnSet;
|
||||||
int layout = UnSet;
|
int layout = UnSet;
|
||||||
int raiddisks = 0;
|
int raiddisks = 0;
|
||||||
|
@ -347,7 +347,7 @@ int main(int argc, char *argv[])
|
||||||
if (strcmp(optarg, "max")==0)
|
if (strcmp(optarg, "max")==0)
|
||||||
size = 0;
|
size = 0;
|
||||||
else {
|
else {
|
||||||
size = strtol(optarg, &c, 10);
|
size = strtoll(optarg, &c, 10);
|
||||||
if (!optarg[0] || *c || size < 4) {
|
if (!optarg[0] || *c || size < 4) {
|
||||||
fprintf(stderr, Name ": invalid size: %s\n",
|
fprintf(stderr, Name ": invalid size: %s\n",
|
||||||
optarg);
|
optarg);
|
||||||
|
|
4
mdadm.h
4
mdadm.h
|
@ -186,7 +186,7 @@ extern struct superswitch {
|
||||||
void (*getinfo_super)(struct mdinfo *info, mddev_ident_t ident, void *sbv);
|
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);
|
int (*update_super)(struct mdinfo *info, void *sbv, char *update, char *devname, int verbose);
|
||||||
__u64 (*event_super)(void *sbv);
|
__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);
|
void (*add_to_super)(void *sbv, mdu_disk_info_t *dinfo);
|
||||||
int (*store_super)(struct supertype *st, int fd, void *sbv);
|
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 (*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,
|
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,
|
char *name,
|
||||||
int subdevs, mddev_dev_t devlist,
|
int subdevs, mddev_dev_t devlist,
|
||||||
int runstop, int verbose, int force, int assume_clean,
|
int runstop, int verbose, int force, int assume_clean,
|
||||||
|
|
6
super0.c
6
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));
|
mdp_super_t *sb = malloc(MD_SB_BYTES + sizeof(bitmap_super_t));
|
||||||
int spares;
|
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->set_uuid0 = random();
|
||||||
sb->ctime = time(0);
|
sb->ctime = time(0);
|
||||||
sb->level = info->level;
|
sb->level = info->level;
|
||||||
|
if (size != info->size)
|
||||||
|
return 0;
|
||||||
sb->size = info->size;
|
sb->size = info->size;
|
||||||
sb->nr_disks = info->nr_disks;
|
sb->nr_disks = info->nr_disks;
|
||||||
sb->raid_disks = info->raid_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;
|
dsize = ((unsigned long long)size)<<9;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dsize < MD_RESERVED_SECTORS*2)
|
if (dsize < MD_RESERVED_SECTORS*2*512)
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
offset = MD_NEW_SIZE_SECTORS(dsize>>9);
|
offset = MD_NEW_SIZE_SECTORS(dsize>>9);
|
||||||
|
|
77
super1.c
77
super1.c
|
@ -409,7 +409,7 @@ static __u64 event_super1(void *sbv)
|
||||||
return __le64_to_cpu(sb->events);
|
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));
|
struct mdp_superblock_1 *sb = malloc(1024 + sizeof(bitmap_super_t));
|
||||||
int spares;
|
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->ctime = __cpu_to_le64((unsigned long long)time(0));
|
||||||
sb->level = __cpu_to_le32(info->level);
|
sb->level = __cpu_to_le32(info->level);
|
||||||
sb->layout = __cpu_to_le32(info->layout);
|
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->chunksize = __cpu_to_le32(info->chunk_size>>9);
|
||||||
sb->raid_disks = __cpu_to_le32(info->raid_disks);
|
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;
|
struct mdp_superblock_1 *sb = sbv;
|
||||||
unsigned long long sb_offset;
|
unsigned long long sb_offset;
|
||||||
int sbsize;
|
int sbsize;
|
||||||
long size;
|
unsigned long size;
|
||||||
|
unsigned long long dsize;
|
||||||
|
|
||||||
if (ioctl(fd, BLKGETSIZE, &size))
|
#ifdef BLKGETSIZE64
|
||||||
return 1;
|
if (ioctl(fd, BLKGETSIZE64, &dsize) != 0)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (ioctl(fd, BLKGETSIZE, &size))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
dsize = (unsigned long long)size;
|
||||||
|
} else
|
||||||
|
dsize >>= 9;
|
||||||
|
|
||||||
|
if (dsize < 24)
|
||||||
if (size < 24)
|
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -510,7 +518,7 @@ static int store_super1(struct supertype *st, int fd, void *sbv)
|
||||||
*/
|
*/
|
||||||
switch(st->minor_version) {
|
switch(st->minor_version) {
|
||||||
case 0:
|
case 0:
|
||||||
sb_offset = size;
|
sb_offset = dsize;
|
||||||
sb_offset -= 8*2;
|
sb_offset -= 8*2;
|
||||||
sb_offset &= ~(4*2-1);
|
sb_offset &= ~(4*2-1);
|
||||||
break;
|
break;
|
||||||
|
@ -556,7 +564,8 @@ static int write_init_super1(struct supertype *st, void *sbv,
|
||||||
int rfd;
|
int rfd;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
long size;
|
unsigned long size;
|
||||||
|
unsigned long long dsize;
|
||||||
long long sb_offset;
|
long long sb_offset;
|
||||||
|
|
||||||
|
|
||||||
|
@ -592,12 +601,18 @@ static int write_init_super1(struct supertype *st, void *sbv,
|
||||||
free(refsb);
|
free(refsb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl(fd, BLKGETSIZE, &size)) {
|
#ifdef BLKGETSIZE64
|
||||||
close(fd);
|
if (ioctl(fd, BLKGETSIZE64, &dsize) != 0)
|
||||||
return 1;
|
#endif
|
||||||
}
|
{
|
||||||
|
if (ioctl(fd, BLKGETSIZE, &size))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
dsize = size;
|
||||||
|
} else
|
||||||
|
dsize >>= 9;
|
||||||
|
|
||||||
if (size < 24) {
|
if (dsize < 24) {
|
||||||
close(fd);
|
close(fd);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
@ -613,7 +628,7 @@ static int write_init_super1(struct supertype *st, void *sbv,
|
||||||
*/
|
*/
|
||||||
switch(st->minor_version) {
|
switch(st->minor_version) {
|
||||||
case 0:
|
case 0:
|
||||||
sb_offset = size;
|
sb_offset = dsize;
|
||||||
sb_offset -= 8*2;
|
sb_offset -= 8*2;
|
||||||
sb_offset &= ~(4*2-1);
|
sb_offset &= ~(4*2-1);
|
||||||
sb->super_offset = __cpu_to_le64(sb_offset);
|
sb->super_offset = __cpu_to_le64(sb_offset);
|
||||||
|
@ -623,13 +638,13 @@ static int write_init_super1(struct supertype *st, void *sbv,
|
||||||
case 1:
|
case 1:
|
||||||
sb->super_offset = __cpu_to_le64(0);
|
sb->super_offset = __cpu_to_le64(0);
|
||||||
sb->data_offset = __cpu_to_le64(4*2); /* leave 4k for super and bitmap */
|
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;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
sb_offset = 4*2;
|
sb_offset = 4*2;
|
||||||
sb->super_offset = __cpu_to_le64(sb_offset);
|
sb->super_offset = __cpu_to_le64(sb_offset);
|
||||||
sb->data_offset = __cpu_to_le64(sb_offset+4*2);
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
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)
|
static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
|
||||||
{
|
{
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
|
unsigned long long dsize;
|
||||||
unsigned long long sb_offset;
|
unsigned long long sb_offset;
|
||||||
struct mdp_superblock_1 *super;
|
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;
|
st->ss = NULL;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
if (ioctl(fd, BLKGETSIZE, &size)) {
|
#ifdef BLKGETSIZE64
|
||||||
if (devname)
|
if (ioctl(fd, BLKGETSIZE64, &dsize) != 0)
|
||||||
fprintf(stderr, Name ": cannot find device size for %s: %s\n",
|
#endif
|
||||||
devname, strerror(errno));
|
{
|
||||||
return 1;
|
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)
|
if (devname)
|
||||||
fprintf(stderr, Name ": %s is too small for md: size is %lu sectors.\n",
|
fprintf(stderr, Name ": %s is too small for md: size is %llu sectors.\n",
|
||||||
devname, size);
|
devname, dsize);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,7 +770,7 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
|
||||||
*/
|
*/
|
||||||
switch(st->minor_version) {
|
switch(st->minor_version) {
|
||||||
case 0:
|
case 0:
|
||||||
sb_offset = size;
|
sb_offset = dsize;
|
||||||
sb_offset -= 8*2;
|
sb_offset -= 8*2;
|
||||||
sb_offset &= ~(4*2-1);
|
sb_offset &= ~(4*2-1);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue