mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-03 05:18:29 +03:00
Change pv_write code to work with the changes in metadata handling interface
and changes in format_instance.
This commit is contained in:
parent
903d7db050
commit
17ad2b1115
@ -426,8 +426,7 @@ static int _format1_lv_setup(struct format_instance *fid, struct logical_volume
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _format1_pv_write(const struct format_type *fmt, struct physical_volume *pv,
|
||||
struct dm_list *mdas __attribute__((unused)), int64_t sector __attribute__((unused)))
|
||||
static int _format1_pv_write(const struct format_type *fmt, struct physical_volume *pv)
|
||||
{
|
||||
struct dm_pool *mem;
|
||||
struct disk_list *dl;
|
||||
|
@ -1256,42 +1256,58 @@ static int _text_scan(const struct format_type *fmt, const char *vgname)
|
||||
}
|
||||
|
||||
/* Only for orphans */
|
||||
/* Set label_sector to -1 if rewriting existing label into same sector */
|
||||
/* If mdas is supplied it overwrites existing mdas e.g. used with pvcreate */
|
||||
static int _text_pv_write(const struct format_type *fmt, struct physical_volume *pv,
|
||||
struct dm_list *mdas, int64_t label_sector)
|
||||
static int _text_pv_write(const struct format_type *fmt, struct physical_volume *pv)
|
||||
{
|
||||
struct text_fid_pv_context *fid_pv_tc;
|
||||
struct format_instance *fid = pv->fid;
|
||||
struct label *label;
|
||||
int64_t label_sector;
|
||||
struct lvmcache_info *info;
|
||||
struct mda_context *mdac;
|
||||
struct metadata_area *mda;
|
||||
unsigned mda_index;
|
||||
char buf[MDA_HEADER_SIZE] __attribute__((aligned(8)));
|
||||
struct mda_header *mdah = (struct mda_header *) buf;
|
||||
uint64_t adjustment;
|
||||
struct data_area_list *da;
|
||||
|
||||
/* FIXME Test mode don't update cache? */
|
||||
|
||||
if (!(info = lvmcache_add(fmt->labeller, (char *) &pv->id, pv->dev,
|
||||
FMT_TEXT_ORPHAN_VG_NAME, NULL, 0)))
|
||||
/* Add a new cache entry with PV info or update existing one. */
|
||||
if (!(info = lvmcache_add(fmt->labeller, (const char *) &pv->id,
|
||||
pv->dev, FMT_TEXT_ORPHAN_VG_NAME, NULL, 0)))
|
||||
return_0;
|
||||
|
||||
label = info->label;
|
||||
|
||||
if (label_sector != -1)
|
||||
/*
|
||||
* We can change the label sector for a
|
||||
* plain PV that is not part of a VG only!
|
||||
*/
|
||||
if (fid && (!fid->type & FMT_INSTANCE_VG) &&
|
||||
(fid_pv_tc = (struct text_fid_pv_context *) pv->fid->private) &&
|
||||
((label_sector = fid_pv_tc->label_sector) != -1))
|
||||
label->sector = label_sector;
|
||||
|
||||
info->device_size = pv->size << SECTOR_SHIFT;
|
||||
info->fmt = fmt;
|
||||
|
||||
/* If mdas supplied, use them regardless of existing ones, */
|
||||
/* otherwise retain existing ones */
|
||||
if (mdas) {
|
||||
/* Flush all cached metadata areas, we will reenter new/modified ones. */
|
||||
if (info->mdas.n)
|
||||
del_mdas(&info->mdas);
|
||||
else
|
||||
dm_list_init(&info->mdas);
|
||||
dm_list_iterate_items(mda, mdas) {
|
||||
mdac = mda->metadata_locn;
|
||||
|
||||
/*
|
||||
* Add all new or modified metadata areas for this PV stored in
|
||||
* its format instance. If this PV is not part of a VG yet,
|
||||
* pv->fid will be used. Otherwise pv->vg->fid will be used.
|
||||
* The fid_get_mda_indexed fn can handle that transparently,
|
||||
* just pass the right format_instance in.
|
||||
*/
|
||||
for (mda_index = 0; mda_index < FMT_TEXT_MAX_MDAS_PER_PV; mda_index++) {
|
||||
if (!(mda = fid_get_mda_indexed(fid, (const char *) &pv->id,
|
||||
ID_LEN, mda_index)))
|
||||
continue;
|
||||
|
||||
mdac = (struct mda_context *) mda->metadata_locn;
|
||||
log_debug("Creating metadata area on %s at sector %"
|
||||
PRIu64 " size %" PRIu64 " sectors",
|
||||
dev_name(mdac->area.dev),
|
||||
@ -1300,16 +1316,21 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
|
||||
add_mda(fmt, NULL, &info->mdas, mdac->area.dev,
|
||||
mdac->area.start, mdac->area.size, mda_is_ignored(mda));
|
||||
}
|
||||
/* FIXME Temporary until mda creation supported by tools */
|
||||
} else if (!info->mdas.n) {
|
||||
dm_list_init(&info->mdas);
|
||||
}
|
||||
|
||||
/*
|
||||
* If no pe_start supplied but PV already exists,
|
||||
* get existing value; use-cases include:
|
||||
* - pvcreate on PV without prior pvremove
|
||||
* - vgremove on VG with PV(s) that have pe_start=0 (hacked cfg)
|
||||
* FIXME: Allow writing zero offset/size data area to disk.
|
||||
* This requires defining a special value since we can't
|
||||
* write offset/size that is 0/0 - this is already reserved
|
||||
* as a delimiter in data/metadata area area list in PV header
|
||||
* (needs exploring compatibility with older lvm2).
|
||||
*/
|
||||
|
||||
/*
|
||||
* We can't actually write pe_start = 0 (a data area offset)
|
||||
* in PV header now. We need to replace this value here. This can
|
||||
* happen with vgcfgrestore with redefined pe_start or
|
||||
* pvcreate --restorefile. However, we can can have this value in
|
||||
* metadata which will override the value in the PV header.
|
||||
*/
|
||||
if (info->das.n) {
|
||||
if (!pv->pe_start)
|
||||
@ -1319,66 +1340,7 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
|
||||
} else
|
||||
dm_list_init(&info->das);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* FIXME: ideally a pre-existing pe_start seen in .pv_write
|
||||
* would always be preserved BUT 'pvcreate on PV without prior pvremove'
|
||||
* could easily cause the pe_start to overlap with the first mda!
|
||||
*/
|
||||
if (pv->pe_start) {
|
||||
log_very_verbose("%s: preserving pe_start=%lu",
|
||||
pv_dev_name(pv), pv->pe_start);
|
||||
goto preserve_pe_start;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If pe_start is still unset, set it to first aligned
|
||||
* sector after any metadata areas that begin before pe_start.
|
||||
*/
|
||||
if (!pv->pe_start) {
|
||||
pv->pe_start = pv->pe_align;
|
||||
if (pv->pe_align_offset)
|
||||
pv->pe_start += pv->pe_align_offset;
|
||||
}
|
||||
dm_list_iterate_items(mda, &info->mdas) {
|
||||
mdac = (struct mda_context *) mda->metadata_locn;
|
||||
if (pv->dev == mdac->area.dev &&
|
||||
((mdac->area.start <= (pv->pe_start << SECTOR_SHIFT)) ||
|
||||
(mdac->area.start <= lvm_getpagesize() &&
|
||||
pv->pe_start < (lvm_getpagesize() >> SECTOR_SHIFT))) &&
|
||||
(mdac->area.start + mdac->area.size >
|
||||
(pv->pe_start << SECTOR_SHIFT))) {
|
||||
pv->pe_start = (mdac->area.start + mdac->area.size)
|
||||
>> SECTOR_SHIFT;
|
||||
/* Adjust pe_start to: (N * pe_align) + pe_align_offset */
|
||||
if (pv->pe_align) {
|
||||
adjustment =
|
||||
(pv->pe_start - pv->pe_align_offset) % pv->pe_align;
|
||||
if (adjustment)
|
||||
pv->pe_start += (pv->pe_align - adjustment);
|
||||
|
||||
log_very_verbose("%s: setting pe_start=%" PRIu64
|
||||
" (orig_pe_start=%" PRIu64 ", "
|
||||
"pe_align=%lu, pe_align_offset=%lu, "
|
||||
"adjustment=%" PRIu64 ")",
|
||||
pv_dev_name(pv), pv->pe_start,
|
||||
(adjustment ?
|
||||
pv->pe_start - (pv->pe_align - adjustment) :
|
||||
pv->pe_start),
|
||||
pv->pe_align, pv->pe_align_offset, adjustment);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pv->pe_start >= pv->size) {
|
||||
log_error("Data area is beyond end of device %s!",
|
||||
pv_dev_name(pv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME: preserve_pe_start: */
|
||||
if (!add_da
|
||||
(NULL, &info->das, pv->pe_start << SECTOR_SHIFT, UINT64_C(0)))
|
||||
if (!add_da(NULL, &info->das, pv->pe_start << SECTOR_SHIFT, UINT64_C(0)))
|
||||
return_0;
|
||||
|
||||
if (!dev_open(pv->dev))
|
||||
@ -1397,11 +1359,17 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
|
||||
}
|
||||
}
|
||||
|
||||
if (!label_write(pv->dev, label)) {
|
||||
if (!label_write(pv->dev, info->label)) {
|
||||
dev_close(pv->dev);
|
||||
return_0;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: We should probably use the format instance's metadata
|
||||
* areas for label_write and only if it's successful,
|
||||
* update the cache afterwards?
|
||||
*/
|
||||
|
||||
if (!dev_close(pv->dev))
|
||||
return_0;
|
||||
|
||||
|
@ -384,8 +384,7 @@ struct dm_list *get_vgnames(struct cmd_context *cmd, int include_internal);
|
||||
struct dm_list *get_vgids(struct cmd_context *cmd, int include_internal);
|
||||
int scan_vgs_for_pvs(struct cmd_context *cmd, int warnings);
|
||||
|
||||
int pv_write(struct cmd_context *cmd, struct physical_volume *pv,
|
||||
struct dm_list *mdas, int64_t label_sector);
|
||||
int pv_write(struct cmd_context *cmd, struct physical_volume *pv);
|
||||
int move_pv(struct volume_group *vg_from, struct volume_group *vg_to,
|
||||
const char *pv_name);
|
||||
int move_pvs_used_by_lv(struct volume_group *vg_from,
|
||||
|
@ -586,7 +586,7 @@ int vg_remove(struct volume_group *vg)
|
||||
}
|
||||
|
||||
/* FIXME Write to same sector label was read from */
|
||||
if (!pv_write(vg->cmd, pv, NULL, INT64_C(-1))) {
|
||||
if (!pv_write(vg->cmd, pv)) {
|
||||
log_error("Failed to remove physical volume \"%s\""
|
||||
" from volume group \"%s\"",
|
||||
pv_dev_name(pv), vg->name);
|
||||
@ -1511,7 +1511,7 @@ struct physical_volume * pvcreate_single(struct cmd_context *cmd,
|
||||
log_very_verbose("Writing physical volume data to disk \"%s\"",
|
||||
pv_name);
|
||||
|
||||
if (!(pv_write(cmd, pv, &mdas, pp->labelsector))) {
|
||||
if (!(pv_write(cmd, pv))) {
|
||||
log_error("Failed to write physical volume \"%s\"", pv_name);
|
||||
goto error;
|
||||
}
|
||||
@ -3536,8 +3536,7 @@ int scan_vgs_for_pvs(struct cmd_context *cmd, int warnings)
|
||||
}
|
||||
|
||||
int pv_write(struct cmd_context *cmd __attribute__((unused)),
|
||||
struct physical_volume *pv,
|
||||
struct dm_list *mdas, int64_t label_sector)
|
||||
struct physical_volume *pv)
|
||||
{
|
||||
if (!pv->fmt->ops->pv_write) {
|
||||
log_error("Format does not support writing physical volumes");
|
||||
@ -3550,7 +3549,7 @@ int pv_write(struct cmd_context *cmd __attribute__((unused)),
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!pv->fmt->ops->pv_write(pv->fmt, pv, mdas, label_sector))
|
||||
if (!pv->fmt->ops->pv_write(pv->fmt, pv))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
@ -3569,7 +3568,7 @@ int pv_write_orphan(struct cmd_context *cmd, struct physical_volume *pv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!pv_write(cmd, pv, NULL, INT64_C(-1))) {
|
||||
if (!pv_write(cmd, pv)) {
|
||||
log_error("Failed to clear metadata from physical "
|
||||
"volume \"%s\" after removal from \"%s\"",
|
||||
pv_dev_name(pv), old_vg_name);
|
||||
|
@ -297,8 +297,7 @@ struct format_handler {
|
||||
* pv->vg_name must be a valid orphan VG name
|
||||
*/
|
||||
int (*pv_write) (const struct format_type * fmt,
|
||||
struct physical_volume * pv, struct dm_list * mdas,
|
||||
int64_t label_sector);
|
||||
struct physical_volume * pv);
|
||||
|
||||
/*
|
||||
* Tweak an already filled out a lv eg, check there
|
||||
|
@ -139,7 +139,7 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
|
||||
|
||||
pv->vg_name = pv->fmt->orphan_vg_name;
|
||||
pv->pe_alloc_count = 0;
|
||||
if (!(pv_write(cmd, pv, NULL, INT64_C(-1)))) {
|
||||
if (!(pv_write(cmd, pv))) {
|
||||
log_error("pv_write with new uuid failed "
|
||||
"for %s.", pv_name);
|
||||
return 0;
|
||||
@ -161,7 +161,7 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
|
||||
return 0;
|
||||
}
|
||||
backup(vg);
|
||||
} else if (!(pv_write(cmd, pv, NULL, INT64_C(-1)))) {
|
||||
} else if (!(pv_write(cmd, pv))) {
|
||||
log_error("Failed to store physical volume \"%s\"",
|
||||
pv_name);
|
||||
return 0;
|
||||
|
@ -150,7 +150,7 @@ static int _pv_resize_single(struct cmd_context *cmd,
|
||||
goto out;
|
||||
}
|
||||
backup(vg);
|
||||
} else if (!(pv_write(cmd, pv, NULL, INT64_C(-1)))) {
|
||||
} else if (!(pv_write(cmd, pv))) {
|
||||
log_error("Failed to store physical volume \"%s\"",
|
||||
pv_name);
|
||||
goto out;
|
||||
|
@ -154,9 +154,7 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
|
||||
|
||||
log_very_verbose("Writing physical volume data to disk \"%s\"",
|
||||
pv_dev_name(pv));
|
||||
if (!(pv_write(cmd, pv, &mdas,
|
||||
arg_int64_value(cmd, labelsector_ARG,
|
||||
DEFAULT_LABELSECTOR)))) {
|
||||
if (!(pv_write(cmd, pv))) {
|
||||
log_error("Failed to write physical volume \"%s\"",
|
||||
pv_dev_name(pv));
|
||||
log_error("Use pvcreate and vgcfgrestore to repair "
|
||||
|
@ -438,7 +438,7 @@ static int _vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!pv_write(cmd, pv, NULL, INT64_C(-1))) {
|
||||
if (!pv_write(cmd, pv)) {
|
||||
log_error("Failed to clear metadata from physical "
|
||||
"volume \"%s\" "
|
||||
"after removal from \"%s\"", name, vg->name);
|
||||
|
Loading…
Reference in New Issue
Block a user