1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-02 01:18:26 +03:00

Add and track an "ondisk" pointer to struct volume_group.

This allows us to get the current on-disk version of the metadata whenever we
have the current in-flight version, without a recourse to scanning or lvmcache.
This commit is contained in:
Petr Rockai 2013-03-17 16:27:44 +01:00 committed by Petr Rockai
parent c1e851e208
commit 5d5f2306bd
4 changed files with 58 additions and 0 deletions

View File

@ -90,4 +90,5 @@ int lv_active_change(struct cmd_context *cmd, struct logical_volume *lv,
enum activation_change activate);
char *lv_active_dup(struct dm_pool *mem, const struct logical_volume *lv);
const struct logical_volume *lv_lock_holder(const struct logical_volume *lv);
struct logical_volume *lv_ondisk(struct logical_volume *lv);
#endif /* _LVM_LV_H */

View File

@ -831,6 +831,21 @@ int vgcreate_params_validate(struct cmd_context *cmd,
return 1;
}
static int _vg_update_vg_ondisk(struct volume_group *vg)
{
struct dm_config_tree *cft;
if (vg->vg_ondisk) /* we already have it */
return 1;
cft = export_vg_to_config_tree(vg);
if (!cft)
return 0;
vg->vg_ondisk = import_vg_from_config_tree(cft, vg->fid);
dm_config_destroy(cft);
return 1;
}
/*
* Create a (struct volume_group) volume group handle from a struct volume_group pointer and a
* possible failure code or zero for success.
@ -839,6 +854,7 @@ static struct volume_group *_vg_make_handle(struct cmd_context *cmd,
struct volume_group *vg,
uint32_t failure)
{
/* Never return a cached VG structure for a failure */
if (vg && vg->vginfo && failure != SUCCESS) {
release_vg(vg);
@ -848,6 +864,9 @@ static struct volume_group *_vg_make_handle(struct cmd_context *cmd,
if (!vg && !(vg = alloc_vg("vg_make_handle", cmd, NULL)))
return_NULL;
if (vg->fid && !_vg_update_vg_ondisk(vg))
vg->read_status |= FAILED_ALLOCATION;
if (vg->read_status != failure)
vg->read_status = failure;
@ -2690,6 +2709,12 @@ int vg_commit(struct volume_group *vg)
* The volume_group structure could be reused later.
*/
vg->old_name = NULL;
/* This *is* the original now that it's commited. */
release_vg(vg->vg_ondisk);
vg->vg_ondisk = NULL;
if (!_vg_update_vg_ondisk(vg)) /* make a new one for future edits */
return_0;
}
/* If update failed, remove any cached precommitted metadata. */
@ -4523,3 +4548,25 @@ char *tags_format_and_copy(struct dm_pool *mem, const struct dm_list *tags)
}
return dm_pool_end_object(mem);
}
struct logical_volume *lv_ondisk(struct logical_volume *lv)
{
struct volume_group *vg;
struct lv_list *lvl;
if (!lv)
return NULL;
vg = lv->vg;
if (vg->vg_ondisk)
vg = vg->vg_ondisk;
dm_list_iterate_items(lvl, &vg->lvs)
if (!strncmp(lvl->lv->lvid.s, lv->lvid.s, sizeof(lv->lvid)))
return lvl->lv;
log_error(INTERNAL_ERROR "LV %s/%s (UUID %s) not found in ondisk metadata.",
lv->vg->name, lv->name, lv->lvid.s);
return NULL;
}

View File

@ -87,6 +87,7 @@ void release_vg(struct volume_group *vg)
!lvmcache_vginfo_holders_dec_and_test_for_zero(vg->vginfo))
return;
release_vg(vg->vg_ondisk);
_free_vg(vg);
}

View File

@ -48,6 +48,15 @@ struct volume_group {
uint32_t cmd_missing_vgs;/* Flag marks missing VG */
uint32_t seqno; /* Metadata sequence number */
/*
* The parsed on-disk copy of this VG; is NULL if this is the on-disk
* version (i.e. vg_ondisk == NULL *implies* this is the on-disk copy,
* there is no guarantee that if this VG is the same as the on-disk one
* this will be NULL). The pointer is maintained by calls to
* _vg_update_vg_ondisk.
*/
struct volume_group *vg_ondisk;
alloc_policy_t alloc;
uint64_t status;