btrfs_cmp_device_info, NULL);
} else {
/*
- * If PREFERRED_METADATA is set, sort the device
- * considering also the kind (preferred_metadata or
- * not). Limit the availables devices to the ones of the
- * requested kind, to prevent metadata appearing on a
- * non-preferred device, or data appearing on a preferred
- * device.
+ * if PREFERRED_METADATA is set, sort the device considering
+ * also the kind (preferred_metadata or not). Limit the
+ * availables devices to the ones of the same kind, to avoid
+ * that a striped profile, like raid5, spreads to all kind of
+ * devices.
+ * It is allowed to use different kinds of devices if the ones
+ * of the same kind are not enough alone.
*/
if (ctl->type & BTRFS_BLOCK_GROUP_DATA) {
int nr_data = ctl->ndevs - nr_preferred_metadata;
sort(devices_info, ctl->ndevs,
sizeof(struct btrfs_device_info),
btrfs_cmp_device_info_data, NULL);
- ctl->ndevs = nr_data;
+ if (nr_data >= ctl->devs_min)
+ ctl->ndevs = nr_data;
} else { /* non data -> metadata and system */
sort(devices_info, ctl->ndevs,
sizeof(struct btrfs_device_info),
btrfs_cmp_device_info_metadata, NULL);
- if (nr_preferred_metadata)
+ if (nr_preferred_metadata >= ctl->devs_min)
ctl->ndevs = nr_preferred_metadata;
}
}