Adding upstream version 4.2+20230901.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
14fbe53fb1
commit
f48db6685a
15 changed files with 418 additions and 196 deletions
14
Assemble.c
14
Assemble.c
|
@ -341,8 +341,10 @@ static int select_devices(struct mddev_dev *devlist,
|
|||
st->ss->free_super(st);
|
||||
dev_policy_free(pol);
|
||||
domain_free(domains);
|
||||
if (tst)
|
||||
if (tst) {
|
||||
tst->ss->free_super(tst);
|
||||
free(tst);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -417,6 +419,7 @@ static int select_devices(struct mddev_dev *devlist,
|
|||
st->ss->free_super(st);
|
||||
dev_policy_free(pol);
|
||||
domain_free(domains);
|
||||
free(st);
|
||||
return -1;
|
||||
}
|
||||
if (c->verbose > 0)
|
||||
|
@ -425,6 +428,8 @@ static int select_devices(struct mddev_dev *devlist,
|
|||
|
||||
/* make sure we finished the loop */
|
||||
tmpdev = NULL;
|
||||
free(st);
|
||||
st = NULL;
|
||||
goto loop;
|
||||
} else {
|
||||
content = *contentp;
|
||||
|
@ -533,6 +538,7 @@ static int select_devices(struct mddev_dev *devlist,
|
|||
st->ss->free_super(st);
|
||||
dev_policy_free(pol);
|
||||
domain_free(domains);
|
||||
free(tst);
|
||||
return -1;
|
||||
}
|
||||
tmpdev->used = 1;
|
||||
|
@ -546,8 +552,10 @@ static int select_devices(struct mddev_dev *devlist,
|
|||
}
|
||||
dev_policy_free(pol);
|
||||
pol = NULL;
|
||||
if (tst)
|
||||
if (tst) {
|
||||
tst->ss->free_super(tst);
|
||||
free(tst);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if we found some imsm spares but no members */
|
||||
|
@ -839,6 +847,7 @@ static int load_devices(struct devs *devices, char *devmap,
|
|||
close(mdfd);
|
||||
free(devices);
|
||||
free(devmap);
|
||||
free(best);
|
||||
*stp = st;
|
||||
return -1;
|
||||
}
|
||||
|
@ -1950,6 +1959,7 @@ out:
|
|||
} else if (mdfd >= 0)
|
||||
close(mdfd);
|
||||
|
||||
free(best);
|
||||
/* '2' means 'OK, but not started yet' */
|
||||
if (rv == -1) {
|
||||
free(devices);
|
||||
|
|
9
Kill.c
9
Kill.c
|
@ -41,6 +41,7 @@ int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl)
|
|||
* 4 - failed to find a superblock.
|
||||
*/
|
||||
|
||||
bool free_super = false;
|
||||
int fd, rv = 0;
|
||||
|
||||
if (force)
|
||||
|
@ -52,8 +53,10 @@ int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl)
|
|||
dev);
|
||||
return 2;
|
||||
}
|
||||
if (st == NULL)
|
||||
if (st == NULL) {
|
||||
st = guess_super(fd);
|
||||
free_super = true;
|
||||
}
|
||||
if (st == NULL || st->ss->init_super == NULL) {
|
||||
if (verbose >= 0)
|
||||
pr_err("Unrecognised md component device - %s\n", dev);
|
||||
|
@ -77,6 +80,10 @@ int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl)
|
|||
rv = 0;
|
||||
}
|
||||
}
|
||||
if (free_super && st) {
|
||||
st->ss->free_super(st);
|
||||
free(st);
|
||||
}
|
||||
close(fd);
|
||||
return rv;
|
||||
}
|
||||
|
|
13
Manage.c
13
Manage.c
|
@ -222,6 +222,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
|
|||
if (verbose >= 0)
|
||||
pr_err("Cannot get exclusive access to %s:Perhaps a running process, mounted filesystem or active volume group?\n",
|
||||
devname);
|
||||
sysfs_free(mdi);
|
||||
return 1;
|
||||
}
|
||||
/* If this is an mdmon managed array, just write 'inactive'
|
||||
|
@ -801,10 +802,16 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
|
|||
rdev, update, devname,
|
||||
verbose, array);
|
||||
dev_st->ss->free_super(dev_st);
|
||||
if (rv)
|
||||
if (rv) {
|
||||
free(dev_st);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
if (dev_st) {
|
||||
dev_st->ss->free_super(dev_st);
|
||||
free(dev_st);
|
||||
}
|
||||
}
|
||||
if (dv->disposition == 'M') {
|
||||
if (verbose > 0)
|
||||
pr_err("--re-add for %s to %s is not possible\n",
|
||||
|
@ -1362,7 +1369,7 @@ int Manage_subdevs(char *devname, int fd,
|
|||
unsigned long long array_size;
|
||||
struct mddev_dev *dv;
|
||||
int tfd = -1;
|
||||
struct supertype *tst;
|
||||
struct supertype *tst = NULL;
|
||||
char *subarray = NULL;
|
||||
int sysfd = -1;
|
||||
int count = 0; /* number of actions taken */
|
||||
|
@ -1699,6 +1706,7 @@ int Manage_subdevs(char *devname, int fd,
|
|||
break;
|
||||
}
|
||||
}
|
||||
free(tst);
|
||||
if (frozen > 0)
|
||||
sysfs_set_str(&info, NULL, "sync_action","idle");
|
||||
if (test && count == 0)
|
||||
|
@ -1706,6 +1714,7 @@ int Manage_subdevs(char *devname, int fd,
|
|||
return 0;
|
||||
|
||||
abort:
|
||||
free(tst);
|
||||
if (frozen > 0)
|
||||
sysfs_set_str(&info, NULL, "sync_action","idle");
|
||||
return !test && busy ? 2 : 1;
|
||||
|
|
|
@ -222,11 +222,10 @@ int Monitor(struct mddev_dev *devlist,
|
|||
info.dosyslog = dosyslog;
|
||||
info.test = c->test;
|
||||
|
||||
if (gethostname(info.hostname, sizeof(info.hostname)) != 0) {
|
||||
if (s_gethostname(info.hostname, sizeof(info.hostname)) != 0) {
|
||||
pr_err("Cannot get hostname.\n");
|
||||
return 1;
|
||||
}
|
||||
info.hostname[sizeof(info.hostname) - 1] = '\0';
|
||||
|
||||
if (share){
|
||||
if (check_one_sharer(c->scan) == 2)
|
||||
|
|
19
lib.c
19
lib.c
|
@ -585,3 +585,22 @@ int parse_num(int *dest, const char *num)
|
|||
*dest = temp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* s_gethostname() - secure get hostname. Assure null-terminated string.
|
||||
*
|
||||
* @buf: buffer for hostname.
|
||||
* @buf_len: buffer length.
|
||||
*
|
||||
* Return: gethostname() result.
|
||||
*/
|
||||
int s_gethostname(char *buf, int buf_len)
|
||||
{
|
||||
assert(buf);
|
||||
|
||||
int ret = gethostname(buf, buf_len);
|
||||
|
||||
buf[buf_len - 1] = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -363,8 +363,7 @@ void RebuildMap(void)
|
|||
char *homehost = conf_get_homehost(&require_homehost);
|
||||
|
||||
if (homehost == NULL || strcmp(homehost, "<system>")==0) {
|
||||
if (gethostname(sys_hostname, sizeof(sys_hostname)) == 0) {
|
||||
sys_hostname[sizeof(sys_hostname)-1] = 0;
|
||||
if (s_gethostname(sys_hostname, sizeof(sys_hostname)) == 0) {
|
||||
homehost = sys_hostname;
|
||||
}
|
||||
}
|
||||
|
|
7
mdadm.c
7
mdadm.c
|
@ -1340,8 +1340,7 @@ int main(int argc, char *argv[])
|
|||
if (c.homehost == NULL && c.require_homehost)
|
||||
c.homehost = conf_get_homehost(&c.require_homehost);
|
||||
if (c.homehost == NULL || strcasecmp(c.homehost, "<system>") == 0) {
|
||||
if (gethostname(sys_hostname, sizeof(sys_hostname)) == 0) {
|
||||
sys_hostname[sizeof(sys_hostname)-1] = 0;
|
||||
if (s_gethostname(sys_hostname, sizeof(sys_hostname)) == 0) {
|
||||
c.homehost = sys_hostname;
|
||||
}
|
||||
}
|
||||
|
@ -1709,6 +1708,10 @@ int main(int argc, char *argv[])
|
|||
autodetect();
|
||||
break;
|
||||
}
|
||||
if (ss) {
|
||||
ss->ss->free_super(ss);
|
||||
free(ss);
|
||||
}
|
||||
if (locked)
|
||||
cluster_release_dlmlock();
|
||||
close_fd(&mdfd);
|
||||
|
|
1
mdadm.h
1
mdadm.h
|
@ -1805,6 +1805,7 @@ extern void set_dlm_hooks(void);
|
|||
extern void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt);
|
||||
extern bool is_directory(const char *path);
|
||||
extern bool is_file(const char *path);
|
||||
extern int s_gethostname(char *buf, int buf_len);
|
||||
|
||||
#define _ROUND_UP(val, base) (((val) + (base) - 1) & ~(base - 1))
|
||||
#define ROUND_UP(val, base) _ROUND_UP(val, (typeof(val))(base))
|
||||
|
|
6
mdmon.c
6
mdmon.c
|
@ -240,7 +240,7 @@ static int make_control_sock(char *devname)
|
|||
return -1;
|
||||
|
||||
addr.sun_family = PF_LOCAL;
|
||||
strcpy(addr.sun_path, path);
|
||||
snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path);
|
||||
umask(077); /* ensure no world write access */
|
||||
if (bind(sfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
||||
close(sfd);
|
||||
|
@ -389,7 +389,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
if (all) {
|
||||
struct mdstat_ent *mdstat, *e;
|
||||
int container_len = strlen(container_name);
|
||||
int container_len = strnlen(container_name, MD_NAME_MAX);
|
||||
|
||||
/* launch an mdmon instance for each container found */
|
||||
mdstat = mdstat_read(0, 0);
|
||||
|
@ -472,7 +472,7 @@ static int mdmon(char *devnm, int must_fork, int takeover)
|
|||
pfd[0] = pfd[1] = -1;
|
||||
|
||||
container = xcalloc(1, sizeof(*container));
|
||||
strcpy(container->devnm, devnm);
|
||||
snprintf(container->devnm, MD_NAME_MAX, "%s", devnm);
|
||||
container->arrays = NULL;
|
||||
container->sock = -1;
|
||||
|
||||
|
|
4
mdopen.c
4
mdopen.c
|
@ -193,14 +193,14 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
|
|||
|
||||
if (dev) {
|
||||
if (strncmp(dev, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) {
|
||||
strcpy(cname, dev + DEV_MD_DIR_LEN);
|
||||
snprintf(cname, MD_NAME_MAX, "%s", dev + DEV_MD_DIR_LEN);
|
||||
} else if (strncmp(dev, "/dev/", 5) == 0) {
|
||||
char *e = dev + strlen(dev);
|
||||
while (e > dev && isdigit(e[-1]))
|
||||
e--;
|
||||
if (e[0])
|
||||
num = strtoul(e, NULL, 10);
|
||||
strcpy(cname, dev+5);
|
||||
snprintf(cname, MD_NAME_MAX, "%s", dev + 5);
|
||||
cname[e-(dev+5)] = 0;
|
||||
/* name *must* be mdXX or md_dXX in this context */
|
||||
if (num < 0 ||
|
||||
|
|
|
@ -140,7 +140,13 @@ do
|
|||
echo $a > $fl
|
||||
any=yes
|
||||
done
|
||||
if [ -z "$any" ]; then exit 0; fi
|
||||
# mdcheck_continue.timer is started by mdcheck_start.timer.
|
||||
# When the check action can be finished in mdcheck_start.service,
|
||||
# it doesn't need mdcheck_continue anymore.
|
||||
if [ -z "$any" ]; then
|
||||
systemctl stop mdcheck_continue.timer
|
||||
exit 0;
|
||||
fi
|
||||
sleep 120
|
||||
done
|
||||
|
||||
|
|
119
platform-intel.c
119
platform-intel.c
|
@ -214,7 +214,7 @@ struct sys_dev *device_by_id_and_path(__u16 device_id, const char *path)
|
|||
|
||||
static int devpath_to_ll(const char *dev_path, const char *entry, unsigned long long *val)
|
||||
{
|
||||
char path[strlen(dev_path) + strlen(entry) + 2];
|
||||
char path[strnlen(dev_path, PATH_MAX) + strnlen(entry, PATH_MAX) + 2];
|
||||
int fd;
|
||||
int n;
|
||||
|
||||
|
@ -510,9 +510,6 @@ static const struct imsm_orom *find_imsm_hba_orom(struct sys_dev *hba)
|
|||
return get_orom_by_device_id(hba->dev_id);
|
||||
}
|
||||
|
||||
#define GUID_STR_MAX 37 /* according to GUID format:
|
||||
* xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" */
|
||||
|
||||
#define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
|
||||
((struct efi_guid) \
|
||||
{{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
|
||||
|
@ -703,6 +700,106 @@ const struct imsm_orom *find_imsm_nvme(struct sys_dev *hba)
|
|||
return &nvme_orom->orom;
|
||||
}
|
||||
|
||||
#define VMD_REGISTER_OFFSET 0x3FC
|
||||
#define VMD_REGISTER_SKU_SHIFT 1
|
||||
#define VMD_REGISTER_SKU_MASK (0x00000007)
|
||||
#define VMD_REGISTER_SKU_PREMIUM 2
|
||||
#define MD_REGISTER_VER_MAJOR_SHIFT 4
|
||||
#define MD_REGISTER_VER_MAJOR_MASK (0x0000000F)
|
||||
#define MD_REGISTER_VER_MINOR_SHIFT 8
|
||||
#define MD_REGISTER_VER_MINOR_MASK (0x0000000F)
|
||||
|
||||
/*
|
||||
* read_vmd_register() - Reads VMD register and writes contents to buff ptr
|
||||
* @buff: buffer for vmd register data, should be the size of uint32_t
|
||||
*
|
||||
* Return: 0 on success, 1 on error
|
||||
*/
|
||||
int read_vmd_register(uint32_t *buff, struct sys_dev *hba)
|
||||
{
|
||||
int fd;
|
||||
char vmd_pci_config_path[PATH_MAX];
|
||||
|
||||
if (!vmd_domain_to_controller(hba, vmd_pci_config_path))
|
||||
return 1;
|
||||
|
||||
strncat(vmd_pci_config_path, "/config", PATH_MAX - strnlen(vmd_pci_config_path, PATH_MAX));
|
||||
|
||||
fd = open(vmd_pci_config_path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return 1;
|
||||
|
||||
if (pread(fd, buff, sizeof(uint32_t), VMD_REGISTER_OFFSET) != sizeof(uint32_t)) {
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* add_vmd_orom() - Adds VMD orom cap to orom list, writes orom_entry ptr into vmd_orom
|
||||
* @vmd_orom: pointer to orom entry pointer
|
||||
*
|
||||
* Return: 0 on success, 1 on error
|
||||
*/
|
||||
int add_vmd_orom(struct orom_entry **vmd_orom, struct sys_dev *hba)
|
||||
{
|
||||
uint8_t sku;
|
||||
uint32_t vmd_register_data;
|
||||
struct imsm_orom vmd_orom_cap = {
|
||||
.signature = IMSM_VMD_OROM_COMPAT_SIGNATURE,
|
||||
.sss = IMSM_OROM_SSS_4kB | IMSM_OROM_SSS_8kB |
|
||||
IMSM_OROM_SSS_16kB | IMSM_OROM_SSS_32kB |
|
||||
IMSM_OROM_SSS_64kB | IMSM_OROM_SSS_128kB,
|
||||
.dpa = IMSM_OROM_DISKS_PER_ARRAY_NVME,
|
||||
.tds = IMSM_OROM_TOTAL_DISKS_VMD,
|
||||
.vpa = IMSM_OROM_VOLUMES_PER_ARRAY,
|
||||
.vphba = IMSM_OROM_VOLUMES_PER_HBA_VMD,
|
||||
.attr = IMSM_OROM_ATTR_2TB | IMSM_OROM_ATTR_2TB_DISK,
|
||||
.driver_features = IMSM_OROM_CAPABILITIES_EnterpriseSystem |
|
||||
IMSM_OROM_CAPABILITIES_TPV
|
||||
};
|
||||
|
||||
if (read_vmd_register(&vmd_register_data, hba) != 0)
|
||||
return 1;
|
||||
|
||||
sku = (uint8_t)((vmd_register_data >> VMD_REGISTER_SKU_SHIFT) &
|
||||
VMD_REGISTER_SKU_MASK);
|
||||
|
||||
if (sku == VMD_REGISTER_SKU_PREMIUM)
|
||||
vmd_orom_cap.rlc = IMSM_OROM_RLC_RAID0 | IMSM_OROM_RLC_RAID1 |
|
||||
IMSM_OROM_RLC_RAID10 | IMSM_OROM_RLC_RAID5;
|
||||
else
|
||||
vmd_orom_cap.rlc = IMSM_OROM_RLC_RAID_CNG;
|
||||
|
||||
vmd_orom_cap.major_ver = (uint8_t)
|
||||
((vmd_register_data >> MD_REGISTER_VER_MAJOR_SHIFT) &
|
||||
MD_REGISTER_VER_MAJOR_MASK);
|
||||
vmd_orom_cap.minor_ver = (uint8_t)
|
||||
((vmd_register_data >> MD_REGISTER_VER_MINOR_SHIFT) &
|
||||
MD_REGISTER_VER_MINOR_MASK);
|
||||
|
||||
*vmd_orom = add_orom(&vmd_orom_cap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct imsm_orom *find_imsm_vmd(struct sys_dev *hba)
|
||||
{
|
||||
static struct orom_entry *vmd_orom;
|
||||
|
||||
if (hba->type != SYS_DEV_VMD)
|
||||
return NULL;
|
||||
|
||||
if (!vmd_orom && add_vmd_orom(&vmd_orom, hba) != 0)
|
||||
return NULL;
|
||||
|
||||
add_orom_device_id(vmd_orom, hba->dev_id);
|
||||
vmd_orom->type = SYS_DEV_VMD;
|
||||
return &vmd_orom->orom;
|
||||
}
|
||||
|
||||
const struct imsm_orom *find_imsm_capability(struct sys_dev *hba)
|
||||
{
|
||||
const struct imsm_orom *cap = get_orom_by_device_id(hba->dev_id);
|
||||
|
@ -712,9 +809,19 @@ const struct imsm_orom *find_imsm_capability(struct sys_dev *hba)
|
|||
|
||||
if (hba->type == SYS_DEV_NVME)
|
||||
return find_imsm_nvme(hba);
|
||||
if ((cap = find_imsm_efi(hba)) != NULL)
|
||||
|
||||
cap = find_imsm_efi(hba);
|
||||
if (cap)
|
||||
return cap;
|
||||
if ((cap = find_imsm_hba_orom(hba)) != NULL)
|
||||
|
||||
if (hba->type == SYS_DEV_VMD) {
|
||||
cap = find_imsm_vmd(hba);
|
||||
if (cap)
|
||||
return cap;
|
||||
}
|
||||
|
||||
cap = find_imsm_hba_orom(hba);
|
||||
if (cap)
|
||||
return cap;
|
||||
|
||||
return NULL;
|
||||
|
|
|
@ -19,11 +19,15 @@
|
|||
#include <asm/types.h>
|
||||
#include <strings.h>
|
||||
|
||||
/* according to GUID format: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" */
|
||||
#define GUID_STR_MAX 37
|
||||
|
||||
/* The IMSM Capability (IMSM AHCI and ISCU OROM/EFI variable) Version Table definition */
|
||||
struct imsm_orom {
|
||||
__u8 signature[4];
|
||||
#define IMSM_OROM_SIGNATURE "$VER"
|
||||
#define IMSM_NVME_OROM_COMPAT_SIGNATURE "$NVM"
|
||||
#define IMSM_VMD_OROM_COMPAT_SIGNATURE "$VMD"
|
||||
__u8 table_ver_major; /* Currently 2 (can change with future revs) */
|
||||
__u8 table_ver_minor; /* Currently 2 (can change with future revs) */
|
||||
__u16 major_ver; /* Example: 8 as in 8.6.0.1020 */
|
||||
|
@ -65,11 +69,13 @@ struct imsm_orom {
|
|||
__u16 tds; /* Total Disks Supported */
|
||||
#define IMSM_OROM_TOTAL_DISKS 6
|
||||
#define IMSM_OROM_TOTAL_DISKS_NVME 12
|
||||
#define IMSM_OROM_TOTAL_DISKS_VMD 48
|
||||
__u8 vpa; /* # Volumes Per Array supported */
|
||||
#define IMSM_OROM_VOLUMES_PER_ARRAY 2
|
||||
__u8 vphba; /* # Volumes Per Host Bus Adapter supported */
|
||||
#define IMSM_OROM_VOLUMES_PER_HBA 4
|
||||
#define IMSM_OROM_VOLUMES_PER_HBA_NVME 4
|
||||
#define IMSM_OROM_VOLUMES_PER_HBA_VMD 24
|
||||
/* Attributes supported. This should map to the
|
||||
* attributes in the MPB. Also, lower 16 bits
|
||||
* should match/duplicate RLC bits above.
|
||||
|
@ -185,6 +191,12 @@ static inline int imsm_orom_is_nvme(const struct imsm_orom *orom)
|
|||
sizeof(orom->signature)) == 0;
|
||||
}
|
||||
|
||||
static inline int imsm_orom_is_vmd_without_efi(const struct imsm_orom *orom)
|
||||
{
|
||||
return memcmp(orom->signature, IMSM_VMD_OROM_COMPAT_SIGNATURE,
|
||||
sizeof(orom->signature)) == 0;
|
||||
}
|
||||
|
||||
static inline int imsm_orom_has_tpv_support(const struct imsm_orom *orom)
|
||||
{
|
||||
return !!(orom->driver_features & IMSM_OROM_CAPABILITIES_TPV);
|
||||
|
@ -229,7 +241,7 @@ extern struct orom_entry *orom_entries;
|
|||
|
||||
static inline char *guid_str(char *buf, struct efi_guid guid)
|
||||
{
|
||||
sprintf(buf, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
snprintf(buf, GUID_STR_MAX, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
guid.b[3], guid.b[2], guid.b[1], guid.b[0],
|
||||
guid.b[5], guid.b[4], guid.b[7], guid.b[6],
|
||||
guid.b[8], guid.b[9], guid.b[10], guid.b[11],
|
||||
|
|
|
@ -2364,8 +2364,7 @@ static int init_super_ddf(struct supertype *st,
|
|||
* Remaining 16 are serial number.... maybe a hostname would do?
|
||||
*/
|
||||
memcpy(ddf->controller.guid, T10, sizeof(T10));
|
||||
gethostname(hostname, sizeof(hostname));
|
||||
hostname[sizeof(hostname) - 1] = 0;
|
||||
s_gethostname(hostname, sizeof(hostname));
|
||||
hostlen = strlen(hostname);
|
||||
memcpy(ddf->controller.guid + 24 - hostlen, hostname, hostlen);
|
||||
for (i = strlen(T10) ; i+hostlen < 24; i++)
|
||||
|
|
383
super-intel.c
383
super-intel.c
|
@ -499,8 +499,15 @@ struct intel_disk {
|
|||
struct intel_disk *next;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct extent - reserved space details.
|
||||
* @start: start offset.
|
||||
* @size: size of reservation, set to 0 for metadata reservation.
|
||||
* @vol: index of the volume, meaningful if &size is set.
|
||||
*/
|
||||
struct extent {
|
||||
unsigned long long start, size;
|
||||
int vol;
|
||||
};
|
||||
|
||||
/* definitions of reshape process types */
|
||||
|
@ -650,6 +657,11 @@ static int check_no_platform(void)
|
|||
char *l = conf_line(fp);
|
||||
char *w = l;
|
||||
|
||||
if (l == NULL) {
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
do {
|
||||
if (strcmp(w, search) == 0)
|
||||
no_platform = 1;
|
||||
|
@ -1534,9 +1546,10 @@ static struct extent *get_extents(struct intel_super *super, struct dl *dl,
|
|||
int get_minimal_reservation)
|
||||
{
|
||||
/* find a list of used extents on the given physical device */
|
||||
struct extent *rv, *e;
|
||||
int i;
|
||||
int memberships = count_memberships(dl, super);
|
||||
struct extent *rv = xcalloc(memberships + 1, sizeof(struct extent));
|
||||
struct extent *e = rv;
|
||||
int i;
|
||||
__u32 reservation;
|
||||
|
||||
/* trim the reserved area for spares, so they can join any array
|
||||
|
@ -1548,9 +1561,6 @@ static struct extent *get_extents(struct intel_super *super, struct dl *dl,
|
|||
else
|
||||
reservation = MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS;
|
||||
|
||||
rv = xcalloc(sizeof(struct extent), (memberships + 1));
|
||||
e = rv;
|
||||
|
||||
for (i = 0; i < super->anchor->num_raid_devs; i++) {
|
||||
struct imsm_dev *dev = get_imsm_dev(super, i);
|
||||
struct imsm_map *map = get_imsm_map(dev, MAP_0);
|
||||
|
@ -1558,6 +1568,7 @@ static struct extent *get_extents(struct intel_super *super, struct dl *dl,
|
|||
if (get_imsm_disk_slot(map, dl->index) >= 0) {
|
||||
e->start = pba_of_lba0(map);
|
||||
e->size = per_dev_array_size(map);
|
||||
e->vol = i;
|
||||
e++;
|
||||
}
|
||||
}
|
||||
|
@ -1639,17 +1650,29 @@ static int is_journal(struct imsm_disk *disk)
|
|||
return (disk->status & JOURNAL_DISK) == JOURNAL_DISK;
|
||||
}
|
||||
|
||||
/* round array size down to closest MB and ensure it splits evenly
|
||||
* between members
|
||||
/**
|
||||
* round_member_size_to_mb()- Round given size to closest MiB.
|
||||
* @size: size to round in sectors.
|
||||
*/
|
||||
static unsigned long long round_size_to_mb(unsigned long long size, unsigned int
|
||||
disk_count)
|
||||
static inline unsigned long long round_member_size_to_mb(unsigned long long size)
|
||||
{
|
||||
size /= disk_count;
|
||||
size = (size >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
|
||||
size *= disk_count;
|
||||
return (size >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
|
||||
}
|
||||
|
||||
return size;
|
||||
/**
|
||||
* round_size_to_mb()- Round given size.
|
||||
* @array_size: size to round in sectors.
|
||||
* @disk_count: count of data members.
|
||||
*
|
||||
* Get size per each data member and round it to closest MiB to ensure that data
|
||||
* splits evenly between members.
|
||||
*
|
||||
* Return: Array size, rounded down.
|
||||
*/
|
||||
static inline unsigned long long round_size_to_mb(unsigned long long array_size,
|
||||
unsigned int disk_count)
|
||||
{
|
||||
return round_member_size_to_mb(array_size / disk_count) * disk_count;
|
||||
}
|
||||
|
||||
static int able_to_resync(int raid_level, int missing_disks)
|
||||
|
@ -2649,9 +2672,14 @@ static void print_imsm_capability(const struct imsm_orom *orom)
|
|||
else
|
||||
printf("Rapid Storage Technology%s\n",
|
||||
imsm_orom_is_enterprise(orom) ? " enterprise" : "");
|
||||
if (orom->major_ver || orom->minor_ver || orom->hotfix_ver || orom->build)
|
||||
if (orom->major_ver || orom->minor_ver || orom->hotfix_ver || orom->build) {
|
||||
if (imsm_orom_is_vmd_without_efi(orom))
|
||||
printf(" Version : %d.%d\n", orom->major_ver,
|
||||
orom->minor_ver);
|
||||
else
|
||||
printf(" Version : %d.%d.%d.%d\n", orom->major_ver,
|
||||
orom->minor_ver, orom->hotfix_ver, orom->build);
|
||||
}
|
||||
printf(" RAID Levels :%s%s%s%s%s\n",
|
||||
imsm_orom_has_raid0(orom) ? " raid0" : "",
|
||||
imsm_orom_has_raid1(orom) ? " raid1" : "",
|
||||
|
@ -6877,20 +6905,35 @@ static unsigned long long find_size(struct extent *e, int *idx, int num_extents)
|
|||
return end - base_start;
|
||||
}
|
||||
|
||||
static unsigned long long merge_extents(struct intel_super *super, int sum_extents)
|
||||
{
|
||||
/* build a composite disk with all known extents and generate a new
|
||||
* 'maxsize' given the "all disks in an array must share a common start
|
||||
* offset" constraint
|
||||
/** merge_extents() - analyze extents and get free size.
|
||||
* @super: Intel metadata, not NULL.
|
||||
* @expanding: if set, we are expanding &super->current_vol.
|
||||
*
|
||||
* Build a composite disk with all known extents and generate a size given the
|
||||
* "all disks in an array must share a common start offset" constraint.
|
||||
* If a volume is expanded, then return free space after the volume.
|
||||
*
|
||||
* Return: Free space or 0 on failure.
|
||||
*/
|
||||
struct extent *e = xcalloc(sum_extents, sizeof(*e));
|
||||
static unsigned long long merge_extents(struct intel_super *super, const bool expanding)
|
||||
{
|
||||
struct extent *e;
|
||||
struct dl *dl;
|
||||
int i, j;
|
||||
int start_extent;
|
||||
unsigned long long pos;
|
||||
int i, j, pos_vol_idx = -1;
|
||||
int extent_idx = 0;
|
||||
int sum_extents = 0;
|
||||
unsigned long long pos = 0;
|
||||
unsigned long long start = 0;
|
||||
unsigned long long maxsize;
|
||||
unsigned long reserve;
|
||||
unsigned long long free_size = 0;
|
||||
|
||||
unsigned long pre_reservation = 0;
|
||||
unsigned long post_reservation = IMSM_RESERVED_SECTORS;
|
||||
unsigned long reservation_size;
|
||||
|
||||
for (dl = super->disks; dl; dl = dl->next)
|
||||
if (dl->e)
|
||||
sum_extents += dl->extent_cnt;
|
||||
e = xcalloc(sum_extents, sizeof(struct extent));
|
||||
|
||||
/* coalesce and sort all extents. also, check to see if we need to
|
||||
* reserve space between member arrays
|
||||
|
@ -6909,50 +6952,57 @@ static unsigned long long merge_extents(struct intel_super *super, int sum_exten
|
|||
j = 0;
|
||||
while (i < sum_extents) {
|
||||
e[j].start = e[i].start;
|
||||
e[j].vol = e[i].vol;
|
||||
e[j].size = find_size(e, &i, sum_extents);
|
||||
j++;
|
||||
if (e[j-1].size == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
pos = 0;
|
||||
maxsize = 0;
|
||||
start_extent = 0;
|
||||
i = 0;
|
||||
do {
|
||||
unsigned long long esize;
|
||||
unsigned long long esize = e[i].start - pos;
|
||||
|
||||
esize = e[i].start - pos;
|
||||
if (esize >= maxsize) {
|
||||
maxsize = esize;
|
||||
if (expanding ? pos_vol_idx == super->current_vol : esize >= free_size) {
|
||||
free_size = esize;
|
||||
start = pos;
|
||||
start_extent = i;
|
||||
extent_idx = i;
|
||||
}
|
||||
|
||||
pos = e[i].start + e[i].size;
|
||||
pos_vol_idx = e[i].vol;
|
||||
|
||||
i++;
|
||||
} while (e[i-1].size);
|
||||
|
||||
if (free_size == 0) {
|
||||
dprintf("imsm: Cannot find free size.\n");
|
||||
free(e);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!expanding && extent_idx != 0)
|
||||
/*
|
||||
* Not a real first volume in a container is created, pre_reservation is needed.
|
||||
*/
|
||||
pre_reservation = IMSM_RESERVED_SECTORS;
|
||||
|
||||
if (e[extent_idx].size == 0)
|
||||
/*
|
||||
* extent_idx points to the metadata, post_reservation is allready done.
|
||||
*/
|
||||
post_reservation = 0;
|
||||
free(e);
|
||||
|
||||
if (maxsize == 0)
|
||||
reservation_size = pre_reservation + post_reservation;
|
||||
|
||||
if (free_size < reservation_size) {
|
||||
dprintf("imsm: Reservation size is greater than free space.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME assumes volume at offset 0 is the first volume in a
|
||||
* container
|
||||
*/
|
||||
if (start_extent > 0)
|
||||
reserve = IMSM_RESERVED_SECTORS; /* gap between raid regions */
|
||||
else
|
||||
reserve = 0;
|
||||
|
||||
if (maxsize < reserve)
|
||||
return 0;
|
||||
|
||||
super->create_offset = ~((unsigned long long) 0);
|
||||
if (start + reserve > super->create_offset)
|
||||
return 0; /* start overflows create_offset */
|
||||
super->create_offset = start + reserve;
|
||||
|
||||
return maxsize - reserve;
|
||||
super->create_offset = start + pre_reservation;
|
||||
return free_size - reservation_size;
|
||||
}
|
||||
|
||||
static int is_raid_level_supported(const struct imsm_orom *orom, int level, int raiddisks)
|
||||
|
@ -6998,7 +7048,7 @@ active_arrays_by_format(char *name, char* hba, struct md_list **devlist,
|
|||
int fd = -1;
|
||||
while (dev && !is_fd_valid(fd)) {
|
||||
char *path = xmalloc(strlen(dev->name) + strlen("/dev/") + 1);
|
||||
num = sprintf(path, "%s%s", "/dev/", dev->name);
|
||||
num = snprintf(path, PATH_MAX, "%s%s", "/dev/", dev->name);
|
||||
if (num > 0)
|
||||
fd = open(path, O_RDONLY, 0);
|
||||
if (num <= 0 || !is_fd_valid(fd)) {
|
||||
|
@ -7550,13 +7600,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* count total number of extents for merge */
|
||||
i = 0;
|
||||
for (dl = super->disks; dl; dl = dl->next)
|
||||
if (dl->e)
|
||||
i += dl->extent_cnt;
|
||||
|
||||
maxsize = merge_extents(super, i);
|
||||
maxsize = merge_extents(super, false);
|
||||
|
||||
if (mpb->num_raid_devs > 0 && size && size != maxsize)
|
||||
pr_err("attempting to create a second volume with size less then remaining space.\n");
|
||||
|
@ -7591,7 +7635,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
|
|||
* @super: &intel_super pointer, not NULL.
|
||||
* @raiddisks: number of raid disks.
|
||||
* @size: requested size, could be 0 (means max size).
|
||||
* @chunk: requested chunk.
|
||||
* @chunk: requested chunk size in KiB.
|
||||
* @freesize: pointer for returned size value.
|
||||
*
|
||||
* Return: &IMSM_STATUS_OK or &IMSM_STATUS_ERROR.
|
||||
|
@ -7605,22 +7649,22 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super,
|
|||
const int raiddisks,
|
||||
unsigned long long size,
|
||||
const int chunk,
|
||||
unsigned long long *freesize)
|
||||
unsigned long long *freesize,
|
||||
bool expanding)
|
||||
{
|
||||
struct imsm_super *mpb = super->anchor;
|
||||
struct dl *dl;
|
||||
int i;
|
||||
int extent_cnt;
|
||||
struct extent *e;
|
||||
int cnt = 0;
|
||||
int used = 0;
|
||||
unsigned long long maxsize;
|
||||
unsigned long long minsize;
|
||||
int cnt;
|
||||
int used;
|
||||
unsigned long long minsize = size;
|
||||
|
||||
if (minsize == 0)
|
||||
minsize = chunk * 2;
|
||||
|
||||
/* find the largest common start free region of the possible disks */
|
||||
used = 0;
|
||||
extent_cnt = 0;
|
||||
cnt = 0;
|
||||
for (dl = super->disks; dl; dl = dl->next) {
|
||||
dl->raiddisk = -1;
|
||||
|
||||
|
@ -7640,19 +7684,18 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super,
|
|||
;
|
||||
dl->e = e;
|
||||
dl->extent_cnt = i;
|
||||
extent_cnt += i;
|
||||
cnt++;
|
||||
}
|
||||
|
||||
maxsize = merge_extents(super, extent_cnt);
|
||||
minsize = size;
|
||||
if (size == 0)
|
||||
/* chunk is in K */
|
||||
minsize = chunk * 2;
|
||||
maxsize = merge_extents(super, expanding);
|
||||
if (maxsize < minsize) {
|
||||
pr_err("imsm: Free space is %llu but must be equal or larger than %llu.\n",
|
||||
maxsize, minsize);
|
||||
return IMSM_STATUS_ERROR;
|
||||
}
|
||||
|
||||
if (cnt < raiddisks || (super->orom && used && used != raiddisks) ||
|
||||
maxsize < minsize || maxsize == 0) {
|
||||
pr_err("not enough devices with space to create array.\n");
|
||||
if (cnt < raiddisks || (super->orom && used && used != raiddisks)) {
|
||||
pr_err("imsm: Not enough devices with space to create array.\n");
|
||||
return IMSM_STATUS_ERROR;
|
||||
}
|
||||
|
||||
|
@ -7702,7 +7745,7 @@ static imsm_status_t autolayout_imsm(struct intel_super *super,
|
|||
int vol_cnt = super->anchor->num_raid_devs;
|
||||
imsm_status_t rv;
|
||||
|
||||
rv = imsm_get_free_size(super, raiddisks, size, chunk, freesize);
|
||||
rv = imsm_get_free_size(super, raiddisks, size, chunk, freesize, false);
|
||||
if (rv != IMSM_STATUS_OK)
|
||||
return IMSM_STATUS_ERROR;
|
||||
|
||||
|
@ -7897,7 +7940,7 @@ static int kill_subarray_imsm(struct supertype *st, char *subarray_id)
|
|||
|
||||
if (i < current_vol)
|
||||
continue;
|
||||
sprintf(subarray, "%u", i);
|
||||
snprintf(subarray, sizeof(subarray), "%u", i);
|
||||
if (is_subarray_active(subarray, st->devnm)) {
|
||||
pr_err("deleting subarray-%d would change the UUID of active subarray-%d, aborting\n",
|
||||
current_vol, i);
|
||||
|
@ -11270,7 +11313,7 @@ static const char *imsm_get_disk_controller_domain(const char *path)
|
|||
char *drv=NULL;
|
||||
struct stat st;
|
||||
|
||||
strcpy(disk_path, disk_by_path);
|
||||
strncpy(disk_path, disk_by_path, PATH_MAX);
|
||||
strncat(disk_path, path, PATH_MAX - strlen(disk_path) - 1);
|
||||
if (stat(disk_path, &st) == 0) {
|
||||
struct sys_dev* hba;
|
||||
|
@ -11624,6 +11667,96 @@ static void imsm_update_metadata_locally(struct supertype *st,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* imsm_analyze_expand() - check expand properties and calculate new size.
|
||||
* @st: imsm supertype.
|
||||
* @geo: new geometry params.
|
||||
* @array: array info.
|
||||
* @direction: reshape direction.
|
||||
*
|
||||
* Obtain free space after the &array and verify if expand to requested size is
|
||||
* possible. If geo->size is set to %MAX_SIZE, assume that max free size is
|
||||
* requested.
|
||||
*
|
||||
* Return:
|
||||
* On success %IMSM_STATUS_OK is returned, geo->size and geo->raid_disks are
|
||||
* updated.
|
||||
* On error, %IMSM_STATUS_ERROR is returned.
|
||||
*/
|
||||
static imsm_status_t imsm_analyze_expand(struct supertype *st,
|
||||
struct geo_params *geo,
|
||||
struct mdinfo *array,
|
||||
int direction)
|
||||
{
|
||||
struct intel_super *super = st->sb;
|
||||
struct imsm_dev *dev = get_imsm_dev(super, super->current_vol);
|
||||
struct imsm_map *map = get_imsm_map(dev, MAP_0);
|
||||
int data_disks = imsm_num_data_members(map);
|
||||
|
||||
unsigned long long current_size;
|
||||
unsigned long long free_size;
|
||||
unsigned long long new_size;
|
||||
unsigned long long max_size;
|
||||
|
||||
const int chunk_kib = geo->chunksize / 1024;
|
||||
imsm_status_t rv;
|
||||
|
||||
if (direction == ROLLBACK_METADATA_CHANGES) {
|
||||
/**
|
||||
* Accept size for rollback only.
|
||||
*/
|
||||
new_size = geo->size * 2;
|
||||
goto success;
|
||||
}
|
||||
|
||||
if (data_disks == 0) {
|
||||
pr_err("imsm: Cannot retrieve data disks.\n");
|
||||
return IMSM_STATUS_ERROR;
|
||||
}
|
||||
current_size = array->custom_array_size / data_disks;
|
||||
|
||||
rv = imsm_get_free_size(super, dev->vol.map->num_members, 0, chunk_kib, &free_size, true);
|
||||
if (rv != IMSM_STATUS_OK) {
|
||||
pr_err("imsm: Cannot find free space for expand.\n");
|
||||
return IMSM_STATUS_ERROR;
|
||||
}
|
||||
max_size = round_member_size_to_mb(free_size + current_size);
|
||||
|
||||
if (geo->size == MAX_SIZE)
|
||||
new_size = max_size;
|
||||
else
|
||||
new_size = round_member_size_to_mb(geo->size * 2);
|
||||
|
||||
if (new_size == 0) {
|
||||
pr_err("imsm: Rounded requested size is 0.\n");
|
||||
return IMSM_STATUS_ERROR;
|
||||
}
|
||||
|
||||
if (new_size > max_size) {
|
||||
pr_err("imsm: Rounded requested size (%llu) is larger than free space available (%llu).\n",
|
||||
new_size, max_size);
|
||||
return IMSM_STATUS_ERROR;
|
||||
}
|
||||
|
||||
if (new_size == current_size) {
|
||||
pr_err("imsm: Rounded requested size (%llu) is same as current size (%llu).\n",
|
||||
new_size, current_size);
|
||||
return IMSM_STATUS_ERROR;
|
||||
}
|
||||
|
||||
if (new_size < current_size) {
|
||||
pr_err("imsm: Size reduction is not supported, rounded requested size (%llu) is smaller than current (%llu).\n",
|
||||
new_size, current_size);
|
||||
return IMSM_STATUS_ERROR;
|
||||
}
|
||||
|
||||
success:
|
||||
dprintf("imsm: New size per member is %llu.\n", new_size);
|
||||
geo->size = data_disks * new_size;
|
||||
geo->raid_disks = dev->vol.map->num_members;
|
||||
return IMSM_STATUS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Function: imsm_analyze_change
|
||||
* Description: Function analyze change for single volume
|
||||
|
@ -11644,13 +11777,6 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
|||
int devNumChange = 0;
|
||||
/* imsm compatible layout value for array geometry verification */
|
||||
int imsm_layout = -1;
|
||||
int data_disks;
|
||||
struct imsm_dev *dev;
|
||||
struct imsm_map *map;
|
||||
struct intel_super *super;
|
||||
unsigned long long current_size;
|
||||
unsigned long long free_size;
|
||||
unsigned long long max_size;
|
||||
imsm_status_t rv;
|
||||
|
||||
getinfo_super_imsm_volume(st, &info, NULL);
|
||||
|
@ -11733,95 +11859,20 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
|||
geo->chunksize = info.array.chunk_size;
|
||||
}
|
||||
|
||||
chunk = geo->chunksize / 1024;
|
||||
|
||||
super = st->sb;
|
||||
dev = get_imsm_dev(super, super->current_vol);
|
||||
map = get_imsm_map(dev, MAP_0);
|
||||
data_disks = imsm_num_data_members(map);
|
||||
/* compute current size per disk member
|
||||
*/
|
||||
current_size = info.custom_array_size / data_disks;
|
||||
|
||||
if (geo->size > 0 && geo->size != MAX_SIZE) {
|
||||
/* align component size
|
||||
*/
|
||||
geo->size = imsm_component_size_alignment_check(
|
||||
get_imsm_raid_level(dev->vol.map),
|
||||
chunk * 1024, super->sector_size,
|
||||
geo->size * 2);
|
||||
if (geo->size == 0) {
|
||||
pr_err("Error. Size expansion is supported only (current size is %llu, requested size /rounded/ is 0).\n",
|
||||
current_size);
|
||||
goto analyse_change_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_size != geo->size && geo->size > 0) {
|
||||
if (geo->size > 0) {
|
||||
if (change != -1) {
|
||||
pr_err("Error. Size change should be the only one at a time.\n");
|
||||
change = -1;
|
||||
goto analyse_change_exit;
|
||||
}
|
||||
if ((super->current_vol + 1) != super->anchor->num_raid_devs) {
|
||||
pr_err("Error. The last volume in container can be expanded only (%i/%s).\n",
|
||||
super->current_vol, st->devnm);
|
||||
goto analyse_change_exit;
|
||||
}
|
||||
/* check the maximum available size
|
||||
*/
|
||||
rv = imsm_get_free_size(super, dev->vol.map->num_members,
|
||||
0, chunk, &free_size);
|
||||
|
||||
rv = imsm_analyze_expand(st, geo, &info, direction);
|
||||
if (rv != IMSM_STATUS_OK)
|
||||
/* Cannot find maximum available space
|
||||
*/
|
||||
max_size = 0;
|
||||
else {
|
||||
max_size = free_size + current_size;
|
||||
/* align component size
|
||||
*/
|
||||
max_size = imsm_component_size_alignment_check(
|
||||
get_imsm_raid_level(dev->vol.map),
|
||||
chunk * 1024, super->sector_size,
|
||||
max_size);
|
||||
}
|
||||
if (geo->size == MAX_SIZE) {
|
||||
/* requested size change to the maximum available size
|
||||
*/
|
||||
if (max_size == 0) {
|
||||
pr_err("Error. Cannot find maximum available space.\n");
|
||||
change = -1;
|
||||
goto analyse_change_exit;
|
||||
} else
|
||||
geo->size = max_size;
|
||||
}
|
||||
|
||||
if (direction == ROLLBACK_METADATA_CHANGES) {
|
||||
/* accept size for rollback only
|
||||
*/
|
||||
} else {
|
||||
/* round size due to metadata compatibility
|
||||
*/
|
||||
geo->size = (geo->size >> SECT_PER_MB_SHIFT)
|
||||
<< SECT_PER_MB_SHIFT;
|
||||
dprintf("Prepare update for size change to %llu\n",
|
||||
geo->size );
|
||||
if (current_size >= geo->size) {
|
||||
pr_err("Error. Size expansion is supported only (current size is %llu, requested size /rounded/ is %llu).\n",
|
||||
current_size, geo->size);
|
||||
goto analyse_change_exit;
|
||||
}
|
||||
if (max_size && geo->size > max_size) {
|
||||
pr_err("Error. Requested size is larger than maximum available size (maximum available size is %llu, requested size /rounded/ is %llu).\n",
|
||||
max_size, geo->size);
|
||||
goto analyse_change_exit;
|
||||
}
|
||||
}
|
||||
geo->size *= data_disks;
|
||||
geo->raid_disks = dev->vol.map->num_members;
|
||||
change = CH_ARRAY_SIZE;
|
||||
}
|
||||
|
||||
chunk = geo->chunksize / 1024;
|
||||
if (!validate_geometry_imsm(st,
|
||||
geo->level,
|
||||
imsm_layout,
|
||||
|
|
Loading…
Add table
Reference in a new issue