From 581b17def23e3cfa0ab82ee1eb8bdf39ddf174fd Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Tue, 15 Apr 2008 14:46:19 +0000 Subject: [PATCH] Drop cached VG metadata before and after committing changes to it. --- WHATS_NEW | 1 + daemons/clvmd/clvmd-command.c | 2 ++ lib/cache/lvmcache.c | 10 ++++++++++ lib/cache/lvmcache.h | 1 + lib/locking/cluster_locking.c | 2 +- lib/locking/file_locking.c | 5 +++++ lib/locking/locking.c | 3 ++- lib/locking/locking.h | 4 ++++ lib/metadata/metadata.c | 9 +++++++++ 9 files changed, 35 insertions(+), 2 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index 23481fb8a..18c544fda 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.35 - ================================= + Drop cached VG metadata before and after committing changes to it. Rename P_global to P_#global. Don't attempt remote metadata backups of non-clustered VGs. (2.02.29) Don't store fid in VG metadata cache to avoid clvmd segfault. (2.02.34) diff --git a/daemons/clvmd/clvmd-command.c b/daemons/clvmd/clvmd-command.c index 2d9e21a1e..b47f52732 100644 --- a/daemons/clvmd/clvmd-command.c +++ b/daemons/clvmd/clvmd-command.c @@ -121,6 +121,8 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen, /* P_#global causes a cache refresh */ if (strcmp(lockname, "P_#global") == 0) do_refresh_cache(); + else if (strncmp(lockname, "P_", 2) == 0) + lvmcache_drop_metadata(lockname + 2); break; diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c index 36296e1f1..b543ad66c 100644 --- a/lib/cache/lvmcache.c +++ b/lib/cache/lvmcache.c @@ -130,6 +130,16 @@ static void _update_cache_lock_state(const char *vgname, int locked) _update_cache_vginfo_lock_state(vginfo, locked); } +void lvmcache_drop_metadata(const char *vgname) +{ + struct lvmcache_vginfo *vginfo; + + if (!(vginfo = vginfo_from_vgname(vgname, NULL))) + return; + + _free_cached_vgmetadata(vginfo); +} + void lvmcache_lock_vgname(const char *vgname, int read_only __attribute((unused))) { if (!_lock_hash && !lvmcache_init()) { diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h index 09c0257f4..bceecd751 100644 --- a/lib/cache/lvmcache.h +++ b/lib/cache/lvmcache.h @@ -111,5 +111,6 @@ struct list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname, /* Returns cached volume group metadata. */ struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted); +void lvmcache_drop_metadata(const char *vgname); #endif diff --git a/lib/locking/cluster_locking.c b/lib/locking/cluster_locking.c index bedc38a29..20ba6ad9e 100644 --- a/lib/locking/cluster_locking.c +++ b/lib/locking/cluster_locking.c @@ -389,7 +389,7 @@ int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags) /* If the VG name is empty then lock the unused PVs */ if (!*resource) /* FIXME Deprecated */ dm_snprintf(lockname, sizeof(lockname), "P_orphans"); - else if (*resource == '#') + else if (*resource == '#' || (flags & LCK_CACHE)) dm_snprintf(lockname, sizeof(lockname), "P_%s", resource); else dm_snprintf(lockname, sizeof(lockname), "V_%s", diff --git a/lib/locking/file_locking.c b/lib/locking/file_locking.c index e830d1514..b162a58c3 100644 --- a/lib/locking/file_locking.c +++ b/lib/locking/file_locking.c @@ -21,6 +21,7 @@ #include "defaults.h" #include "lvm-file.h" #include "lvm-string.h" +#include "lvmcache.h" #include #include @@ -209,6 +210,10 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource, switch (flags & LCK_SCOPE_MASK) { case LCK_VG: + if (flags & LCK_CACHE) { + lvmcache_drop_metadata(resource); + break; + } if (!*resource) /* FIXME Deprecated */ dm_snprintf(lockfile, sizeof(lockfile), "%s/P_orphans", _lock_dir); diff --git a/lib/locking/locking.c b/lib/locking/locking.c index d97c564b0..abfadbf16 100644 --- a/lib/locking/locking.c +++ b/lib/locking/locking.c @@ -324,7 +324,8 @@ static int _lock_vol(struct cmd_context *cmd, const char *resource, uint32_t fla assert(resource); if ((ret = _locking.lock_resource(cmd, resource, flags))) { - if ((flags & LCK_SCOPE_MASK) == LCK_VG) { + if ((flags & LCK_SCOPE_MASK) == LCK_VG && + !(flags & LCK_CACHE)) { if ((flags & LCK_TYPE_MASK) == LCK_UNLOCK) lvmcache_unlock_vgname(resource); else diff --git a/lib/locking/locking.h b/lib/locking/locking.h index a5872bcbb..4c33d943a 100644 --- a/lib/locking/locking.h +++ b/lib/locking/locking.h @@ -69,6 +69,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname); #define LCK_HOLD 0x00000020U /* Hold lock when lock_vol returns? */ #define LCK_LOCAL 0x00000040U /* Don't propagate to other nodes */ #define LCK_CLUSTER_VG 0x00000080U /* VG is clustered */ +#define LCK_CACHE 0x00000100U /* Operation on cache using P_ lock */ /* * Additional lock bits for cluster communication @@ -91,6 +92,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname); #define LCK_VG_READ (LCK_VG | LCK_READ | LCK_HOLD) #define LCK_VG_WRITE (LCK_VG | LCK_WRITE | LCK_HOLD) #define LCK_VG_UNLOCK (LCK_VG | LCK_UNLOCK) +#define LCK_VG_DROP_CACHE (LCK_VG | LCK_WRITE | LCK_CACHE) #define LCK_LV_EXCLUSIVE (LCK_LV | LCK_EXCL | LCK_NONBLOCK) #define LCK_LV_SUSPEND (LCK_LV | LCK_WRITE | LCK_NONBLOCK) @@ -116,6 +118,8 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname); lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD | LCK_LOCAL) #define deactivate_lv_local(cmd, lv) \ lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE | LCK_LOCAL) +#define drop_cached_metadata(vg) \ + lock_vol((vg)->cmd, (vg)->name, LCK_VG_DROP_CACHE) /* Process list of LVs */ int suspend_lvs(struct cmd_context *cmd, struct list *lvs); diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c index c0a02a071..91050949d 100644 --- a/lib/metadata/metadata.c +++ b/lib/metadata/metadata.c @@ -1333,6 +1333,11 @@ int vg_commit(struct volume_group *vg) return cache_updated; } + if (!drop_cached_metadata(vg)) { + log_error("Unable to drop cached metadata for VG %s.", vg->name); + return 0; + } + /* Commit to each copy of the metadata area */ list_iterate_items(mda, &vg->fid->metadata_areas) { failed = 0; @@ -1348,6 +1353,10 @@ int vg_commit(struct volume_group *vg) } } + if (!drop_cached_metadata(vg)) + log_error("Attempt to drop cached metadata failed " + "after commit for VG %s.", vg->name); + /* If at least one mda commit succeeded, it was committed */ return cache_updated; }