summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2012-05-09 20:49:31 +1000
committerNeilBrown <neilb@suse.de>2012-05-09 20:49:31 +1000
commite041a07a544bb92d4f15e35c8dbc20a056f7ec9b (patch)
treece0a535f458aa872e32e6aff94cb3b232aff844e
parentf648834d137df59c4902fa2942be2dbad664a810 (diff)
downloadmdadm-e041a07a544bb92d4f15e35c8dbc20a056f7ec9b.tar.gz
Add data_offset arg to ->avail_size
This is currently only useful for 1.x metadata and will allow an explicit --data-offset request on command line. Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--Incremental.c5
-rw-r--r--Manage.c2
-rw-r--r--mdadm.h3
-rw-r--r--super-ddf.c5
-rw-r--r--super-intel.c5
-rw-r--r--super0.c5
-rw-r--r--super1.c25
7 files changed, 38 insertions, 12 deletions
diff --git a/Incremental.c b/Incremental.c
index a61f453..e3639f2 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -897,7 +897,10 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
close(mdfd);
}
if ((sra->component_size > 0 &&
- st2->ss->avail_size(st2, devsize) < sra->component_size)
+ st2->ss->avail_size(st2, devsize,
+ sra->devs
+ ? (long long)sra->devs->data_offset : -1)
+ < sra->component_size)
||
(sra->component_size == 0 && devsize < component_size)) {
if (verbose > 1)
diff --git a/Manage.c b/Manage.c
index 95aa270..19afba9 100644
--- a/Manage.c
+++ b/Manage.c
@@ -746,7 +746,7 @@ int Manage_subdevs(char *devname, int fd,
}
/* Make sure device is large enough */
- if (tst->ss->avail_size(tst, ldsize/512) <
+ if (tst->ss->avail_size(tst, ldsize/512, -1) <
array_size) {
close(tfd);
tfd = -1;
diff --git a/mdadm.h b/mdadm.h
index 4946d4e..410fc77 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -705,7 +705,8 @@ extern struct superswitch {
int (*load_super)(struct supertype *st, int fd, char *devname);
int (*load_container)(struct supertype *st, int fd, char *devname);
struct supertype * (*match_metadata_desc)(char *arg);
- __u64 (*avail_size)(struct supertype *st, __u64 size);
+ __u64 (*avail_size)(struct supertype *st, __u64 size,
+ long long data_offset);
unsigned long long (*min_acceptable_spare_size)(struct supertype *st);
int (*add_internal_bitmap)(struct supertype *st, int *chunkp,
int delay, int write_behind,
diff --git a/super-ddf.c b/super-ddf.c
index 5e51c4c..bfb0160 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -2497,7 +2497,8 @@ static int write_init_super_ddf(struct supertype *st)
#endif
-static __u64 avail_size_ddf(struct supertype *st, __u64 devsize)
+static __u64 avail_size_ddf(struct supertype *st, __u64 devsize,
+ long long data_offset)
{
/* We must reserve the last 32Meg */
if (devsize <= 32*1024*2)
@@ -2768,7 +2769,7 @@ validate_geometry_ddf_container(struct supertype *st,
}
close(fd);
- *freesize = avail_size_ddf(st, ldsize >> 9);
+ *freesize = avail_size_ddf(st, ldsize >> 9, -1);
if (*freesize == 0)
return 0;
diff --git a/super-intel.c b/super-intel.c
index e2ed95a..5ae48d0 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -2971,7 +2971,8 @@ static size_t disks_to_mpb_size(int disks)
return size;
}
-static __u64 avail_size_imsm(struct supertype *st, __u64 devsize)
+static __u64 avail_size_imsm(struct supertype *st, __u64 devsize,
+ long long data_offset)
{
if (devsize < (MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS))
return 0;
@@ -5383,7 +5384,7 @@ static int validate_geometry_imsm_container(struct supertype *st, int level,
}
}
- *freesize = avail_size_imsm(st, ldsize >> 9);
+ *freesize = avail_size_imsm(st, ldsize >> 9, -1);
free_imsm(super);
return 1;
diff --git a/super0.c b/super0.c
index 1375799..4da6fa9 100644
--- a/super0.c
+++ b/super0.c
@@ -981,8 +981,11 @@ static struct supertype *match_metadata_desc0(char *arg)
return NULL;
}
-static __u64 avail_size0(struct supertype *st, __u64 devsize)
+static __u64 avail_size0(struct supertype *st, __u64 devsize,
+ long long data_offset)
{
+ if (data_offset > 0)
+ return 0ULL;
if (devsize < MD_RESERVED_SECTORS)
return 0ULL;
return MD_NEW_SIZE_SECTORS(devsize);
diff --git a/super1.c b/super1.c
index be77c33..7fc91b2 100644
--- a/super1.c
+++ b/super1.c
@@ -1497,27 +1497,44 @@ 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)
+static __u64 avail_size1(struct supertype *st, __u64 devsize,
+ long long data_offset)
{
struct mdp_superblock_1 *super = st->sb;
+ int bmspace = 0;
if (devsize < 24)
return 0;
if (super == NULL)
/* creating: allow suitable space for bitmap */
- devsize -= choose_bm_space(devsize);
+ bmspace = 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)+MAX_SB_SIZE);
- devsize -= bitmap_sectors(bsb);
+ bmspace = bitmap_sectors(bsb);
}
#endif
+
if (st->minor_version < 0)
/* not specified, so time to set default */
st->minor_version = 2;
+
+ if (data_offset > 0)
+ switch(st->minor_version) {
+ case 0:
+ return devsize - data_offset - 8*2;
+ case 1:
+ case 2:
+ return devsize - data_offset;
+ default:
+ return 0;
+ }
+
+ devsize -= bmspace;
+
if (super == NULL && st->minor_version > 0) {
/* haven't committed to a size yet, so allow some
* slack for space for reshape.
@@ -1780,7 +1797,7 @@ static int validate_geometry1(struct supertype *st, int level,
}
close(fd);
- *freesize = avail_size1(st, ldsize >> 9);
+ *freesize = avail_size1(st, ldsize >> 9, -1);
return 1;
}
#endif /* MDASSEMBLE */