Index: LVM2.2.02.84/lib/device/dev-io.c
===================================================================
--- LVM2.2.02.84.orig/lib/device/dev-io.c
+++ LVM2.2.02.84/lib/device/dev-io.c
@@ -391,9 +391,8 @@ int dev_open_flags(struct device *dev, i
 		}
 
 		if (dev->open_count && !need_excl) {
-			/* FIXME Ensure we never get here */
-			log_error(INTERNAL_ERROR "%s already opened read-only",
-				 dev_name(dev));
+			log_debug("%s already opened read-only. Upgrading "
+				  "to read-write.", dev_name(dev));
 			dev->open_count++;
 		}
 
@@ -500,20 +499,27 @@ int dev_open_flags(struct device *dev, i
 
 int dev_open_quiet(struct device *dev)
 {
-	int flags;
-
-	flags = vg_write_lock_held() ? O_RDWR : O_RDONLY;
-
-	return dev_open_flags(dev, flags, 1, 1);
+	return dev_open_flags(dev, O_RDWR, 1, 1);
 }
 
 int dev_open(struct device *dev)
 {
-	int flags;
+	return dev_open_flags(dev, O_RDWR, 1, 0);
+}
 
-	flags = vg_write_lock_held() ? O_RDWR : O_RDONLY;
+int dev_open_readonly(struct device *dev)
+{
+	return dev_open_flags(dev, O_RDONLY, 1, 0);
+}
 
-	return dev_open_flags(dev, flags, 1, 0);
+int dev_open_readonly_buffered(struct device *dev)
+{
+	return dev_open_flags(dev, O_RDONLY, 0, 0);
+}
+
+int dev_open_readonly_quiet(struct device *dev)
+{
+	return dev_open_flags(dev, O_RDONLY, 1, 1);
 }
 
 int dev_test_excl(struct device *dev)
Index: LVM2.2.02.84/lib/device/dev-luks.c
===================================================================
--- LVM2.2.02.84.orig/lib/device/dev-luks.c
+++ LVM2.2.02.84/lib/device/dev-luks.c
@@ -23,7 +23,7 @@ int dev_is_luks(struct device *dev, uint
 	char buf[LUKS_SIGNATURE_SIZE];
 	int ret = -1;
 
-	if (!dev_open(dev)) {
+	if (!dev_open_readonly(dev)) {
 		stack;
 		return -1;
 	}
Index: LVM2.2.02.84/lib/device/dev-md.c
===================================================================
--- LVM2.2.02.84.orig/lib/device/dev-md.c
+++ LVM2.2.02.84/lib/device/dev-md.c
@@ -94,7 +94,7 @@ int dev_is_md(struct device *dev, uint64
 	if (size < MD_RESERVED_SECTORS * 2)
 		return 0;
 
-	if (!dev_open(dev)) {
+	if (!dev_open_readonly(dev)) {
 		stack;
 		return -1;
 	}
Index: LVM2.2.02.84/lib/device/dev-swap.c
===================================================================
--- LVM2.2.02.84.orig/lib/device/dev-swap.c
+++ LVM2.2.02.84/lib/device/dev-swap.c
@@ -49,7 +49,7 @@ int dev_is_swap(struct device *dev, uint
 		return -1;
 	}
 
-	if (!dev_open(dev)) {
+	if (!dev_open_readonly(dev)) {
 		stack;
 		return -1;
 	}
Index: LVM2.2.02.84/lib/format1/disk-rep.c
===================================================================
--- LVM2.2.02.84.orig/lib/format1/disk-rep.c
+++ LVM2.2.02.84/lib/format1/disk-rep.c
@@ -415,7 +415,7 @@ struct disk_list *read_disk(const struct
 {
 	struct disk_list *dl;
 
-	if (!dev_open(dev))
+	if (!dev_open_readonly(dev))
 		return_NULL;
 
 	dl = __read_disk(fmt, dev, mem, vg_name);
Index: LVM2.2.02.84/lib/format_pool/disk_rep.c
===================================================================
--- LVM2.2.02.84.orig/lib/format_pool/disk_rep.c
+++ LVM2.2.02.84/lib/format_pool/disk_rep.c
@@ -355,7 +355,7 @@ struct pool_list *read_pool_disk(const s
 {
 	struct pool_list *pl;
 
-	if (!dev_open(dev))
+	if (!dev_open_readonly(dev))
 		return_NULL;
 
 	if (!(pl = dm_pool_zalloc(mem, sizeof(*pl)))) {
Index: LVM2.2.02.84/lib/format_text/format-text.c
===================================================================
--- LVM2.2.02.84.orig/lib/format_text/format-text.c
+++ LVM2.2.02.84/lib/format_text/format-text.c
@@ -188,7 +188,7 @@ static int _pv_analyze_mda_raw (const st
 		  PRIu64, mdac->area.start, mdac->area.size);
 	area = &mdac->area;
 
-	if (!dev_open(area->dev))
+	if (!dev_open_readonly(area->dev))
 		return_0;
 
 	if (!(mdah = raw_read_mda_header(fmt, area)))
@@ -466,7 +466,7 @@ static int _raw_holds_vgname(struct form
 	int noprecommit = 0;
 	struct mda_header *mdah;
 
-	if (!dev_open(dev_area->dev))
+	if (!dev_open_readonly(dev_area->dev))
 		return_0;
 
 	if (!(mdah = raw_read_mda_header(fid->fmt, dev_area)))
@@ -537,7 +537,7 @@ static struct volume_group *_vg_read_raw
 	struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
 	struct volume_group *vg;
 
-	if (!dev_open(mdac->area.dev))
+	if (!dev_open_readonly(mdac->area.dev))
 		return_NULL;
 
 	vg = _vg_read_raw_area(fid, vgname, &mdac->area, 0);
@@ -555,7 +555,7 @@ static struct volume_group *_vg_read_pre
 	struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
 	struct volume_group *vg;
 
-	if (!dev_open(mdac->area.dev))
+	if (!dev_open_readonly(mdac->area.dev))
 		return_NULL;
 
 	vg = _vg_read_raw_area(fid, vgname, &mdac->area, 1);
@@ -1225,7 +1225,7 @@ static int _scan_raw(const struct format
 
 	dm_list_iterate_items(rl, raw_list) {
 		/* FIXME We're reading mdah twice here... */
-		if (!dev_open(rl->dev_area.dev)) {
+		if (!dev_open_readonly(rl->dev_area.dev)) {
 			stack;
 			continue;
 		}
Index: LVM2.2.02.84/lib/format_text/text_label.c
===================================================================
--- LVM2.2.02.84.orig/lib/format_text/text_label.c
+++ LVM2.2.02.84/lib/format_text/text_label.c
@@ -302,7 +302,7 @@ static int _text_read(struct labeller *l
 
 	dm_list_iterate_items(mda, &info->mdas) {
 		mdac = (struct mda_context *) mda->metadata_locn;
-		if (!dev_open(mdac->area.dev)) {
+		if (!dev_open_readonly(mdac->area.dev)) {
 			mda_set_ignored(mda, 1);
 			stack;
 			continue;
Index: LVM2.2.02.84/lib/label/label.c
===================================================================
--- LVM2.2.02.84.orig/lib/label/label.c
+++ LVM2.2.02.84/lib/label/label.c
@@ -272,7 +272,7 @@ int label_read(struct device *dev, struc
 		return 1;
 	}
 
-	if (!dev_open(dev)) {
+	if (!dev_open_readonly(dev)) {
 		stack;
 
 		if ((info = info_from_pvid(dev->pvid, 0)))
@@ -352,7 +352,7 @@ int label_verify(struct device *dev)
 	struct lvmcache_info *info;
 	int r = 0;
 
-	if (!dev_open(dev)) {
+	if (!dev_open_readonly(dev)) {
 		if ((info = info_from_pvid(dev->pvid, 0)))
 			lvmcache_update_vgname_and_id(info, info->fmt->orphan_vg_name,
 						      info->fmt->orphan_vg_name,
Index: LVM2.2.02.84/tools/lvmdiskscan.c
===================================================================
--- LVM2.2.02.84.orig/tools/lvmdiskscan.c
+++ LVM2.2.02.84/tools/lvmdiskscan.c
@@ -72,7 +72,7 @@ static int _check_device(struct cmd_cont
 	char buffer;
 	uint64_t size;
 
-	if (!dev_open(dev)) {
+	if (!dev_open_readonly(dev)) {
 		return 0;
 	}
 	if (!dev_read(dev, UINT64_C(0), (size_t) 1, &buffer)) {
Index: LVM2.2.02.84/lib/config/config.c
===================================================================
--- LVM2.2.02.84.orig/lib/config/config.c
+++ LVM2.2.02.84/lib/config/config.c
@@ -295,7 +295,7 @@ int read_config_file(struct config_tree
 		if (!(c->dev = dev_create_file(c->filename, NULL, NULL, 1)))
 			return_0;
 
-		if (!dev_open_flags(c->dev, O_RDONLY, 0, 0)) {
+		if (!dev_open_readonly_buffered(c->dev)) {
 			c->dev = 0;
 			return_0;
 		}
Index: LVM2.2.02.84/lib/device/device.h
===================================================================
--- LVM2.2.02.84.orig/lib/device/device.h
+++ LVM2.2.02.84/lib/device/device.h
@@ -73,6 +73,9 @@ int dev_get_read_ahead(struct device *de
 int dev_open(struct device *dev);
 int dev_open_quiet(struct device *dev);
 int dev_open_flags(struct device *dev, int flags, int direct, int quiet);
+int dev_open_readonly(struct device *dev);
+int dev_open_readonly_buffered(struct device *dev);
+int dev_open_readonly_quiet(struct device *dev);
 int dev_close(struct device *dev);
 int dev_close_immediate(struct device *dev);
 void dev_close_all(void);
Index: LVM2.2.02.84/lib/filters/filter.c
===================================================================
--- LVM2.2.02.84.orig/lib/filters/filter.c
+++ LVM2.2.02.84/lib/filters/filter.c
@@ -154,7 +154,7 @@ static int _passes_lvm_type_device_filte
 	}
 
 	/* Check it's accessible */
-	if (!dev_open_flags(dev, O_RDONLY|O_NONBLOCK, 1, 1)) {
+	if (!dev_open_readonly_quiet(dev)) {
 		log_debug("%s: Skipping: open failed", name);
 		return 0;
 	}
