]> sourceware.org Git - lvm2.git/commitdiff
Cache and share generated VG structs
authorZdenek Kabelac <zkabelac@redhat.com>
Thu, 11 Aug 2011 17:24:23 +0000 (17:24 +0000)
committerZdenek Kabelac <zkabelac@redhat.com>
Thu, 11 Aug 2011 17:24:23 +0000 (17:24 +0000)
Extend vginfo cache with cached VG structure. So if the same metadata
are use, skip mda decoding in the case, the same data are in use.
This helps for operations like activation of all LVs in one VG,
where same data were decoded giving the same output result.

Patch adds 1-to-1 connection between volume_group and lvmcache_vginfo.

WHATS_NEW
lib/cache/lvmcache.c
lib/cache/lvmcache.h
lib/metadata/metadata.c
lib/metadata/vg.c
lib/metadata/vg.h

index 3a3bab639be76fb2e2cfe63ef8fb971da1ec98d5..614d81714897c99ad72da5e573393c2f38ee65bf 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
 Version 2.02.87 - 
 ===============================
+  Cache and share generated VG structs.
   Fix possible format instance memory leaks and premature releases in _vg_read.
   Suppress locking error messages in monitoring init scripts.
   If pipe in clvmd fails, return busy instead of using uninitialised descriptors.
index 43ed1f46973008eebe65f5051e629a75813185cd..59f060dba54bafe36b140d005440e407d37dc6a5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
  *
  * This file is part of LVM2.
  *
@@ -90,6 +90,8 @@ static void _free_cached_vgmetadata(struct lvmcache_vginfo *vginfo)
        }
 
        log_debug("Metadata cache: VG %s wiped.", vginfo->vgname);
+
+       release_vg(vginfo->cached_vg);
 }
 
 /*
@@ -662,6 +664,10 @@ struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted)
            (!precommitted && vginfo->precommitted && !critical_section()))
                return NULL;
 
+       /* Use already-cached VG struct when available */
+       if ((vg = vginfo->cached_vg))
+               goto out;
+
        fic.type = FMT_INSTANCE_VG | FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
        fic.context.vg_ref.vg_name = vginfo->vgname;
        fic.context.vg_ref.vg_id = vgid;
@@ -677,17 +683,44 @@ struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted)
        if (!(vg = import_vg_from_config_tree(vginfo->cft, fid)))
                goto_bad;
 
-       log_debug("Using cached %smetadata for VG %s.",
-                 vginfo->precommitted ? "pre-committed" : "", vginfo->vgname);
+       /* Cache VG struct for reuse */
+       vginfo->cached_vg = vg;
+       vginfo->holders = 1;
+       vginfo->vg_use_count = 0;
+       vg->vginfo = vginfo;
+
+out:
+       vginfo->holders++;
+       vginfo->vg_use_count++;
+       log_debug("Using cached %smetadata for VG %s with %u holder(s).",
+                 vginfo->precommitted ? "pre-committed " : "",
+                 vginfo->vgname, vginfo->holders);
 
        return vg;
 
 bad:
-       release_vg(vg);
        _free_cached_vgmetadata(vginfo);
        return NULL;
 }
 
+int vginfo_holders_dec_and_test_for_zero(struct lvmcache_vginfo *vginfo)
+{
+       log_debug("VG %s decrementing %d holder(s) at %p.",
+                 vginfo->cached_vg->name, vginfo->holders, vginfo->cached_vg);
+
+       if (--vginfo->holders)
+               return 0;
+
+       if (vginfo->vg_use_count > 1)
+               log_debug("VG %s reused %d times.",
+                         vginfo->cached_vg->name, vginfo->vg_use_count);
+
+       vginfo->cached_vg->vginfo = NULL;
+       vginfo->cached_vg = NULL;
+
+       return 1;
+}
+
 struct dm_list *lvmcache_get_vgids(struct cmd_context *cmd,
                                   int include_internal)
 {
index 9aafff5a60aff3cf99045b089ab757da06f92aad..2cf02362ae0839487f717b917a53319ce82f0ff3 100644 (file)
@@ -50,6 +50,9 @@ struct lvmcache_vginfo {
        char *vgmetadata;       /* Copy of VG metadata as format_text string */
        struct config_tree *cft; /* Config tree created from vgmetadata */
                                /* Lifetime is directly tied to vgmetadata */
+       struct volume_group *cached_vg;
+       unsigned holders;
+       unsigned vg_use_count;  /* Counter of vg reusage */
        unsigned precommitted;  /* Is vgmetadata live or precommitted? */
 };
 
@@ -93,6 +96,8 @@ int lvmcache_verify_lock_order(const char *vgname);
 
 /* Queries */
 const struct format_type *fmt_from_vgname(const char *vgname, const char *vgid, unsigned revalidate_labels);
+/* Decrement and test if there are still vg holders in vginfo. */
+int vginfo_holders_dec_and_test_for_zero(struct lvmcache_vginfo *vginfo);
 struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname,
                                           const char *vgid);
 struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid);
index 0383e54649fa06598d59d905e8578874616828a0..69955f6be8b72fc1e84a0046a42987b3e7b658a3 100644 (file)
@@ -866,6 +866,12 @@ static struct volume_group *_vg_make_handle(struct cmd_context *cmd,
                                            struct volume_group *vg,
                                            uint32_t failure)
 {
+       /* Never return a cached VG structure for a failure */
+       if (vg && vg->vginfo && failure != SUCCESS) {
+               release_vg(vg);
+               vg = NULL;
+       }
+
        if (!vg && !(vg = alloc_vg("vg_make_handle", cmd, NULL)))
                return_NULL;
 
index ef88a4d3a4c1c14234b002f8aeb9a6ebee5ece1e..7aaea3e30991f8a189eb119442d4540d3066bbc4 100644 (file)
@@ -18,6 +18,7 @@
 #include "display.h"
 #include "activate.h"
 #include "toolcontext.h"
+#include "lvmcache.h"
 
 struct volume_group *alloc_vg(const char *pool_name, struct cmd_context *cmd,
                              const char *vg_name)
@@ -49,6 +50,8 @@ struct volume_group *alloc_vg(const char *pool_name, struct cmd_context *cmd,
        dm_list_init(&vg->tags);
        dm_list_init(&vg->removed_pvs);
 
+       log_debug("Allocated VG %s at %p.", vg->name, vg);
+
        return vg;
 }
 
@@ -62,6 +65,8 @@ static void _free_vg(struct volume_group *vg)
                return;
        }
 
+       log_debug("Freeing VG %s at %p.", vg->name, vg);
+
        dm_pool_destroy(vg->vgmem);
 }
 
@@ -70,6 +75,11 @@ void release_vg(struct volume_group *vg)
        if (!vg)
                return;
 
+       /* Check if there are any vginfo holders */
+       if (vg->vginfo &&
+           !vginfo_holders_dec_and_test_for_zero(vg->vginfo))
+               return;
+
        _free_vg(vg);
 }
 
index 524888803b110588425260bf64dff0235409b5e9..9c21f37edffff2aa9f2a3f313b0c2f9a1dc776fd 100644 (file)
@@ -41,6 +41,7 @@ struct volume_group {
        struct cmd_context *cmd;
        struct dm_pool *vgmem;
        struct format_instance *fid;
+       struct lvmcache_vginfo *vginfo;
        struct dm_list *cmd_vgs;/* List of wanted/locked and opened VGs */
        uint32_t cmd_missing_vgs;/* Flag marks missing VG */
        uint32_t seqno;         /* Metadata sequence number */
This page took 0.050806 seconds and 5 git commands to generate.