[lvm-devel] [PATCH 3/7] Use vg_set_fid and new pv_set_fid throughout.

Peter Rajnoha prajnoha at redhat.com
Wed Mar 9 12:22:35 UTC 2011


Let's define a strict rule that each fid assignment to a PV/VG will be
done via pv_set_fid/vg_set_fid fn. This is needed for proper reference
counting.

(Even a NULL fid should be assigned using these fns to decrement
ref_count for any currently assigned fid)

Signed-off-by: Peter Rajnoha <prajnoha at redhat.com>
---
 lib/format1/format1.c         |    2 +-
 lib/format_pool/format_pool.c |    2 +-
 lib/format_text/format-text.c |    6 +----
 lib/format_text/import_vsn1.c |    8 +++---
 lib/metadata/metadata.c       |   52 +++++++++++++++++++++++++++++++++++-----
 lib/metadata/metadata.h       |    1 +
 6 files changed, 53 insertions(+), 18 deletions(-)

diff --git a/lib/format1/format1.c b/lib/format1/format1.c
index a024d99..3961b67 100644
--- a/lib/format1/format1.c
+++ b/lib/format1/format1.c
@@ -192,12 +192,12 @@ static struct volume_group *_build_vg(struct format_instance *fid,
 
 	vg->cmd = fid->fmt->cmd;
 	vg->vgmem = mem;
-	vg->fid = fid;
 	vg->seqno = 0;
 	dm_list_init(&vg->pvs);
 	dm_list_init(&vg->lvs);
 	dm_list_init(&vg->tags);
 	dm_list_init(&vg->removed_pvs);
+	vg_set_fid(vg, fid);
 
 	if (!_check_vgs(pvs, vg))
 		goto_bad;
diff --git a/lib/format_pool/format_pool.c b/lib/format_pool/format_pool.c
index 24c21c2..53b4171 100644
--- a/lib/format_pool/format_pool.c
+++ b/lib/format_pool/format_pool.c
@@ -114,7 +114,6 @@ static struct volume_group *_build_vg_from_pds(struct format_instance
 
 	vg->cmd = fid->fmt->cmd;
 	vg->vgmem = mem;
-	vg->fid = fid;
 	vg->name = NULL;
 	vg->status = 0;
 	vg->extent_count = 0;
@@ -125,6 +124,7 @@ static struct volume_group *_build_vg_from_pds(struct format_instance
 	dm_list_init(&vg->lvs);
 	dm_list_init(&vg->tags);
 	dm_list_init(&vg->removed_pvs);
+	vg_set_fid(vg, fid);
 
 	if (!import_pool_vg(vg, smem, pds))
 		return_NULL;
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index 166c8cc..789c984 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -1690,12 +1690,8 @@ static int _text_pv_setup(const struct format_type *fmt,
 	    (pv_mdac = pv_mda->metadata_locn))
 		size_reduction = pv_mdac->area.size >> SECTOR_SHIFT;
 
-	/* Destroy old PV-based format instance if it exists. */
-	if (!(pv->fid->type & FMT_INSTANCE_VG))
-		pv->fmt->ops->destroy_instance(pv->fid);
-
 	/* From now on, VG format instance will be used. */
-	pv->fid = vg->fid;
+	pv_set_fid(pv, vg->fid);
 
 	/* FIXME Cope with genuine pe_count 0 */
 
diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c
index 0ffe334..d71f1ec 100644
--- a/lib/format_text/import_vsn1.c
+++ b/lib/format_text/import_vsn1.c
@@ -673,10 +673,6 @@ static struct volume_group *_read_vg(struct format_instance *fid,
 	vg->vgmem = mem;
 	vg->cmd = fid->fmt->cmd;
 
-	/* FIXME Determine format type from file contents */
-	/* eg Set to instance of fmt1 here if reading a format1 backup? */
-	vg->fid = fid;
-
 	if (!(vg->name = dm_pool_strdup(mem, vgn->key)))
 		goto_bad;
 
@@ -812,6 +808,10 @@ static struct volume_group *_read_vg(struct format_instance *fid,
 	dm_hash_destroy(pv_hash);
 	dm_hash_destroy(lv_hash);
 
+	/* FIXME Determine format type from file contents */
+	/* eg Set to instance of fmt1 here if reading a format1 backup? */
+	vg_set_fid(vg, fid);
+
 	/*
 	 * Finished.
 	 */
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 5fba636..cfbc1b7 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -166,14 +166,24 @@ void add_pvl_to_vgs(struct volume_group *vg, struct pv_list *pvl)
 	dm_list_add(&vg->pvs, &pvl->list);
 	vg->pv_count++;
 	pvl->pv->vg = vg;
-	pvl->pv->fid = vg->fid;
+	pv_set_fid(pvl->pv, vg->fid);
 }
 
 void del_pvl_from_vgs(struct volume_group *vg, struct pv_list *pvl)
 {
+	struct format_instance_ctx fic;
+	struct format_instance *fid;
+
 	vg->pv_count--;
 	dm_list_del(&pvl->list);
 	pvl->pv->vg = NULL; /* orphan */
+
+	/* Use a new PV-based format instance since the PV is orphan now. */
+	fic.type = FMT_INSTANCE_PV | FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
+	fic.context.pv_id = (const char *) &pvl->pv->id;
+	fid = pvl->pv->fid->fmt->ops->create_instance(pvl->pv->fid->fmt, &fic);
+
+	pv_set_fid(pvl->pv, fid);
 }
 
 
@@ -288,6 +298,10 @@ static int _copy_pv(struct dm_pool *pvmem,
 {
 	memcpy(pv_to, pv_from, sizeof(*pv_to));
 
+	/* We must use pv_set_fid here to update the reference counter! */
+	pv_to->fid = NULL;
+	pv_set_fid(pv_to, pv_from->fid);
+
 	if (!(pv_to->vg_name = dm_pool_strdup(pvmem, pv_from->vg_name)))
 		return_0;
 
@@ -890,6 +904,7 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name)
 {
 	struct volume_group *vg;
 	struct format_instance_ctx fic;
+	struct format_instance *fid;
 	int consistent = 0;
 	struct dm_pool *mem;
 	uint32_t rc;
@@ -966,10 +981,11 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name)
 	fic.type = FMT_INSTANCE_VG | FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
 	fic.context.vg_ref.vg_name = vg_name;
 	fic.context.vg_ref.vg_id = NULL;
-	if (!(vg->fid = cmd->fmt->ops->create_instance(cmd->fmt, &fic))) {
+	if (!(fid = cmd->fmt->ops->create_instance(cmd->fmt, &fic))) {
 		log_error("Failed to create format instance");
 		goto bad;
 	}
+	vg_set_fid(vg, fid);
 
 	if (vg->fid->fmt->ops->vg_setup &&
 	    !vg->fid->fmt->ops->vg_setup(vg->fid, vg)) {
@@ -1536,7 +1552,7 @@ static struct physical_volume *_alloc_pv(struct dm_pool *mem, struct device *dev
 	if (!pv)
 		return_NULL;
 
-	pv->fid = NULL;
+	pv_set_fid(pv, NULL);
 	pv->pe_size = 0;
 	pv->pe_start = 0;
 	pv->pe_count = 0;
@@ -1591,6 +1607,7 @@ struct physical_volume *pv_create(const struct cmd_context *cmd,
 {
 	const struct format_type *fmt = cmd->fmt;
 	struct format_instance_ctx fic;
+	struct format_instance *fid;
 	struct dm_pool *mem = fmt->cmd->mem;
 	struct physical_volume *pv = _alloc_pv(mem, dev);
 	unsigned mda_index;
@@ -1634,10 +1651,11 @@ struct physical_volume *pv_create(const struct cmd_context *cmd,
 
 	fic.type = FMT_INSTANCE_PV;
 	fic.context.pv_id = (const char *) &pv->id;
-	if (!(pv->fid = fmt->ops->create_instance(fmt, &fic))) {
+	if (!(fid = fmt->ops->create_instance(fmt, &fic))) {
 		log_error("Couldn't create format instance for PV %s.", pv_dev_name(pv));
 		goto bad;
 	}
+	pv_set_fid(pv, fid);
 
 	pv->fmt = fmt;
 	pv->vg_name = fmt->orphan_vg_name;
@@ -2609,6 +2627,7 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd,
 					     const char *orphan_vgname)
 {
 	struct format_instance_ctx fic;
+	struct format_instance *fid;
 	struct lvmcache_vginfo *vginfo;
 	struct lvmcache_info *info;
 	struct pv_list *pvl;
@@ -2643,10 +2662,11 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd,
 	fic.type = FMT_INSTANCE_VG | FMT_INSTANCE_AUX_MDAS;
 	fic.context.vg_ref.vg_name = orphan_vgname;
 	fic.context.vg_ref.vg_id = NULL;
-	if (!(vg->fid = vginfo->fmt->ops->create_instance(vginfo->fmt, &fic))) {
+	if (!(fid = vginfo->fmt->ops->create_instance(vginfo->fmt, &fic))) {
 		log_error("Failed to create format instance");
 		goto bad;
 	}
+	vg_set_fid(vg, fid);
 
 	dm_list_iterate_items(info, &vginfo->infos) {
 		if (!(pv = _pv_read(cmd, mem, dev_name(info->dev),
@@ -3425,11 +3445,12 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd,
 	else {
 		fic.type = FMT_INSTANCE_PV | FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
 		fic.context.pv_id = (const char *) &pv->id;
-		if (!(pv->fid = pv->fmt->ops->create_instance(pv->fmt, &fic))) {
+		if (!(fid = pv->fmt->ops->create_instance(pv->fmt, &fic))) {
 			log_error("_pv_read: Couldn't create format instance "
 				  "for PV %s", pv_name);
 			goto bad;
 		}
+		pv_set_fid(pv, fid);
 	}
 
 	return pv;
@@ -3980,14 +4001,31 @@ bad:
 	return NULL;
 }
 
+void pv_set_fid(struct physical_volume *pv,
+		struct format_instance *fid)
+{
+	if (pv->fid)
+		pv->fid->fmt->ops->destroy_instance(pv->fid);
+
+	pv->fid = fid;
+	if (fid)
+		fid->ref_count++;
+}
+
 void vg_set_fid(struct volume_group *vg,
 		 struct format_instance *fid)
 {
 	struct pv_list *pvl;
 
+	if (vg->fid)
+		vg->fid->fmt->ops->destroy_instance(vg->fid);
+
 	vg->fid = fid;
+	if (fid)
+		fid->ref_count++;
+
 	dm_list_iterate_items(pvl, &vg->pvs)
-		pvl->pv->fid = fid;
+		pv_set_fid(pvl->pv, fid);
 }
 
 static int _convert_key_to_string(const char *key, size_t key_len,
diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h
index 8f0a6b1..46311df 100644
--- a/lib/metadata/metadata.h
+++ b/lib/metadata/metadata.h
@@ -206,6 +206,7 @@ struct format_instance_ctx {
 
 struct format_instance *alloc_fid(const struct format_type *fmt,
 				  const struct format_instance_ctx *fic);
+void pv_set_fid(struct physical_volume *pv, struct format_instance *fid);
 void vg_set_fid(struct volume_group *vg, struct format_instance *fid);
 /* FIXME: Add generic interface for mda counts based on given key. */
 int fid_add_mda(struct format_instance *fid, struct metadata_area *mda,
-- 
1.7.4




More information about the lvm-devel mailing list