summaryrefslogtreecommitdiff
path: root/Monitor.c
diff options
context:
space:
mode:
authorAnna Czarnowska <anna.czarnowska@intel.com>2010-11-22 20:58:07 +1100
committerNeilBrown <neilb@suse.de>2010-11-22 20:58:07 +1100
commit80e7f8c31a514b02d227a083cb2bcb34f70c0eee (patch)
treee093b53221d5535f604d69d37b10038dee60b62e /Monitor.c
parent66f5c4b66562cfbe0f0fb65a9bfabb17441ae23e (diff)
Monitor: Allow metadata to set minimum size for spare to migrate in.
Signed-off-by: Anna Czarnowska <anna.czarnowska@intel.com> Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Monitor.c')
-rw-r--r--Monitor.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/Monitor.c b/Monitor.c
index 793087e0..b907cf2d 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -681,12 +681,33 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state *statelist,
return new_found;
}
+unsigned long long min_spare_size_required(struct state *st)
+{
+ int fd;
+ unsigned long long rv = 0;
+
+ if (!st->metadata ||
+ !st->metadata->ss->min_acceptable_spare_size)
+ return rv;
+
+ fd = open(st->devname, O_RDONLY);
+ if (fd < 0)
+ return 0;
+ st->metadata->ss->load_super(st->metadata, fd, st->devname);
+ close(fd);
+ rv = st->metadata->ss->min_acceptable_spare_size(st->metadata);
+ st->metadata->ss->free_super(st->metadata);
+
+ return rv;
+}
+
static int move_spare(struct state *from, struct state *to,
struct domainlist *domlist,
struct alert_info *info)
{
struct mddev_dev devlist;
char devname[20];
+ unsigned long long min_size;
/* try to remove and add */
int fd1 = open(to->devname, O_RDONLY);
@@ -698,10 +719,19 @@ static int move_spare(struct state *from, struct state *to,
if (fd2>=0) close(fd2);
return 0;
}
+ min_size = min_spare_size_required(to);
for (d = from->raid; dev < 0 && d < MaxDisks; d++) {
if (from->devid[d] > 0 &&
from->devstate[d] == 0) {
- struct dev_policy *pol = devnum_policy(from->devid[d]);
+ struct dev_policy *pol;
+ unsigned long long dev_size;
+
+ if (min_size &&
+ dev_size_from_id(from->devid[d], &dev_size) &&
+ dev_size < min_size)
+ continue;
+
+ pol = devnum_policy(from->devid[d]);
pol_add(&pol, pol_domain, from->spare_group, NULL);
if (domain_test(domlist, pol, to->metadata->ss->name))
dev = from->devid[d];