mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
export: change to read_segtype_and_lvflags
Instead of duplicating whole segtype string with flags and using 2 calls read_segtype_lvflags() + get_segtype_from_string(), merge the functionality into a single read_segtype_and_lvflags(). This allows to make only a local string copy (no allocs) and eventually to not copy segtype string at all, when there are no flags.
This commit is contained in:
parent
4929c55bc5
commit
e0421ee7bf
@ -17,6 +17,7 @@
|
|||||||
#include "lib/metadata/metadata.h"
|
#include "lib/metadata/metadata.h"
|
||||||
#include "import-export.h"
|
#include "import-export.h"
|
||||||
#include "lib/misc/lvm-string.h"
|
#include "lib/misc/lvm-string.h"
|
||||||
|
#include "lib/metadata/segtype.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bitsets held in the 'status' flags get
|
* Bitsets held in the 'status' flags get
|
||||||
@ -234,47 +235,50 @@ int read_flags(uint64_t *status, enum pv_vg_lv_e type, int mask, const struct dm
|
|||||||
* Note: using these segtype status flags instead of actual
|
* Note: using these segtype status flags instead of actual
|
||||||
* status flags ensures wanted incompatibility.
|
* status flags ensures wanted incompatibility.
|
||||||
*/
|
*/
|
||||||
int read_segtype_lvflags(uint64_t *status, char *segtype_str)
|
struct segment_type *read_segtype_and_lvflags(struct cmd_context *cmd, uint64_t *status,
|
||||||
|
const char *segtype_str)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
size_t len;
|
||||||
|
struct segment_type *segtype;
|
||||||
const struct flag *flags = _lv_flags;
|
const struct flag *flags = _lv_flags;
|
||||||
char *delim;
|
char *delim, *flag, *str, buffer[2048];
|
||||||
char *flag, *buffer, *str;
|
|
||||||
|
|
||||||
if (!(str = strchr(segtype_str, '+')))
|
if ((str = strchr(segtype_str, '+'))) {
|
||||||
return 1; /* No flags */
|
if ((len = (strlen(segtype_str) + 1)) >= sizeof(buffer)) {
|
||||||
|
log_error("Segment string type string is too long.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(buffer = strdup(str + 1))) {
|
memcpy(buffer, segtype_str, len);
|
||||||
log_error("Cannot duplicate segment string.");
|
delim = buffer + (str - segtype_str);
|
||||||
return 0;
|
|
||||||
|
do {
|
||||||
|
flag = delim;
|
||||||
|
if ((delim = strchr(delim, '+')))
|
||||||
|
*delim++ = '\0';
|
||||||
|
|
||||||
|
for (i = 0; flags[i].kind; i++)
|
||||||
|
if ((flags[i].kind & SEGTYPE_FLAG) &&
|
||||||
|
!strcmp(flags[i].description, flag)) {
|
||||||
|
*status |= flags[i].mask;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (delim && flags[i].kind); /* Till no more flags in type appear */
|
||||||
|
|
||||||
|
if (!flags[i].kind)
|
||||||
|
/* Unknown flag is incompatible - returns unmodified segtype_str */
|
||||||
|
log_warn("WARNING: Unrecognised flag %s in segment type %s.",
|
||||||
|
flag, segtype_str);
|
||||||
|
|
||||||
|
segtype_str = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
delim = buffer;
|
if (!(segtype = get_segtype_from_string(cmd, segtype_str)))
|
||||||
|
return_NULL;
|
||||||
|
|
||||||
do {
|
return segtype;
|
||||||
flag = delim;
|
|
||||||
if ((delim = strchr(delim, '+')))
|
|
||||||
*delim++ = '\0';
|
|
||||||
|
|
||||||
for (i = 0; flags[i].description; i++)
|
|
||||||
if ((flags[i].kind & SEGTYPE_FLAG) &&
|
|
||||||
!strcmp(flags[i].description, flag)) {
|
|
||||||
*status |= flags[i].mask;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
} while (delim && flags[i].description); /* Till no more flags in type appear */
|
|
||||||
|
|
||||||
if (!flags[i].description)
|
|
||||||
/* Unknown flag is incompatible - returns unmodified segtype_str */
|
|
||||||
log_warn("WARNING: Unrecognised flag %s in segment type %s.",
|
|
||||||
flag, segtype_str);
|
|
||||||
else
|
|
||||||
*str = '\0'; /* Cut away 1st. '+' */
|
|
||||||
|
|
||||||
free(buffer);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int print_segtype_lvflags(char *buffer, size_t size, uint64_t status)
|
int print_segtype_lvflags(char *buffer, size_t size, uint64_t status)
|
||||||
|
@ -67,7 +67,8 @@ int print_flags(char *buffer, size_t size, enum pv_vg_lv_e type, int mask, uint6
|
|||||||
int read_flags(uint64_t *status, enum pv_vg_lv_e type, int mask, const struct dm_config_value *cv);
|
int read_flags(uint64_t *status, enum pv_vg_lv_e type, int mask, const struct dm_config_value *cv);
|
||||||
|
|
||||||
int print_segtype_lvflags(char *buffer, size_t size, uint64_t status);
|
int print_segtype_lvflags(char *buffer, size_t size, uint64_t status);
|
||||||
int read_segtype_lvflags(uint64_t *status, char *segtype_str);
|
struct segment_type *read_segtype_and_lvflags(struct cmd_context *cmd, uint64_t *status,
|
||||||
|
const char *segtype_str);
|
||||||
|
|
||||||
int text_vg_export_file(struct volume_group *vg, const char *desc, FILE *fp);
|
int text_vg_export_file(struct volume_group *vg, const char *desc, FILE *fp);
|
||||||
size_t text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf, uint32_t *alloc_size);
|
size_t text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf, uint32_t *alloc_size);
|
||||||
|
@ -386,7 +386,6 @@ static int _read_segment(struct cmd_context *cmd,
|
|||||||
uint32_t area_extents, start_extent, extent_count, reshape_count, data_copies;
|
uint32_t area_extents, start_extent, extent_count, reshape_count, data_copies;
|
||||||
struct segment_type *segtype;
|
struct segment_type *segtype;
|
||||||
const char *segtype_str;
|
const char *segtype_str;
|
||||||
char *segtype_with_flags;
|
|
||||||
|
|
||||||
if (!sn_child) {
|
if (!sn_child) {
|
||||||
log_error("Empty segment section.");
|
log_error("Empty segment section.");
|
||||||
@ -418,24 +417,12 @@ static int _read_segment(struct cmd_context *cmd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Locally duplicate to parse out status flag bits */
|
if (!(segtype = read_segtype_and_lvflags(cmd, &lv->status, segtype_str))) {
|
||||||
if (!(segtype_with_flags = dm_pool_strdup(mem, segtype_str))) {
|
|
||||||
log_error("Cannot duplicate segtype string.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!read_segtype_lvflags(&lv->status, segtype_with_flags)) {
|
|
||||||
log_error("Couldn't read segtype for logical volume %s.",
|
log_error("Couldn't read segtype for logical volume %s.",
|
||||||
display_lvname(lv));
|
display_lvname(lv));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(segtype = get_segtype_from_string(cmd, segtype_with_flags)))
|
|
||||||
return_0;
|
|
||||||
|
|
||||||
/* Can drop temporary string here as nothing has allocated from VGMEM meanwhile */
|
|
||||||
dm_pool_free(mem, segtype_with_flags);
|
|
||||||
|
|
||||||
if (segtype->ops->text_import_area_count &&
|
if (segtype->ops->text_import_area_count &&
|
||||||
!segtype->ops->text_import_area_count(sn_child, &area_count))
|
!segtype->ops->text_import_area_count(sn_child, &area_count))
|
||||||
return_0;
|
return_0;
|
||||||
|
Loading…
Reference in New Issue
Block a user