Add sector size as spare selection criterion
Add sector size as new spare selection criterion. Assume that 0 means there is no requirement for the sector size in the array. Skip disks with unsuitable sector size when looking for a spare to move across containers. Signed-off-by: Alexey Obitotskiy <aleksey.obitotskiy@intel.com> Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com> Signed-off-by: Jes Sorensen <jsorensen@fb.com>
This commit is contained in:
parent
fbfdcb06dc
commit
4b57ecf6ce
|
@ -867,7 +867,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
|
|||
struct domainlist *dl = NULL;
|
||||
struct mdinfo *sra;
|
||||
unsigned long long devsize;
|
||||
struct spare_criteria sc = {0};
|
||||
struct spare_criteria sc = {0, 0};
|
||||
|
||||
if (is_subarray(mp->metadata))
|
||||
continue;
|
||||
|
@ -1627,7 +1627,7 @@ static int Incremental_container(struct supertype *st, char *devname,
|
|||
struct mdinfo *sinfo;
|
||||
|
||||
if (!sst->ss->load_container(sst, sfd, NULL)) {
|
||||
struct spare_criteria sc = {0};
|
||||
struct spare_criteria sc = {0, 0};
|
||||
|
||||
if (st->ss->get_spare_criteria)
|
||||
st->ss->get_spare_criteria(st, &sc);
|
||||
|
|
|
@ -731,6 +731,7 @@ static int get_required_spare_criteria(struct state *st,
|
|||
if (!st->metadata ||
|
||||
!st->metadata->ss->get_spare_criteria) {
|
||||
sc->min_size = 0;
|
||||
sc->sector_size = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -787,6 +788,7 @@ static dev_t choose_spare(struct state *from, struct state *to,
|
|||
from->devstate[d] == 0) {
|
||||
struct dev_policy *pol;
|
||||
unsigned long long dev_size;
|
||||
unsigned int dev_sector_size;
|
||||
|
||||
if (to->metadata->ss->external &&
|
||||
test_partition_from_id(from->devid[d]))
|
||||
|
@ -797,6 +799,12 @@ static dev_t choose_spare(struct state *from, struct state *to,
|
|||
dev_size < sc->min_size)
|
||||
continue;
|
||||
|
||||
if (sc->sector_size &&
|
||||
dev_sector_size_from_id(from->devid[d],
|
||||
&dev_sector_size) &&
|
||||
sc->sector_size != dev_sector_size)
|
||||
continue;
|
||||
|
||||
pol = devid_policy(from->devid[d]);
|
||||
if (from->spare_group)
|
||||
pol_add(&pol, pol_domain,
|
||||
|
|
3
mdadm.h
3
mdadm.h
|
@ -363,6 +363,7 @@ struct createinfo {
|
|||
|
||||
struct spare_criteria {
|
||||
unsigned long long min_size;
|
||||
unsigned int sector_size;
|
||||
};
|
||||
|
||||
enum mode {
|
||||
|
@ -947,6 +948,7 @@ extern struct superswitch {
|
|||
/*
|
||||
* Return spare criteria for array:
|
||||
* - minimum disk size can be used in array;
|
||||
* - sector size can be used in array.
|
||||
* Return values: 0 - for success and -EINVAL on error.
|
||||
*/
|
||||
int (*get_spare_criteria)(struct supertype *st,
|
||||
|
@ -1189,6 +1191,7 @@ extern int get_dev_size(int fd, char *dname, unsigned long long *sizep);
|
|||
extern int get_dev_sector_size(int fd, char *dname, unsigned int *sectsizep);
|
||||
extern int must_be_container(int fd);
|
||||
extern int dev_size_from_id(dev_t id, unsigned long long *size);
|
||||
extern int dev_sector_size_from_id(dev_t id, unsigned int *size);
|
||||
void wait_for(char *dev, int fd);
|
||||
|
||||
/*
|
||||
|
|
|
@ -1396,6 +1396,7 @@ int get_spare_criteria_imsm(struct supertype *st, struct spare_criteria *c)
|
|||
unsigned long long size = 0;
|
||||
|
||||
c->min_size = 0;
|
||||
c->sector_size = 0;
|
||||
|
||||
if (!super)
|
||||
return -EINVAL;
|
||||
|
@ -1419,6 +1420,7 @@ int get_spare_criteria_imsm(struct supertype *st, struct spare_criteria *c)
|
|||
size += imsm_min_reserved_sectors(super);
|
||||
|
||||
c->min_size = size * 512;
|
||||
c->sector_size = super->sector_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
31
util.c
31
util.c
|
@ -1265,6 +1265,23 @@ int dev_size_from_id(dev_t id, unsigned long long *size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int dev_sector_size_from_id(dev_t id, unsigned int *size)
|
||||
{
|
||||
char buf[20];
|
||||
int fd;
|
||||
|
||||
sprintf(buf, "%d:%d", major(id), minor(id));
|
||||
fd = dev_open(buf, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
if (get_dev_sector_size(fd, NULL, size)) {
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct supertype *dup_super(struct supertype *orig)
|
||||
{
|
||||
struct supertype *st;
|
||||
|
@ -2129,12 +2146,24 @@ struct mdinfo *container_choose_spares(struct supertype *st,
|
|||
if (d->disk.state == 0) {
|
||||
/* check if size is acceptable */
|
||||
unsigned long long dev_size;
|
||||
unsigned int dev_sector_size;
|
||||
int size_valid = 0;
|
||||
int sector_size_valid = 0;
|
||||
|
||||
dev_t dev = makedev(d->disk.major,d->disk.minor);
|
||||
|
||||
if (!criteria->min_size ||
|
||||
(dev_size_from_id(dev, &dev_size) &&
|
||||
dev_size >= criteria->min_size))
|
||||
found = 1;
|
||||
size_valid = 1;
|
||||
|
||||
if (!criteria->sector_size ||
|
||||
(dev_sector_size_from_id(dev, &dev_sector_size) &&
|
||||
criteria->sector_size == dev_sector_size))
|
||||
sector_size_valid = 1;
|
||||
|
||||
found = size_valid && sector_size_valid;
|
||||
|
||||
/* check if domain matches */
|
||||
if (found && domlist) {
|
||||
struct dev_policy *pol = devid_policy(dev);
|
||||
|
|
Loading…
Reference in New Issue