diff options
Diffstat (limited to 'libmount/src/cache.c')
| -rw-r--r-- | libmount/src/cache.c | 89 |
1 files changed, 60 insertions, 29 deletions
diff --git a/libmount/src/cache.c b/libmount/src/cache.c index 7b651228a..92f469456 100644 --- a/libmount/src/cache.c +++ b/libmount/src/cache.c @@ -10,7 +10,7 @@ * @title: Cache * @short_description: paths and tags (UUID/LABEL) caching * - * The cache is a very simple API for work with tags (LABEL, UUID, ...) and + * The cache is a very simple API for working with tags (LABEL, UUID, ...) and * paths. The cache uses libblkid as a backend for TAGs resolution. * * All returned paths are always canonicalized. @@ -48,6 +48,7 @@ struct libmnt_cache { struct mnt_cache_entry *ents; size_t nents; size_t nallocs; + int refcount; /* blkid_evaluate_tag() works in two ways: * @@ -72,6 +73,7 @@ struct libmnt_cache *mnt_new_cache(void) if (!cache) return NULL; DBG(CACHE, mnt_debug_h(cache, "alloc")); + cache->refcount = 1; return cache; } @@ -79,7 +81,8 @@ struct libmnt_cache *mnt_new_cache(void) * mnt_free_cache: * @cache: pointer to struct libmnt_cache instance * - * Deallocates the cache. + * Deallocates the cache. This function does not care about reference count. Don't + * use this function directly -- it's better to use use mnt_unref_cache(). */ void mnt_free_cache(struct libmnt_cache *cache) { @@ -89,6 +92,7 @@ void mnt_free_cache(struct libmnt_cache *cache) return; DBG(CACHE, mnt_debug_h(cache, "free")); + WARN_REFCOUNT(CACHE, cache, cache->refcount); for (i = 0; i < cache->nents; i++) { struct mnt_cache_entry *e = &cache->ents[i]; @@ -102,7 +106,39 @@ void mnt_free_cache(struct libmnt_cache *cache) free(cache); } -/* note that the @key could be tha same pointer as @value */ +/** + * mnt_ref_cache: + * @cache: cache pointer + * + * Increments reference counter. + */ +void mnt_ref_cache(struct libmnt_cache *cache) +{ + if (cache) { + cache->refcount++; + /*DBG(CACHE, mnt_debug_h(cache, "ref=%d", cache->refcount));*/ + } +} + +/** + * mnt_unref_cache: + * @cache: cache pointer + * + * De-increments reference counter, on zero the cache is automatically + * deallocated by mnt_free_cache(). + */ +void mnt_unref_cache(struct libmnt_cache *cache) +{ + if (cache) { + cache->refcount--; + /*DBG(CACHE, mnt_debug_h(cache, "unref=%d", cache->refcount));*/ + if (cache->refcount <= 0) + mnt_free_cache(cache); + } +} + + +/* note that the @key could be the same pointer as @value */ static int cache_add_entry(struct libmnt_cache *cache, char *key, char *value, int flag) { @@ -135,7 +171,7 @@ static int cache_add_entry(struct libmnt_cache *cache, char *key, return 0; } -/* add tag to the cache, @devname has to be allocated string */ +/* add tag to the cache, @devname has to be an allocated string */ static int cache_add_tag(struct libmnt_cache *cache, const char *tagname, const char *tagval, char *devname, int flag) { @@ -270,13 +306,13 @@ int mnt_cache_read_tags(struct libmnt_cache *cache, const char *devname) DBG(CACHE, mnt_debug_h(cache, "tags for %s requested", devname)); - /* check is device is already cached */ + /* check if device is already cached */ for (i = 0; i < cache->nents; i++) { struct mnt_cache_entry *e = &cache->ents[i]; if (!(e->flag & MNT_CACHE_TAGREAD)) continue; if (strcmp(e->value, devname) == 0) - /* tags has been already read */ + /* tags have already been read */ return 0; } @@ -335,7 +371,7 @@ error: * @token: tag name (e.g "LABEL") * @value: tag value * - * Look up @cache to check it @tag+@value are associated with @devname. + * Look up @cache to check if @tag+@value are associated with @devname. * * Returns: 1 on success or 0. */ @@ -421,7 +457,7 @@ char *mnt_get_fstype(const char *devname, int *ambi, struct libmnt_cache *cache) rc = blkid_do_safeprobe(pr); - DBG(CACHE, mnt_debug_h(cache, "liblkid rc=%d", rc)); + DBG(CACHE, mnt_debug_h(cache, "libblkid rc=%d", rc)); if (!rc && !blkid_probe_lookup_value(pr, "TYPE", &data, NULL)) type = strdup(data); @@ -493,7 +529,7 @@ error: * - /dev/loopN to the loop backing filename * - empty path (NULL) to 'none' * - * Returns: new allocated string with path, result has to be always deallocated + * Returns: newly allocated string with path, result always has to be deallocated * by free(). */ char *mnt_pretty_path(const char *path, struct libmnt_cache *cache) @@ -583,22 +619,18 @@ error: char *mnt_resolve_spec(const char *spec, struct libmnt_cache *cache) { char *cn = NULL; + char *t = NULL, *v = NULL; if (!spec) return NULL; - if (strchr(spec, '=')) { - char *tag, *val; - - if (!blkid_parse_tag_string(spec, &tag, &val)) { - cn = mnt_resolve_tag(tag, val, cache); - - free(tag); - free(val); - } - } else + if (blkid_parse_tag_string(spec, &t, &v) == 0 && mnt_valid_tagname(t)) + cn = mnt_resolve_tag(t, v, cache); + else cn = mnt_resolve_path(spec, cache); + free(t); + free(v); return cn; } @@ -624,7 +656,7 @@ int test_resolve_path(struct libmnt_test *ts, int argc, char *argv[]) p = mnt_resolve_path(line, cache); printf("%s : %s\n", line, p); } - mnt_free_cache(cache); + mnt_unref_cache(cache); return 0; } @@ -647,7 +679,7 @@ int test_resolve_spec(struct libmnt_test *ts, int argc, char *argv[]) p = mnt_resolve_spec(line, cache); printf("%s : %s\n", line, p); } - mnt_free_cache(cache); + mnt_unref_cache(cache); return 0; } @@ -663,6 +695,7 @@ int test_read_tags(struct libmnt_test *ts, int argc, char *argv[]) while(fgets(line, sizeof(line), stdin)) { size_t sz = strlen(line); + char *t = NULL, *v = NULL; if (sz > 0 && line[sz - 1] == '\n') line[sz - 1] = '\0'; @@ -674,16 +707,14 @@ int test_read_tags(struct libmnt_test *ts, int argc, char *argv[]) if (mnt_cache_read_tags(cache, line) < 0) fprintf(stderr, "%s: read tags failed\n", line); - } else if (strchr(line, '=')) { - char *tag, *val; + } else if (blkid_parse_tag_string(line, &t, &v) == 0) { const char *cn = NULL; - if (!blkid_parse_tag_string(line, &tag, &val)) { - cn = cache_find_tag(cache, tag, val); + if (mnt_valid_tagname(t)) + cn = cache_find_tag(cache, t, v); + free(t); + free(v); - free(tag); - free(val); - } if (cn) printf("%s: %s\n", line, cn); else @@ -700,7 +731,7 @@ int test_read_tags(struct libmnt_test *ts, int argc, char *argv[]) e->key + strlen(e->key) + 1); } - mnt_free_cache(cache); + mnt_unref_cache(cache); return 0; } |
