summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Manage.c17
-rw-r--r--bitmap.c9
-rw-r--r--mdadm.h1
-rw-r--r--super1.c13
4 files changed, 31 insertions, 9 deletions
diff --git a/Manage.c b/Manage.c
index 1fb8468..12e24dd 100644
--- a/Manage.c
+++ b/Manage.c
@@ -344,14 +344,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
*/
@@ -381,6 +373,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 */