diff --git a/Manage.c b/Manage.c index 8297708..7b3fabe 100644 --- a/Manage.c +++ b/Manage.c @@ -349,14 +349,6 @@ int Manage_subdevs(char *devname, int fd, if (array.not_persistent == 0) { - /* Make sure device is large enough */ - if (tst->ss->avail_size(tst, ldsize/512) < - array_size) { - fprintf(stderr, Name ": %s not large enough to join array\n", - dv->devname); - return 1; - } - /* need to find a sample superblock to copy, and * a spare slot to use */ @@ -386,6 +378,15 @@ int Manage_subdevs(char *devname, int fd, fprintf(stderr, Name ": cannot find valid superblock in this array - HELP\n"); return 1; } + + /* Make sure device is large enough */ + if (tst->ss->avail_size(tst, ldsize/512) < + array_size) { + fprintf(stderr, Name ": %s not large enough to join array\n", + dv->devname); + return 1; + } + /* Possibly this device was recently part of the array * and was temporarily removed, and is now being re-added. * If so, we can simply re-add it. diff --git a/bitmap.c b/bitmap.c index fdf8884..b647939 100644 --- a/bitmap.c +++ b/bitmap.c @@ -115,6 +115,15 @@ unsigned long long bitmap_bits(unsigned long long array_size, return (array_size * 512 + chunksize - 1) / chunksize; } +unsigned long bitmap_sectors(struct bitmap_super_s *bsb) +{ + unsigned long long bits = bitmap_bits(__le64_to_cpu(bsb->sync_size), + __le32_to_cpu(bsb->chunksize)); + int bits_per_sector = 8*512; + return (bits + bits_per_sector - 1) / bits_per_sector; +} + + bitmap_info_t *bitmap_fd_read(int fd, int brief) { /* Note: fd might be open O_DIRECT, so we must be diff --git a/mdadm.h b/mdadm.h index 5c18d15..ce140e5 100644 --- a/mdadm.h +++ b/mdadm.h @@ -474,6 +474,7 @@ extern int CreateBitmap(char *filename, int force, char uuid[16], int major); extern int ExamineBitmap(char *filename, int brief, struct supertype *st); extern int bitmap_update_uuid(int fd, int *uuid, int swap); +extern unsigned long bitmap_sectors(struct bitmap_super_s *bsb); extern int md_get_version(int fd); extern int get_linux_version(void); diff --git a/super1.c b/super1.c index fe915f8..e1d0219 100644 --- a/super1.c +++ b/super1.c @@ -1214,10 +1214,21 @@ static struct supertype *match_metadata_desc1(char *arg) */ static __u64 avail_size1(struct supertype *st, __u64 devsize) { + struct mdp_superblock_1 *super = st->sb; if (devsize < 24) return 0; - devsize -= choose_bm_space(devsize); + if (super == NULL) + /* creating: allow suitable space for bitmap */ + devsize -= choose_bm_space(devsize); +#ifndef MDASSEMBLE + else if (__le32_to_cpu(super->feature_map)&MD_FEATURE_BITMAP_OFFSET) { + /* hot-add. allow for actual size of bitmap */ + struct bitmap_super_s *bsb; + bsb = (struct bitmap_super_s *)(((char*)super)+1024); + devsize -= bitmap_sectors(bsb); + } +#endif switch(st->minor_version) { case -1: /* no specified. Now time to set default */