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;
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);
if (!st->metadata ||
!st->metadata->ss->get_spare_criteria) {
sc->min_size = 0;
+ sc->sector_size = 0;
return 0;
}
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]))
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,
struct spare_criteria {
unsigned long long min_size;
+ unsigned int sector_size;
};
enum mode {
/*
* 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,
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);
/*
unsigned long long size = 0;
c->min_size = 0;
+ c->sector_size = 0;
if (!super)
return -EINVAL;
size += imsm_min_reserved_sectors(super);
c->min_size = size * 512;
+ c->sector_size = super->sector_size;
return 0;
}
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;
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);