[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[lvm-devel] [PATCH] Clear up the confusing "precommit(ed)" terminology



Hi,

we have discussed the current use of "precommit" and "precommitted"
terminology as related to LVM metadata with Alasdair, and arrived at the
following conclusion:

The *state* of the metadata, what was most of the time called
"precommitted" (and sometimes "precommit") is changed to "tentative".

The *act* of writing the "precommitted" (i.e. tentative) metadata, which
has been called "precommit" is now more explicitly part of vg_write (the
*action* of precommitting only existed as part of metadata_area_ops and
was called vg_precommit). To reflect the two-phase nature of vg_write
with multiple MDAs, I have renamed vg_write in metadata_area_ops to
vg_write_phase1 and vg_precommit to vg_write_phase2. Other suggestions
have been made, for now I picked phase1/phase2 because it is the easiest
to track down and rename to any other combination of names.

The current (proposed) terminology therefore is:
- the metadata after vg_write, but before vg_commit is "tentative"
- the metadata after vg_write *and* vg_commit is "committed"

There is no user-visible state between not-yet-written and tentative
(even though vg_write is internally a 2-phase operation, this is not
exposed in the metadata layer API).

I am attaching 2 diffs, the first is the changes I did manually, the
second is these changes with

find -name \*.\[hc\] | xargs sed -i.orig -e 's,precommitted,tentative,g;s,PRECOMMIT\(TED\)\?,TENTATIVE,g;s,pre-committed,tentative,g;'

on top (you can use interdiff to see just the diff produced by sed).

Yours,
  Petr

Index: lib/format1/format1.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/format1/format1.c,v
retrieving revision 1.139
diff -u -p -r1.139 format1.c
--- lib/format1/format1.c	1 Jun 2011 19:29:32 -0000	1.139
+++ lib/format1/format1.c	31 Aug 2011 18:06:24 -0000
@@ -509,7 +509,7 @@ static int _format1_segtype_supported(st
 
 static struct metadata_area_ops _metadata_format1_ops = {
 	.vg_read = _format1_vg_read,
-	.vg_write = _format1_vg_write,
+	.vg_write_phase1 = _format1_vg_write,
 };
 
 static struct format_instance *_format1_create_instance(const struct format_type *fmt,
Index: lib/format_text/archiver.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/format_text/archiver.c,v
retrieving revision 1.47
diff -u -p -r1.47 archiver.c
--- lib/format_text/archiver.c	10 Aug 2011 20:25:30 -0000	1.47
+++ lib/format_text/archiver.c	31 Aug 2011 18:06:24 -0000
@@ -407,12 +407,20 @@ int backup_to_file(const char *file, con
 		return 0;
 	}
 
-	/* Write and commit the metadata area */
+	/*
+	 * Write and commit the metadata area(s). We want to write/commit each
+	 * MDA separately, since this is a backup, and failure of one backup
+	 * location should not affect others.
+	 */
 	dm_list_iterate_items(mda, &tf->metadata_areas_in_use) {
-		if (!(r = mda->ops->vg_write(tf, vg, mda))) {
+		if (!(r = mda->ops->vg_write_phase1(tf, vg, mda))) {
 			stack;
 			continue;
 		}
+		if (mda->ops->vg_write_phase2 &&
+		    !(r = mda->ops->vg_write_phase2(tf, vg, mda))) {
+			stack;
+		}
 		if (mda->ops->vg_commit &&
 		    !(r = mda->ops->vg_commit(tf, vg, mda))) {
 			stack;
Index: lib/format_text/format-text.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/format_text/format-text.c,v
retrieving revision 1.185
diff -u -p -r1.185 format-text.c
--- lib/format_text/format-text.c	30 Aug 2011 14:55:17 -0000	1.185
+++ lib/format_text/format-text.c	31 Aug 2011 18:06:27 -0000
@@ -461,7 +461,7 @@ static int _raw_holds_vgname(struct form
 			     struct device_area *dev_area, const char *vgname)
 {
 	int r = 0;
-	int noprecommit = 0;
+	int notentative = 0;
 	struct mda_header *mdah;
 
 	if (!dev_open_readonly(dev_area->dev))
@@ -470,7 +470,7 @@ static int _raw_holds_vgname(struct form
 	if (!(mdah = raw_read_mda_header(fid->fmt, dev_area)))
 		return_0;
 
-	if (_find_vg_rlocn(dev_area, mdah, vgname, &noprecommit))
+	if (_find_vg_rlocn(dev_area, mdah, vgname, &notentative))
 		r = 1;
 
 	if (!dev_close(dev_area->dev))
@@ -546,7 +546,7 @@ static struct volume_group *_vg_read_raw
 	return vg;
 }
 
-static struct volume_group *_vg_read_precommit_raw(struct format_instance *fid,
+static struct volume_group *_vg_read_tentative_raw(struct format_instance *fid,
 						   const char *vgname,
 						   struct metadata_area *mda)
 {
@@ -564,8 +564,8 @@ static struct volume_group *_vg_read_pre
 	return vg;
 }
 
-static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
-			 struct metadata_area *mda)
+static int _vg_write_phase1_raw(struct format_instance *fid, struct volume_group *vg,
+				struct metadata_area *mda)
 {
 	struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
 	struct text_fid_context *fidtc = (struct text_fid_context *) fid->private;
@@ -575,7 +575,7 @@ static int _vg_write_raw(struct format_i
 	int r = 0;
        uint64_t new_wrap = 0, old_wrap = 0, new_end;
 	int found = 0;
-	int noprecommit = 0;
+	int notentative = 0;
 
 	/* Ignore any mda on a PV outside the VG. vgsplit relies on this */
 	dm_list_iterate_items(pvl, &vg->pvs) {
@@ -595,7 +595,7 @@ static int _vg_write_raw(struct format_i
 		goto_out;
 
 	rlocn = _find_vg_rlocn(&mdac->area, mdah,
-			vg->old_name ? vg->old_name : vg->name, &noprecommit);
+			vg->old_name ? vg->old_name : vg->name, &notentative);
 	mdac->rlocn.offset = _next_rlocn_offset(rlocn, mdah);
 
 	if (!fidtc->raw_metadata_buf &&
@@ -672,10 +672,10 @@ static int _vg_write_raw(struct format_i
 	return r;
 }
 
-static int _vg_commit_raw_rlocn(struct format_instance *fid,
-				struct volume_group *vg,
-				struct metadata_area *mda,
-				int precommit)
+static int _vg_write_rlocn_raw(struct format_instance *fid,
+			       struct volume_group *vg,
+			       struct metadata_area *mda,
+			       int tentative)
 {
 	struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
 	struct text_fid_context *fidtc = (struct text_fid_context *) fid->private;
@@ -684,7 +684,7 @@ static int _vg_commit_raw_rlocn(struct f
 	struct pv_list *pvl;
 	int r = 0;
 	int found = 0;
-	int noprecommit = 0;
+	int notentative = 0;
 
 	/* Ignore any mda on a PV outside the VG. vgsplit relies on this */
 	dm_list_iterate_items(pvl, &vg->pvs) {
@@ -702,7 +702,7 @@ static int _vg_commit_raw_rlocn(struct f
 
 	if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah,
 				     vg->old_name ? vg->old_name : vg->name,
-				     &noprecommit))) {
+				     &notentative))) {
 		mdah->raw_locns[0].offset = 0;
 		mdah->raw_locns[0].size = 0;
 		mdah->raw_locns[0].checksum = 0;
@@ -715,10 +715,10 @@ static int _vg_commit_raw_rlocn(struct f
 		rlocn = &mdah->raw_locns[0];
 	}
 
-	if (precommit)
+	if (tentative)
 		rlocn++;
 	else {
-		/* If not precommitting, wipe the precommitted rlocn */
+		/* If writing the committed rlocn, wipe the tentative one */
 		mdah->raw_locns[1].offset = 0;
 		mdah->raw_locns[1].size = 0;
 		mdah->raw_locns[1].checksum = 0;
@@ -729,11 +729,11 @@ static int _vg_commit_raw_rlocn(struct f
 		rlocn->offset = mdac->rlocn.offset;
 		rlocn->size = mdac->rlocn.size;
 		rlocn->checksum = mdac->rlocn.checksum;
-		log_debug("%sCommitting %s metadata (%u) to %s header at %"
-			  PRIu64, precommit ? "Pre-" : "", vg->name, vg->seqno,
+		log_debug("%s %s metadata (%u) to %s header at %"
+			  PRIu64, tentative ? "Writing tentative" : "Committing", vg->name, vg->seqno,
 			  dev_name(mdac->area.dev), mdac->area.start);
 	} else
-		log_debug("Wiping pre-committed %s metadata from %s "
+		log_debug("Wiping tentative %s metadata from %s "
 			  "header at %" PRIu64, vg->name,
 			  dev_name(mdac->area.dev), mdac->area.start);
 
@@ -748,7 +748,7 @@ static int _vg_commit_raw_rlocn(struct f
 	r = 1;
 
       out:
-	if (!precommit) {
+	if (!tentative) {
 		if (!dev_close(mdac->area.dev))
 			stack;
 		if (fidtc->raw_metadata_buf) {
@@ -763,14 +763,14 @@ static int _vg_commit_raw_rlocn(struct f
 static int _vg_commit_raw(struct format_instance *fid, struct volume_group *vg,
 			  struct metadata_area *mda)
 {
-	return _vg_commit_raw_rlocn(fid, vg, mda, 0);
+	return _vg_write_rlocn_raw(fid, vg, mda, 0);
 }
 
-static int _vg_precommit_raw(struct format_instance *fid,
-			     struct volume_group *vg,
-			     struct metadata_area *mda)
+static int _vg_write_phase2_raw(struct format_instance *fid,
+				struct volume_group *vg,
+				struct metadata_area *mda)
 {
-	return _vg_commit_raw_rlocn(fid, vg, mda, 1);
+	return _vg_write_rlocn_raw(fid, vg, mda, 1);
 }
 
 /* Close metadata area devices */
@@ -794,7 +794,7 @@ static int _vg_revert_raw(struct format_
 
 	/* Wipe pre-committed metadata */
 	mdac->rlocn.size = 0;
-	return _vg_commit_raw_rlocn(fid, vg, mda, 0);
+	return _vg_write_rlocn_raw(fid, vg, mda, 0);
 }
 
 static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
@@ -804,7 +804,7 @@ static int _vg_remove_raw(struct format_
 	struct mda_header *mdah;
 	struct raw_locn *rlocn;
 	int r = 0;
-	int noprecommit = 0;
+	int notentative = 0;
 
 	if (!dev_open(mdac->area.dev))
 		return_0;
@@ -812,7 +812,7 @@ static int _vg_remove_raw(struct format_
 	if (!(mdah = raw_read_mda_header(fid->fmt, &mdac->area)))
 		goto_out;
 
-	if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit))) {
+	if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &notentative))) {
 		rlocn = &mdah->raw_locns[0];
 		mdah->raw_locns[1].offset = 0;
 	}
@@ -874,7 +874,7 @@ static struct volume_group *_vg_read_fil
 	return _vg_read_file_name(fid, vgname, tc->path_live);
 }
 
-static struct volume_group *_vg_read_precommit_file(struct format_instance *fid,
+static struct volume_group *_vg_read_tentative_file(struct format_instance *fid,
 						    const char *vgname,
 						    struct metadata_area *mda)
 {
@@ -1607,25 +1607,25 @@ static void _text_destroy(struct format_
 
 static struct metadata_area_ops _metadata_text_file_ops = {
 	.vg_read = _vg_read_file,
-	.vg_read_precommit = _vg_read_precommit_file,
-	.vg_write = _vg_write_file,
+	.vg_read_tentative = _vg_read_tentative_file,
+	.vg_write_phase1 = _vg_write_file,
 	.vg_remove = _vg_remove_file,
 	.vg_commit = _vg_commit_file
 };
 
 static struct metadata_area_ops _metadata_text_file_backup_ops = {
 	.vg_read = _vg_read_file,
-	.vg_write = _vg_write_file,
+	.vg_write_phase1 = _vg_write_file,
 	.vg_remove = _vg_remove_file,
 	.vg_commit = _vg_commit_file_backup
 };
 
 static struct metadata_area_ops _metadata_text_raw_ops = {
 	.vg_read = _vg_read_raw,
-	.vg_read_precommit = _vg_read_precommit_raw,
-	.vg_write = _vg_write_raw,
+	.vg_read_tentative = _vg_read_tentative_raw,
+	.vg_write_phase1 = _vg_write_phase1_raw,
+	.vg_write_phase2 = _vg_write_phase2_raw,
 	.vg_remove = _vg_remove_raw,
-	.vg_precommit = _vg_precommit_raw,
 	.vg_commit = _vg_commit_raw,
 	.vg_revert = _vg_revert_raw,
 	.mda_metadata_locn_copy = _metadata_locn_copy_raw,
Index: lib/metadata/metadata.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/metadata/metadata.c,v
retrieving revision 1.466
diff -u -p -r1.466 metadata.c
--- lib/metadata/metadata.c	30 Aug 2011 14:55:17 -0000	1.466
+++ lib/metadata/metadata.c	31 Aug 2011 18:06:32 -0000
@@ -2519,8 +2519,13 @@ out:
 }
 
 /*
- * After vg_write() returns success,
- * caller MUST call either vg_commit() or vg_revert()
+ * After vg_write() returns success, caller MUST call either vg_commit() or
+ * vg_revert(). When vg_write finishes, the metadata written on disk is in
+ * "tentative" state. In a cluster, other machines can read tentative metadata
+ * during a coordinated cluster-wide volume activation. When vg_commit is
+ * called, the currently written tentative metadata is upgraded to committed. On
+ * the other hand, vg_revert erases the tentative metadata, keeping the existing
+ * committed metadata intact.
  */
 int vg_write(struct volume_group *vg)
 {
@@ -2571,7 +2576,7 @@ int vg_write(struct volume_group *vg)
 
 	/* Write to each copy of the metadata area */
 	dm_list_iterate_items(mda, &vg->fid->metadata_areas_in_use) {
-		if (!mda->ops->vg_write) {
+		if (!mda->ops->vg_write_phase1) {
 			log_error("Format does not support writing volume"
 				  "group metadata areas");
 			/* Revert */
@@ -2585,7 +2590,7 @@ int vg_write(struct volume_group *vg)
 			}
 			return 0;
 		}
-		if (!mda->ops->vg_write(vg->fid, vg, mda)) {
+		if (!mda->ops->vg_write_phase1(vg->fid, vg, mda)) {
 			stack;
 			/* Revert */
 			dm_list_uniterate(mdah, &vg->fid->metadata_areas_in_use, &mda->list) {
@@ -2602,8 +2607,8 @@ int vg_write(struct volume_group *vg)
 
 	/* Now pre-commit each copy of the new metadata */
 	dm_list_iterate_items(mda, &vg->fid->metadata_areas_in_use) {
-		if (mda->ops->vg_precommit &&
-		    !mda->ops->vg_precommit(vg->fid, vg, mda)) {
+		if (mda->ops->vg_write_phase2 &&
+		    !mda->ops->vg_write_phase2(vg->fid, vg, mda)) {
 			stack;
 			/* Revert */
 			dm_list_iterate_items(mda, &vg->fid->metadata_areas_in_use) {
@@ -2945,7 +2950,7 @@ static struct volume_group *_vg_read(str
 	dm_list_iterate_items(mda, &fid->metadata_areas_in_use) {
 
 		if ((use_precommitted &&
-		     !(vg = mda->ops->vg_read_precommit(fid, vgname, mda))) ||
+		     !(vg = mda->ops->vg_read_tentative(fid, vgname, mda))) ||
 		    (!use_precommitted &&
 		     !(vg = mda->ops->vg_read(fid, vgname, mda)))) {
 			inconsistent = 1;
@@ -3122,7 +3127,7 @@ static struct volume_group *_vg_read(str
 		inconsistent_mda_count=0;
 		dm_list_iterate_items(mda, &fid->metadata_areas_in_use) {
 			if ((use_precommitted &&
-			     !(vg = mda->ops->vg_read_precommit(fid, vgname,
+			     !(vg = mda->ops->vg_read_tentative(fid, vgname,
 								mda))) ||
 			    (!use_precommitted &&
 			     !(vg = mda->ops->vg_read(fid, vgname, mda)))) {
Index: lib/metadata/metadata.h
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/metadata/metadata.h,v
retrieving revision 1.250
diff -u -p -r1.250 metadata.h
--- lib/metadata/metadata.h	30 Aug 2011 14:55:17 -0000	1.250
+++ lib/metadata/metadata.h	31 Aug 2011 18:06:32 -0000
@@ -106,9 +106,9 @@ struct metadata_area_ops {
 	struct volume_group *(*vg_read) (struct format_instance * fi,
 					 const char *vg_name,
 					 struct metadata_area * mda);
-	struct volume_group *(*vg_read_precommit) (struct format_instance * fi,
-					 const char *vg_name,
-					 struct metadata_area * mda);
+	struct volume_group *(*vg_read_tentative) (struct format_instance * fi,
+						   const char *vg_name,
+						   struct metadata_area * mda);
 	/*
 	 * Write out complete VG metadata.  You must ensure internal
 	 * consistency before calling. eg. PEs can't refer to PVs not
@@ -116,18 +116,22 @@ struct metadata_area_ops {
 	 *
 	 * It is also the responsibility of the caller to ensure external
 	 * consistency, eg by calling pv_write() if removing PVs from
-	 * a VG or calling vg_write() a second time if splitting a VG
+	 * a VG or calling vg_write_*() a second time if splitting a VG
 	 * into two.
 	 *
-	 * vg_write() should not read or write from any PVs not included
+	 * vg_write_*() should not read or write from any PVs not included
 	 * in the volume_group structure it is handed.
 	 * (format1 currently breaks this rule.)
+	 *
+	 * In general, vg_write_* should only be called through vg_write() as
+	 * implemented in metadata.c
 	 */
-	int (*vg_write) (struct format_instance * fid, struct volume_group * vg,
-			 struct metadata_area * mda);
-	int (*vg_precommit) (struct format_instance * fid,
-			     struct volume_group * vg,
-			     struct metadata_area * mda);
+	int (*vg_write_phase1) (struct format_instance * fid,
+				struct volume_group * vg,
+				struct metadata_area * mda);
+	int (*vg_write_phase2) (struct format_instance * fid,
+				struct volume_group * vg,
+				struct metadata_area * mda);
 	int (*vg_commit) (struct format_instance * fid,
 			  struct volume_group * vg, struct metadata_area * mda);
 	int (*vg_revert) (struct format_instance * fid,
Index: lib/activate/activate.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/activate/activate.c,v
retrieving revision 1.212
diff -u -p -r1.212 activate.c
--- lib/activate/activate.c	30 Aug 2011 14:55:16 -0000	1.212
+++ lib/activate/activate.c	31 Aug 2011 18:26:25 -0000
@@ -1142,7 +1142,7 @@ static int _lv_suspend(struct cmd_contex
 	if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
 		goto_out;
 
-	/* Use precommitted metadata if present */
+	/* Use tentative metadata if present */
 	if (!(lv_pre = lv_from_lvid(cmd, lvid_s, 1)))
 		goto_out;
 
@@ -1251,12 +1251,12 @@ static int _lv_suspend(struct cmd_contex
  	 * inactive table to load or not instead so lv_suspend
  	 * can be called separately for each LV safely.
  	 */
-	if ((lv_pre->vg->status & PRECOMMITTED) &&
+	if ((lv_pre->vg->status & TENTATIVE) &&
 	    (lv_pre->status & LOCKED) && find_pvmove_lv_in_lv(lv_pre)) {
 		if (!_lv_suspend_lv(lv_pre, laopts, lockfs, flush_required)) {
-			critical_section_dec(cmd, "failed precommitted suspend");
+			critical_section_dec(cmd, "failed tentative suspend");
 			if (pvmove_lv)
-				critical_section_dec(cmd, "failed precommitted suspend (pvmove)");
+				critical_section_dec(cmd, "failed tentative suspend (pvmove)");
 			goto_out;
 		}
 	} else {
Index: lib/activate/dev_manager.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/activate/dev_manager.c,v
retrieving revision 1.231
diff -u -p -r1.231 dev_manager.c
--- lib/activate/dev_manager.c	30 Aug 2011 14:55:16 -0000	1.231
+++ lib/activate/dev_manager.c	31 Aug 2011 18:26:26 -0000
@@ -1579,7 +1579,7 @@ static int _add_new_lv_to_dtree(struct d
 
 	/*
 	 * Add LV to dtree.
-	 * If we're working with precommitted metadata, clear any
+	 * If we're working with tentative metadata, clear any
 	 * existing inactive table left behind.
 	 * Major/minor settings only apply to the visible layer.
 	 */
@@ -1590,7 +1590,7 @@ static int _add_new_lv_to_dtree(struct d
 					     layer ? UINT32_C(0) : (uint32_t) lv->major,
 					     layer ? UINT32_C(0) : (uint32_t) lv->minor,
 					     _read_only_lv(lv),
-					     (lv->vg->status & PRECOMMITTED) ? 1 : 0,
+					     (lv->vg->status & TENTATIVE) ? 1 : 0,
 					     lvlayer,
 					     _get_udev_flags(dm, lv, layer))))
 		return_0;
Index: lib/cache/lvmcache.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/cache/lvmcache.c,v
retrieving revision 1.117
diff -u -p -r1.117 lvmcache.c
--- lib/cache/lvmcache.c	30 Aug 2011 14:55:16 -0000	1.117
+++ lib/cache/lvmcache.c	31 Aug 2011 18:26:27 -0000
@@ -97,7 +97,7 @@ static void _free_cached_vgmetadata(stru
 /*
  * Cache VG metadata against the vginfo with matching vgid.
  */
-static void _store_metadata(struct volume_group *vg, unsigned precommitted)
+static void _store_metadata(struct volume_group *vg, unsigned tentative)
 {
 	char uuid[64] __attribute__((aligned(8)));
 	struct lvmcache_vginfo *vginfo;
@@ -125,7 +125,7 @@ static void _store_metadata(struct volum
 		vginfo->vgmetadata = data;
 	}
 
-	vginfo->precommitted = precommitted;
+	vginfo->tentative = tentative;
 
 	if (!id_write_format((const struct id *)vginfo->vgid, uuid, sizeof(uuid))) {
 		stack;
@@ -134,7 +134,7 @@ static void _store_metadata(struct volum
 
 	log_debug("Metadata cache: VG %s (%s) stored (%d bytes%s).",
 		  vginfo->vgname, uuid, size,
-		  precommitted ? ", precommitted" : "");
+		  tentative ? ", tentative" : "");
 }
 
 static void _update_cache_info_lock_state(struct lvmcache_info *info,
@@ -182,7 +182,7 @@ static void _update_cache_lock_state(con
 	_update_cache_vginfo_lock_state(vginfo, locked);
 }
 
-static void _drop_metadata(const char *vgname, int drop_precommitted)
+static void _drop_metadata(const char *vgname, int drop_tentative)
 {
 	struct lvmcache_vginfo *vginfo;
 	struct lvmcache_info *info;
@@ -192,15 +192,15 @@ static void _drop_metadata(const char *v
 
 	/*
 	 * Invalidate cached PV labels.
-	 * If cached precommitted metadata exists that means we
+	 * If cached tentative metadata exists that means we
 	 * already invalidated the PV labels (before caching it)
 	 * and we must not do it again.
 	 */
-	if (!drop_precommitted && vginfo->precommitted && !vginfo->vgmetadata)
+	if (!drop_tentative && vginfo->tentative && !vginfo->vgmetadata)
 		log_error(INTERNAL_ERROR "metadata commit (or revert) missing before "
 			  "dropping metadata from cache.");
 
-	if (drop_precommitted || !vginfo->precommitted)
+	if (drop_tentative || !vginfo->tentative)
 		dm_list_iterate_items(info, &vginfo->infos)
 			info->status |= CACHE_INVALID;
 
@@ -219,14 +219,14 @@ void lvmcache_commit_metadata(const char
 	if (!(vginfo = vginfo_from_vgname(vgname, NULL)))
 		return;
 
-	if (vginfo->precommitted) {
+	if (vginfo->tentative) {
 		log_debug("Precommitted metadata cache: VG %s upgraded to committed.",
 			  vginfo->vgname);
-		vginfo->precommitted = 0;
+		vginfo->tentative = 0;
 	}
 }
 
-void lvmcache_drop_metadata(const char *vgname, int drop_precommitted)
+void lvmcache_drop_metadata(const char *vgname, int drop_tentative)
 {
 	/* For VG_ORPHANS, we need to invalidate all labels on orphan PVs. */
 	if (!strcmp(vgname, VG_ORPHANS)) {
@@ -237,7 +237,7 @@ void lvmcache_drop_metadata(const char *
 		/* Indicate that PVs could now be missing from the cache */
 		init_full_scan_done(0);
 	} else if (!vgname_is_locked(VG_GLOBAL))
-		_drop_metadata(vgname, drop_precommitted);
+		_drop_metadata(vgname, drop_tentative);
 }
 
 /*
@@ -635,7 +635,7 @@ int lvmcache_label_scan(struct cmd_conte
 	return r;
 }
 
-struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted)
+struct volume_group *lvmcache_get_vg(const char *vgid, unsigned tentative)
 {
 	struct lvmcache_vginfo *vginfo;
 	struct volume_group *vg = NULL;
@@ -650,18 +650,18 @@ struct volume_group *lvmcache_get_vg(con
 
 	/*
 	 * Don't return cached data if either:
-	 * (i)  precommitted metadata is requested but we don't have it cached
+	 * (i)  tentative metadata is requested but we don't have it cached
 	 *      - caller should read it off disk;
-	 * (ii) live metadata is requested but we have precommitted metadata cached
+	 * (ii) live metadata is requested but we have tentative metadata cached
 	 *      and no devices are suspended so caller may read it off disk.
 	 *
-	 * If live metadata is requested but we have precommitted metadata cached
-	 * and devices are suspended, we assume this precommitted metadata has
+	 * If live metadata is requested but we have tentative metadata cached
+	 * and devices are suspended, we assume this tentative metadata has
 	 * already been preloaded and committed so it's OK to return it as live.
-	 * Note that we do not clear the PRECOMMITTED flag.
+	 * Note that we do not clear the TENTATIVE flag.
 	 */
-	if ((precommitted && !vginfo->precommitted) ||
-	    (!precommitted && vginfo->precommitted && !critical_section()))
+	if ((tentative && !vginfo->tentative) ||
+	    (!tentative && vginfo->tentative && !critical_section()))
 		return NULL;
 
 	/* Use already-cached VG struct when available */
@@ -696,7 +696,7 @@ out:
 	vginfo->holders++;
 	vginfo->vg_use_count++;
 	log_debug("Using cached %smetadata for VG %s with %u holder(s).",
-		  vginfo->precommitted ? "pre-committed " : "",
+		  vginfo->tentative ? "tentative " : "",
 		  vginfo->vgname, vginfo->holders);
 
 	return vg;
@@ -1305,7 +1305,7 @@ int lvmcache_update_vgname_and_id(struct
 	return 1;
 }
 
-int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted)
+int lvmcache_update_vg(struct volume_group *vg, unsigned tentative)
 {
 	struct pv_list *pvl;
 	struct lvmcache_info *info;
@@ -1325,7 +1325,7 @@ int lvmcache_update_vg(struct volume_gro
 
 	/* store text representation of vg to cache */
 	if (vg->cmd->current_settings.cache_vgmetadata)
-		_store_metadata(vg, precommitted);
+		_store_metadata(vg, tentative);
 
 	return 1;
 }
Index: lib/cache/lvmcache.h
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/cache/lvmcache.h,v
retrieving revision 1.41
diff -u -p -r1.41 lvmcache.h
--- lib/cache/lvmcache.h	30 Aug 2011 14:55:16 -0000	1.41
+++ lib/cache/lvmcache.h	31 Aug 2011 18:26:27 -0000
@@ -53,7 +53,7 @@ struct lvmcache_vginfo {
 	struct volume_group *cached_vg;
 	unsigned holders;
 	unsigned vg_use_count;	/* Counter of vg reusage */
-	unsigned precommitted;	/* Is vgmetadata live or precommitted? */
+	unsigned tentative;	/* Is vgmetadata live or tentative? */
 };
 
 /* One per device */
@@ -88,7 +88,7 @@ void lvmcache_del(struct lvmcache_info *
 int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
 				  const char *vgname, const char *vgid,
 				  uint32_t vgstatus, const char *hostname);
-int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted);
+int lvmcache_update_vg(struct volume_group *vg, unsigned tentative);
 
 void lvmcache_lock_vgname(const char *vgname, int read_only);
 void lvmcache_unlock_vgname(const char *vgname);
@@ -126,8 +126,8 @@ struct dm_list *lvmcache_get_pvids(struc
 				const char *vgid);
 
 /* Returns cached volume group metadata. */
-struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted);
-void lvmcache_drop_metadata(const char *vgname, int drop_precommitted);
+struct volume_group *lvmcache_get_vg(const char *vgid, unsigned tentative);
+void lvmcache_drop_metadata(const char *vgname, int drop_tentative);
 void lvmcache_commit_metadata(const char *vgname);
 
 #endif
Index: lib/format1/format1.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/format1/format1.c,v
retrieving revision 1.139
diff -u -p -r1.139 format1.c
--- lib/format1/format1.c	1 Jun 2011 19:29:32 -0000	1.139
+++ lib/format1/format1.c	31 Aug 2011 18:26:31 -0000
@@ -509,7 +509,7 @@ static int _format1_segtype_supported(st
 
 static struct metadata_area_ops _metadata_format1_ops = {
 	.vg_read = _format1_vg_read,
-	.vg_write = _format1_vg_write,
+	.vg_write_phase1 = _format1_vg_write,
 };
 
 static struct format_instance *_format1_create_instance(const struct format_type *fmt,
Index: lib/format_text/archiver.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/format_text/archiver.c,v
retrieving revision 1.47
diff -u -p -r1.47 archiver.c
--- lib/format_text/archiver.c	10 Aug 2011 20:25:30 -0000	1.47
+++ lib/format_text/archiver.c	31 Aug 2011 18:26:33 -0000
@@ -407,12 +407,20 @@ int backup_to_file(const char *file, con
 		return 0;
 	}
 
-	/* Write and commit the metadata area */
+	/*
+	 * Write and commit the metadata area(s). We want to write/commit each
+	 * MDA separately, since this is a backup, and failure of one backup
+	 * location should not affect others.
+	 */
 	dm_list_iterate_items(mda, &tf->metadata_areas_in_use) {
-		if (!(r = mda->ops->vg_write(tf, vg, mda))) {
+		if (!(r = mda->ops->vg_write_phase1(tf, vg, mda))) {
 			stack;
 			continue;
 		}
+		if (mda->ops->vg_write_phase2 &&
+		    !(r = mda->ops->vg_write_phase2(tf, vg, mda))) {
+			stack;
+		}
 		if (mda->ops->vg_commit &&
 		    !(r = mda->ops->vg_commit(tf, vg, mda))) {
 			stack;
Index: lib/format_text/flags.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/format_text/flags.c,v
retrieving revision 1.47
diff -u -p -r1.47 flags.c
--- lib/format_text/flags.c	30 Aug 2011 14:55:17 -0000	1.47
+++ lib/format_text/flags.c	31 Aug 2011 18:26:34 -0000
@@ -37,7 +37,7 @@ static const struct flag _vg_flags[] = {
 	{CLUSTERED, "CLUSTERED", STATUS_FLAG},
 	{SHARED, "SHARED", STATUS_FLAG},
 	{PARTIAL_VG, NULL, 0},
-	{PRECOMMITTED, NULL, 0},
+	{TENTATIVE, NULL, 0},
 	{0, NULL, 0}
 };
 
Index: lib/format_text/format-text.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/format_text/format-text.c,v
retrieving revision 1.185
diff -u -p -r1.185 format-text.c
--- lib/format_text/format-text.c	30 Aug 2011 14:55:17 -0000	1.185
+++ lib/format_text/format-text.c	31 Aug 2011 18:26:36 -0000
@@ -390,22 +390,22 @@ static int _raw_write_mda_header(const s
 static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
 				       struct mda_header *mdah,
 				       const char *vgname,
-				       int *precommitted)
+				       int *tentative)
 {
 	size_t len;
 	char vgnamebuf[NAME_LEN + 2] __attribute__((aligned(8)));
-	struct raw_locn *rlocn, *rlocn_precommitted;
+	struct raw_locn *rlocn, *rlocn_tentative;
 	struct lvmcache_info *info;
 
 	rlocn = mdah->raw_locns;	/* Slot 0 */
-	rlocn_precommitted = rlocn + 1;	/* Slot 1 */
+	rlocn_tentative = rlocn + 1;	/* Slot 1 */
 
-	/* Should we use precommitted metadata? */
-	if (*precommitted && rlocn_precommitted->size &&
-	    (rlocn_precommitted->offset != rlocn->offset)) {
-		rlocn = rlocn_precommitted;
+	/* Should we use tentative metadata? */
+	if (*tentative && rlocn_tentative->size &&
+	    (rlocn_tentative->offset != rlocn->offset)) {
+		rlocn = rlocn_tentative;
 	} else
-		*precommitted = 0;
+		*tentative = 0;
 
 	/* Do not check non-existent metadata. */
 	if (!rlocn->offset && !rlocn->size)
@@ -461,7 +461,7 @@ static int _raw_holds_vgname(struct form
 			     struct device_area *dev_area, const char *vgname)
 {
 	int r = 0;
-	int noprecommit = 0;
+	int notentative = 0;
 	struct mda_header *mdah;
 
 	if (!dev_open_readonly(dev_area->dev))
@@ -470,7 +470,7 @@ static int _raw_holds_vgname(struct form
 	if (!(mdah = raw_read_mda_header(fid->fmt, dev_area)))
 		return_0;
 
-	if (_find_vg_rlocn(dev_area, mdah, vgname, &noprecommit))
+	if (_find_vg_rlocn(dev_area, mdah, vgname, &notentative))
 		r = 1;
 
 	if (!dev_close(dev_area->dev))
@@ -482,7 +482,7 @@ static int _raw_holds_vgname(struct form
 static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
 					      const char *vgname,
 					      struct device_area *area,
-					      int precommitted)
+					      int tentative)
 {
 	struct volume_group *vg = NULL;
 	struct raw_locn *rlocn;
@@ -494,7 +494,7 @@ static struct volume_group *_vg_read_raw
 	if (!(mdah = raw_read_mda_header(fid->fmt, area)))
 		goto_out;
 
-	if (!(rlocn = _find_vg_rlocn(area, mdah, vgname, &precommitted))) {
+	if (!(rlocn = _find_vg_rlocn(area, mdah, vgname, &tentative))) {
 		log_debug("VG %s not found on %s", vgname, dev_name(area->dev));
 		goto out;
 	}
@@ -517,12 +517,12 @@ static struct volume_group *_vg_read_raw
 				     &desc)))
 		goto_out;
 	log_debug("Read %s %smetadata (%u) from %s at %" PRIu64 " size %"
-		  PRIu64, vg->name, precommitted ? "pre-commit " : "",
+		  PRIu64, vg->name, tentative ? "pre-commit " : "",
 		  vg->seqno, dev_name(area->dev),
 		  area->start + rlocn->offset, rlocn->size);
 
-	if (precommitted)
-		vg->status |= PRECOMMITTED;
+	if (tentative)
+		vg->status |= TENTATIVE;
 
       out:
 	return vg;
@@ -546,7 +546,7 @@ static struct volume_group *_vg_read_raw
 	return vg;
 }
 
-static struct volume_group *_vg_read_precommit_raw(struct format_instance *fid,
+static struct volume_group *_vg_read_tentative_raw(struct format_instance *fid,
 						   const char *vgname,
 						   struct metadata_area *mda)
 {
@@ -564,8 +564,8 @@ static struct volume_group *_vg_read_pre
 	return vg;
 }
 
-static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
-			 struct metadata_area *mda)
+static int _vg_write_phase1_raw(struct format_instance *fid, struct volume_group *vg,
+				struct metadata_area *mda)
 {
 	struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
 	struct text_fid_context *fidtc = (struct text_fid_context *) fid->private;
@@ -575,7 +575,7 @@ static int _vg_write_raw(struct format_i
 	int r = 0;
        uint64_t new_wrap = 0, old_wrap = 0, new_end;
 	int found = 0;
-	int noprecommit = 0;
+	int notentative = 0;
 
 	/* Ignore any mda on a PV outside the VG. vgsplit relies on this */
 	dm_list_iterate_items(pvl, &vg->pvs) {
@@ -595,7 +595,7 @@ static int _vg_write_raw(struct format_i
 		goto_out;
 
 	rlocn = _find_vg_rlocn(&mdac->area, mdah,
-			vg->old_name ? vg->old_name : vg->name, &noprecommit);
+			vg->old_name ? vg->old_name : vg->name, &notentative);
 	mdac->rlocn.offset = _next_rlocn_offset(rlocn, mdah);
 
 	if (!fidtc->raw_metadata_buf &&
@@ -672,10 +672,10 @@ static int _vg_write_raw(struct format_i
 	return r;
 }
 
-static int _vg_commit_raw_rlocn(struct format_instance *fid,
-				struct volume_group *vg,
-				struct metadata_area *mda,
-				int precommit)
+static int _vg_write_rlocn_raw(struct format_instance *fid,
+			       struct volume_group *vg,
+			       struct metadata_area *mda,
+			       int tentative)
 {
 	struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
 	struct text_fid_context *fidtc = (struct text_fid_context *) fid->private;
@@ -684,7 +684,7 @@ static int _vg_commit_raw_rlocn(struct f
 	struct pv_list *pvl;
 	int r = 0;
 	int found = 0;
-	int noprecommit = 0;
+	int notentative = 0;
 
 	/* Ignore any mda on a PV outside the VG. vgsplit relies on this */
 	dm_list_iterate_items(pvl, &vg->pvs) {
@@ -702,7 +702,7 @@ static int _vg_commit_raw_rlocn(struct f
 
 	if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah,
 				     vg->old_name ? vg->old_name : vg->name,
-				     &noprecommit))) {
+				     &notentative))) {
 		mdah->raw_locns[0].offset = 0;
 		mdah->raw_locns[0].size = 0;
 		mdah->raw_locns[0].checksum = 0;
@@ -715,10 +715,10 @@ static int _vg_commit_raw_rlocn(struct f
 		rlocn = &mdah->raw_locns[0];
 	}
 
-	if (precommit)
+	if (tentative)
 		rlocn++;
 	else {
-		/* If not precommitting, wipe the precommitted rlocn */
+		/* If writing the committed rlocn, wipe the tentative one */
 		mdah->raw_locns[1].offset = 0;
 		mdah->raw_locns[1].size = 0;
 		mdah->raw_locns[1].checksum = 0;
@@ -729,11 +729,11 @@ static int _vg_commit_raw_rlocn(struct f
 		rlocn->offset = mdac->rlocn.offset;
 		rlocn->size = mdac->rlocn.size;
 		rlocn->checksum = mdac->rlocn.checksum;
-		log_debug("%sCommitting %s metadata (%u) to %s header at %"
-			  PRIu64, precommit ? "Pre-" : "", vg->name, vg->seqno,
+		log_debug("%s %s metadata (%u) to %s header at %"
+			  PRIu64, tentative ? "Writing tentative" : "Committing", vg->name, vg->seqno,
 			  dev_name(mdac->area.dev), mdac->area.start);
 	} else
-		log_debug("Wiping pre-committed %s metadata from %s "
+		log_debug("Wiping tentative %s metadata from %s "
 			  "header at %" PRIu64, vg->name,
 			  dev_name(mdac->area.dev), mdac->area.start);
 
@@ -748,7 +748,7 @@ static int _vg_commit_raw_rlocn(struct f
 	r = 1;
 
       out:
-	if (!precommit) {
+	if (!tentative) {
 		if (!dev_close(mdac->area.dev))
 			stack;
 		if (fidtc->raw_metadata_buf) {
@@ -763,14 +763,14 @@ static int _vg_commit_raw_rlocn(struct f
 static int _vg_commit_raw(struct format_instance *fid, struct volume_group *vg,
 			  struct metadata_area *mda)
 {
-	return _vg_commit_raw_rlocn(fid, vg, mda, 0);
+	return _vg_write_rlocn_raw(fid, vg, mda, 0);
 }
 
-static int _vg_precommit_raw(struct format_instance *fid,
-			     struct volume_group *vg,
-			     struct metadata_area *mda)
+static int _vg_write_phase2_raw(struct format_instance *fid,
+				struct volume_group *vg,
+				struct metadata_area *mda)
 {
-	return _vg_commit_raw_rlocn(fid, vg, mda, 1);
+	return _vg_write_rlocn_raw(fid, vg, mda, 1);
 }
 
 /* Close metadata area devices */
@@ -792,9 +792,9 @@ static int _vg_revert_raw(struct format_
 	if (!found)
 		return 1;
 
-	/* Wipe pre-committed metadata */
+	/* Wipe tentative metadata */
 	mdac->rlocn.size = 0;
-	return _vg_commit_raw_rlocn(fid, vg, mda, 0);
+	return _vg_write_rlocn_raw(fid, vg, mda, 0);
 }
 
 static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
@@ -804,7 +804,7 @@ static int _vg_remove_raw(struct format_
 	struct mda_header *mdah;
 	struct raw_locn *rlocn;
 	int r = 0;
-	int noprecommit = 0;
+	int notentative = 0;
 
 	if (!dev_open(mdac->area.dev))
 		return_0;
@@ -812,7 +812,7 @@ static int _vg_remove_raw(struct format_
 	if (!(mdah = raw_read_mda_header(fid->fmt, &mdac->area)))
 		goto_out;
 
-	if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit))) {
+	if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &notentative))) {
 		rlocn = &mdah->raw_locns[0];
 		mdah->raw_locns[1].offset = 0;
 	}
@@ -874,7 +874,7 @@ static struct volume_group *_vg_read_fil
 	return _vg_read_file_name(fid, vgname, tc->path_live);
 }
 
-static struct volume_group *_vg_read_precommit_file(struct format_instance *fid,
+static struct volume_group *_vg_read_tentative_file(struct format_instance *fid,
 						    const char *vgname,
 						    struct metadata_area *mda)
 {
@@ -882,7 +882,7 @@ static struct volume_group *_vg_read_pre
 	struct volume_group *vg;
 
 	if ((vg = _vg_read_file_name(fid, vgname, tc->path_edit)))
-		vg->status |= PRECOMMITTED;
+		vg->status |= TENTATIVE;
 	else
 		vg = _vg_read_file_name(fid, vgname, tc->path_live);
 
@@ -1607,25 +1607,25 @@ static void _text_destroy(struct format_
 
 static struct metadata_area_ops _metadata_text_file_ops = {
 	.vg_read = _vg_read_file,
-	.vg_read_precommit = _vg_read_precommit_file,
-	.vg_write = _vg_write_file,
+	.vg_read_tentative = _vg_read_tentative_file,
+	.vg_write_phase1 = _vg_write_file,
 	.vg_remove = _vg_remove_file,
 	.vg_commit = _vg_commit_file
 };
 
 static struct metadata_area_ops _metadata_text_file_backup_ops = {
 	.vg_read = _vg_read_file,
-	.vg_write = _vg_write_file,
+	.vg_write_phase1 = _vg_write_file,
 	.vg_remove = _vg_remove_file,
 	.vg_commit = _vg_commit_file_backup
 };
 
 static struct metadata_area_ops _metadata_text_raw_ops = {
 	.vg_read = _vg_read_raw,
-	.vg_read_precommit = _vg_read_precommit_raw,
-	.vg_write = _vg_write_raw,
+	.vg_read_tentative = _vg_read_tentative_raw,
+	.vg_write_phase1 = _vg_write_phase1_raw,
+	.vg_write_phase2 = _vg_write_phase2_raw,
 	.vg_remove = _vg_remove_raw,
-	.vg_precommit = _vg_precommit_raw,
 	.vg_commit = _vg_commit_raw,
 	.vg_revert = _vg_revert_raw,
 	.mda_metadata_locn_copy = _metadata_locn_copy_raw,
@@ -2344,7 +2344,7 @@ struct format_type *create_text_format(s
 	fmt->name = FMT_TEXT_NAME;
 	fmt->alias = FMT_TEXT_ALIAS;
 	fmt->orphan_vg_name = ORPHAN_VG_NAME(FMT_TEXT_NAME);
-	fmt->features = FMT_SEGMENTS | FMT_MDAS | FMT_TAGS | FMT_PRECOMMIT |
+	fmt->features = FMT_SEGMENTS | FMT_MDAS | FMT_TAGS | FMT_TENTATIVE |
 			FMT_UNLIMITED_VOLS | FMT_RESIZE_PV |
 			FMT_UNLIMITED_STRIPESIZE;
 
Index: lib/metadata/metadata-exported.h
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/metadata/metadata-exported.h,v
retrieving revision 1.203
diff -u -p -r1.203 metadata-exported.h
--- lib/metadata/metadata-exported.h	26 Aug 2011 17:40:53 -0000	1.203
+++ lib/metadata/metadata-exported.h	31 Aug 2011 18:26:45 -0000
@@ -70,7 +70,7 @@
 #define MIRROR_LOG		0x00020000U	/* LV */
 #define MIRROR_IMAGE		0x00040000U	/* LV */
 #define LV_NOTSYNCED		0x00080000U	/* LV */
-//#define PRECOMMITTED		0x00200000U	/* VG - internal use only */
+//#define TENTATIVE		0x00200000U	/* VG - internal use only */
 #define CONVERTING		0x00400000U	/* LV */
 
 #define MISSING_PV              0x00800000U	/* PV */
@@ -99,7 +99,7 @@
 #define FMT_UNLIMITED_VOLS	0x00000008U	/* Unlimited PVs/LVs? */
 #define FMT_RESTRICTED_LVIDS	0x00000010U	/* LVID <= 255 */
 #define FMT_ORPHAN_ALLOCATABLE	0x00000020U	/* Orphan PV allocatable? */
-//#define FMT_PRECOMMIT		0x00000040U	/* Supports pre-commit? */
+//#define FMT_TENTATIVE		0x00000040U	/* Supports pre-commit? */
 #define FMT_RESIZE_PV		0x00000080U	/* Supports pvresize? */
 #define FMT_UNLIMITED_STRIPESIZE 0x00000100U	/* Unlimited stripe size? */
 #define FMT_RESTRICTED_READAHEAD 0x00000200U	/* Readahead restricted to 2-120? */
Index: lib/metadata/metadata.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/metadata/metadata.c,v
retrieving revision 1.466
diff -u -p -r1.466 metadata.c
--- lib/metadata/metadata.c	30 Aug 2011 14:55:17 -0000	1.466
+++ lib/metadata/metadata.c	31 Aug 2011 18:26:47 -0000
@@ -2519,8 +2519,13 @@ out:
 }
 
 /*
- * After vg_write() returns success,
- * caller MUST call either vg_commit() or vg_revert()
+ * After vg_write() returns success, caller MUST call either vg_commit() or
+ * vg_revert(). When vg_write finishes, the metadata written on disk is in
+ * "tentative" state. In a cluster, other machines can read tentative metadata
+ * during a coordinated cluster-wide volume activation. When vg_commit is
+ * called, the currently written tentative metadata is upgraded to committed. On
+ * the other hand, vg_revert erases the tentative metadata, keeping the existing
+ * committed metadata intact.
  */
 int vg_write(struct volume_group *vg)
 {
@@ -2571,7 +2576,7 @@ int vg_write(struct volume_group *vg)
 
 	/* Write to each copy of the metadata area */
 	dm_list_iterate_items(mda, &vg->fid->metadata_areas_in_use) {
-		if (!mda->ops->vg_write) {
+		if (!mda->ops->vg_write_phase1) {
 			log_error("Format does not support writing volume"
 				  "group metadata areas");
 			/* Revert */
@@ -2585,7 +2590,7 @@ int vg_write(struct volume_group *vg)
 			}
 			return 0;
 		}
-		if (!mda->ops->vg_write(vg->fid, vg, mda)) {
+		if (!mda->ops->vg_write_phase1(vg->fid, vg, mda)) {
 			stack;
 			/* Revert */
 			dm_list_uniterate(mdah, &vg->fid->metadata_areas_in_use, &mda->list) {
@@ -2602,8 +2607,8 @@ int vg_write(struct volume_group *vg)
 
 	/* Now pre-commit each copy of the new metadata */
 	dm_list_iterate_items(mda, &vg->fid->metadata_areas_in_use) {
-		if (mda->ops->vg_precommit &&
-		    !mda->ops->vg_precommit(vg->fid, vg, mda)) {
+		if (mda->ops->vg_write_phase2 &&
+		    !mda->ops->vg_write_phase2(vg->fid, vg, mda)) {
 			stack;
 			/* Revert */
 			dm_list_iterate_items(mda, &vg->fid->metadata_areas_in_use) {
@@ -2675,7 +2680,7 @@ int vg_commit(struct volume_group *vg)
 		vg->old_name = NULL;
 	}
 
-	/* If update failed, remove any cached precommitted metadata. */
+	/* If update failed, remove any cached tentative metadata. */
 	if (!cache_updated && !drop_cached_metadata(vg))
 		log_error("Attempt to drop cached metadata failed "
 			  "after commit for VG %s.", vg->name);
@@ -2843,7 +2848,7 @@ static void check_reappeared_pv(struct v
  * and take appropriate action if it isn't (e.g. abort; get write lock
  * and call vg_read_internal again).
  *
- * If precommitted is set, use precommitted metadata if present.
+ * If tentative is set, use tentative metadata if present.
  *
  * Either of vgname or vgid may be NULL.
  *
@@ -2854,7 +2859,7 @@ static struct volume_group *_vg_read(str
 				     const char *vgname,
 				     const char *vgid,
 				     int warnings, 
-				     int *consistent, unsigned precommitted)
+				     int *consistent, unsigned tentative)
 {
 	struct format_instance *fid = NULL;
 	struct format_instance_ctx fic;
@@ -2867,7 +2872,7 @@ static struct volume_group *_vg_read(str
 	int inconsistent_pvs = 0;
 	int inconsistent_mdas = 0;
 	int inconsistent_mda_count = 0;
-	unsigned use_precommitted = precommitted;
+	unsigned use_tentative = tentative;
 	unsigned saved_handles_missing_pvs = cmd->handles_missing_pvs;
 	struct dm_list *pvids;
 	struct pv_list *pvl, *pvl2;
@@ -2875,7 +2880,7 @@ static struct volume_group *_vg_read(str
 	char uuid[64] __attribute__((aligned(8)));
 
 	if (is_orphan_vg(vgname)) {
-		if (use_precommitted) {
+		if (use_tentative) {
 			log_error(INTERNAL_ERROR "vg_read_internal requires vgname "
 				  "with pre-commit.");
 			return NULL;
@@ -2887,11 +2892,11 @@ static struct volume_group *_vg_read(str
 	/*
 	 * If cached metadata was inconsistent and *consistent is set
 	 * then repair it now.  Otherwise just return it.
-	 * Also return if use_precommitted is set due to the FIXME in
+	 * Also return if use_tentative is set due to the FIXME in
 	 * the missing PV logic below.
 	 */
-	if ((correct_vg = lvmcache_get_vg(vgid, precommitted)) &&
-	    (use_precommitted || !*consistent)) {
+	if ((correct_vg = lvmcache_get_vg(vgid, tentative)) &&
+	    (use_tentative || !*consistent)) {
 		*consistent = 1;
 		return correct_vg;
 	} else {
@@ -2917,8 +2922,8 @@ static struct volume_group *_vg_read(str
 	if (!vgname && !(vgname = vgname_from_vgid(cmd->mem, vgid)))
 		return_NULL;
 
-	if (use_precommitted && !(fmt->features & FMT_PRECOMMIT))
-		use_precommitted = 0;
+	if (use_tentative && !(fmt->features & FMT_TENTATIVE))
+		use_tentative = 0;
 
 	/* create format instance with appropriate metadata area */
 	fic.type = FMT_INSTANCE_VG | FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
@@ -2944,9 +2949,9 @@ static struct volume_group *_vg_read(str
 	inconsistent_mda_count=0;
 	dm_list_iterate_items(mda, &fid->metadata_areas_in_use) {
 
-		if ((use_precommitted &&
-		     !(vg = mda->ops->vg_read_precommit(fid, vgname, mda))) ||
-		    (!use_precommitted &&
+		if ((use_tentative &&
+		     !(vg = mda->ops->vg_read_tentative(fid, vgname, mda))) ||
+		    (!use_tentative &&
 		     !(vg = mda->ops->vg_read(fid, vgname, mda)))) {
 			inconsistent = 1;
 			release_vg(vg);
@@ -3038,10 +3043,10 @@ static struct volume_group *_vg_read(str
 				log_debug("Updating cache for PVs without mdas "
 					  "in VG %s.", vgname);
 				/*
-				 * If there is no precommitted metadata, committed metadata
-				 * is read and stored in the cache even if use_precommitted is set
+				 * If there is no tentative metadata, committed metadata
+				 * is read and stored in the cache even if use_tentative is set
 				 */
-				lvmcache_update_vg(correct_vg, correct_vg->status & PRECOMMITTED);
+				lvmcache_update_vg(correct_vg, correct_vg->status & TENTATIVE);
 
 				if (!(pvids = lvmcache_get_pvids(cmd, vgname, vgid))) {
 					release_vg(correct_vg);
@@ -3101,8 +3106,8 @@ static struct volume_group *_vg_read(str
 		if (!(fmt = fmt_from_vgname(vgname, vgid, 0)))
 			return_NULL;
 
-		if (precommitted && !(fmt->features & FMT_PRECOMMIT))
-			use_precommitted = 0;
+		if (tentative && !(fmt->features & FMT_TENTATIVE))
+			use_tentative = 0;
 
 		/* create format instance with appropriate metadata area */
 		fic.type = FMT_INSTANCE_VG | FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
@@ -3121,10 +3126,10 @@ static struct volume_group *_vg_read(str
 		/* Ensure contents of all metadata areas match - else recover */
 		inconsistent_mda_count=0;
 		dm_list_iterate_items(mda, &fid->metadata_areas_in_use) {
-			if ((use_precommitted &&
-			     !(vg = mda->ops->vg_read_precommit(fid, vgname,
+			if ((use_tentative &&
+			     !(vg = mda->ops->vg_read_tentative(fid, vgname,
 								mda))) ||
-			    (!use_precommitted &&
+			    (!use_tentative &&
 			     !(vg = mda->ops->vg_read(fid, vgname, mda)))) {
 				inconsistent = 1;
 				continue;
@@ -3185,14 +3190,14 @@ static struct volume_group *_vg_read(str
 	}
 
 	/*
-	 * If there is no precommitted metadata, committed metadata
-	 * is read and stored in the cache even if use_precommitted is set
+	 * If there is no tentative metadata, committed metadata
+	 * is read and stored in the cache even if use_tentative is set
 	 */
-	lvmcache_update_vg(correct_vg, (correct_vg->status & PRECOMMITTED));
+	lvmcache_update_vg(correct_vg, (correct_vg->status & TENTATIVE));
 
 	if (inconsistent) {
-		/* FIXME Test should be if we're *using* precommitted metadata not if we were searching for it */
-		if (use_precommitted) {
+		/* FIXME Test should be if we're *using* tentative metadata not if we were searching for it */
+		if (use_tentative) {
 			log_error("Inconsistent pre-commit metadata copies "
 				  "for volume group %s", vgname);
 
@@ -3366,7 +3371,7 @@ void free_pv_fid(struct physical_volume 
  */
 static struct volume_group *_vg_read_by_vgid(struct cmd_context *cmd,
 					    const char *vgid,
-					    unsigned precommitted)
+					    unsigned tentative)
 {
 	const char *vgname;
 	struct dm_list *vgnames;
@@ -3379,7 +3384,7 @@ static struct volume_group *_vg_read_by_
 	if ((vginfo = vginfo_from_vgid(vgid)) &&
 	    vginfo->vgname && !is_orphan_vg(vginfo->vgname)) {
 		if ((vg = _vg_read(cmd, NULL, vgid, 1,
-				   &consistent, precommitted)) &&
+				   &consistent, tentative)) &&
 		    id_equal(&vg->id, (const struct id *)vgid)) {
 			if (!consistent)
 				log_error("Volume group %s metadata is "
@@ -3410,7 +3415,7 @@ static struct volume_group *_vg_read_by_
 			continue;	// FIXME Unnecessary?
 		consistent = 0;
 		if ((vg = _vg_read(cmd, vgname, vgid, 1, &consistent,
-				   precommitted)) &&
+				   tentative)) &&
 		    id_equal(&vg->id, (const struct id *)vgid)) {
 			if (!consistent) {
 				log_error("Volume group %s metadata is "
@@ -3428,7 +3433,7 @@ static struct volume_group *_vg_read_by_
 
 /* Only called by activate.c */
 struct logical_volume *lv_from_lvid(struct cmd_context *cmd, const char *lvid_s,
-				    unsigned precommitted)
+				    unsigned tentative)
 {
 	struct lv_list *lvl;
 	struct volume_group *vg;
@@ -3437,7 +3442,7 @@ struct logical_volume *lv_from_lvid(stru
 	lvid = (const union lvid *) lvid_s;
 
 	log_very_verbose("Finding volume group for uuid %s", lvid_s);
-	if (!(vg = _vg_read_by_vgid(cmd, (const char *)lvid->id[0].uuid, precommitted))) {
+	if (!(vg = _vg_read_by_vgid(cmd, (const char *)lvid->id[0].uuid, tentative))) {
 		log_error("Volume group for uuid not found: %s", lvid_s);
 		return NULL;
 	}
Index: lib/metadata/metadata.h
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/metadata/metadata.h,v
retrieving revision 1.250
diff -u -p -r1.250 metadata.h
--- lib/metadata/metadata.h	30 Aug 2011 14:55:17 -0000	1.250
+++ lib/metadata/metadata.h	31 Aug 2011 18:26:47 -0000
@@ -71,7 +71,7 @@
 //#define MIRROR_LOG		0x00020000U	/* LV */
 //#define MIRROR_IMAGE		0x00040000U	/* LV */
 //#define MIRROR_NOTSYNCED	0x00080000U	/* LV */
-#define PRECOMMITTED		0x00200000U	/* VG - internal use only */
+#define TENTATIVE		0x00200000U	/* VG - internal use only */
 //#define CONVERTING		0x00400000U	/* LV */
 
 //#define MISSING_PV		0x00800000U	/* PV */
@@ -94,7 +94,7 @@
 //#define FMT_UNLIMITED_VOLS	0x00000008U	/* Unlimited PVs/LVs? */
 //#define FMT_RESTRICTED_LVIDS	0x00000010U	/* LVID <= 255 */
 //#define FMT_ORPHAN_ALLOCATABLE	0x00000020U	/* Orphan PV allocatable? */
-#define FMT_PRECOMMIT		0x00000040U	/* Supports pre-commit? */
+#define FMT_TENTATIVE		0x00000040U	/* Supports pre-commit? */
 //#define FMT_RESIZE_PV		0x00000080U	/* Supports pvresize? */
 //#define FMT_UNLIMITED_STRIPESIZE 0x00000100U	/* Unlimited stripe size? */
 
@@ -106,9 +106,9 @@ struct metadata_area_ops {
 	struct volume_group *(*vg_read) (struct format_instance * fi,
 					 const char *vg_name,
 					 struct metadata_area * mda);
-	struct volume_group *(*vg_read_precommit) (struct format_instance * fi,
-					 const char *vg_name,
-					 struct metadata_area * mda);
+	struct volume_group *(*vg_read_tentative) (struct format_instance * fi,
+						   const char *vg_name,
+						   struct metadata_area * mda);
 	/*
 	 * Write out complete VG metadata.  You must ensure internal
 	 * consistency before calling. eg. PEs can't refer to PVs not
@@ -116,18 +116,22 @@ struct metadata_area_ops {
 	 *
 	 * It is also the responsibility of the caller to ensure external
 	 * consistency, eg by calling pv_write() if removing PVs from
-	 * a VG or calling vg_write() a second time if splitting a VG
+	 * a VG or calling vg_write_*() a second time if splitting a VG
 	 * into two.
 	 *
-	 * vg_write() should not read or write from any PVs not included
+	 * vg_write_*() should not read or write from any PVs not included
 	 * in the volume_group structure it is handed.
 	 * (format1 currently breaks this rule.)
+	 *
+	 * In general, vg_write_* should only be called through vg_write() as
+	 * implemented in metadata.c
 	 */
-	int (*vg_write) (struct format_instance * fid, struct volume_group * vg,
-			 struct metadata_area * mda);
-	int (*vg_precommit) (struct format_instance * fid,
-			     struct volume_group * vg,
-			     struct metadata_area * mda);
+	int (*vg_write_phase1) (struct format_instance * fid,
+				struct volume_group * vg,
+				struct metadata_area * mda);
+	int (*vg_write_phase2) (struct format_instance * fid,
+				struct volume_group * vg,
+				struct metadata_area * mda);
 	int (*vg_commit) (struct format_instance * fid,
 			  struct volume_group * vg, struct metadata_area * mda);
 	int (*vg_revert) (struct format_instance * fid,
@@ -391,7 +395,7 @@ struct volume_group *find_vg_with_lv(con
 /* Find LV with given lvid (used during activation) */
 struct logical_volume *lv_from_lvid(struct cmd_context *cmd,
 				    const char *lvid_s,
-				    unsigned precommitted);
+				    unsigned tentative);
 
 /* FIXME Merge these functions with ones above */
 struct physical_volume *find_pv(struct volume_group *vg, struct device *dev);
Index: lib/metadata/mirror.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/metadata/mirror.c,v
retrieving revision 1.159
diff -u -p -r1.159 mirror.c
--- lib/metadata/mirror.c	30 Aug 2011 14:55:17 -0000	1.159
+++ lib/metadata/mirror.c	31 Aug 2011 18:26:48 -0000
@@ -994,7 +994,7 @@ static int _remove_mirror_images(struct 
 	/* FIXME: second suspend should not be needed
 	 * Explicitly suspend temporary LV.
 	 * This balances critical_section_inc() calls with critical_section_dec()
-	 * in resume (both local and cluster) and also properly propagates precommitted
+	 * in resume (both local and cluster) and also properly propagates tentative
 	 * metadata into dm table on other nodes.
 	 * FIXME: check propagation of suspend with visible flag
 	 */
-- 
id' Ash = Ash; id' Dust = Dust; id' _ = undefined

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]