summaryrefslogtreecommitdiff
path: root/lib/cache
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2020-09-18 14:42:23 -0500
committerDavid Teigland <teigland@redhat.com>2020-09-18 15:10:11 -0500
commit1404e5ee61bdaddeb07a5e9ecfe1aad477cc9bf9 (patch)
treec923e58968ba40073e79724f0dd5a92988959e28 /lib/cache
parent1570e76233398957911c3559b40de6e03c37df9a (diff)
downloadlvm2-1404e5ee61bdaddeb07a5e9ecfe1aad477cc9bf9.tar.gz
metadata: open rw fd before closing ro fd
lvm opens devices readonly to scan them, but needs to open then readwrite to update the metadata. Previously, the ro fd was closed before the rw fd was opened, leaving a small gap where the dev was not held open, and during which the dev could possibly change which storage it referred to. With the bcache_change_fd() interface, lvm opens a rw fd on a device to be written, tells bcache to change to the new rw fd, and closes the ro fd. . open dev ro . read dev with the ro fd (label_scan) . lock vg (ex for writing) . open dev rw . close ro fd . rescan dev to check if the metadata changed between the scan and the lock . if the metadata did change, reread in full . write the metadata
Diffstat (limited to 'lib/cache')
-rw-r--r--lib/cache/lvmcache.c16
-rw-r--r--lib/cache/lvmcache.h1
2 files changed, 17 insertions, 0 deletions
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index cad8247c7..d8df4c796 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -996,6 +996,22 @@ int lvmcache_label_rescan_vg_rw(struct cmd_context *cmd, const char *vgname, con
return _label_rescan_vg(cmd, vgname, vgid, 1);
}
+int lvmcache_label_reopen_vg_rw(struct cmd_context *cmd, const char *vgname, const char *vgid)
+{
+ struct lvmcache_vginfo *vginfo;
+ struct lvmcache_info *info;
+
+ if (!(vginfo = lvmcache_vginfo_from_vgname(vgname, vgid)))
+ return_0;
+
+ dm_list_iterate_items(info, &vginfo->infos) {
+ if (!label_scan_reopen_rw(info->dev))
+ return_0;
+ }
+
+ return 1;
+}
+
/*
* Uses label_scan to populate lvmcache with 'vginfo' struct for each VG
* and associated 'info' structs for those VGs. Only VG summary information
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 6cef4d102..1ee99b534 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -69,6 +69,7 @@ void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans, int reset);
int lvmcache_label_scan(struct cmd_context *cmd);
int lvmcache_label_rescan_vg(struct cmd_context *cmd, const char *vgname, const char *vgid);
int lvmcache_label_rescan_vg_rw(struct cmd_context *cmd, const char *vgname, const char *vgid);
+int lvmcache_label_reopen_vg_rw(struct cmd_context *cmd, const char *vgname, const char *vgid);
/* Add/delete a device */
struct lvmcache_info *lvmcache_add(struct cmd_context *cmd, struct labeller *labeller, const char *pvid,