You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
344 lines
9.3 KiB
344 lines
9.3 KiB
7 years ago
|
autofs-5.0.8 - dont clobber mapent for negative cache
|
||
|
|
||
|
From: Ian Kent <raven@themaw.net>
|
||
|
|
||
|
When negative caching a map entry on mount fail don't save the mapent
|
||
|
and restore it when the negative cache timeout expires.
|
||
|
|
||
|
Deleting the mapent, as is done now, can be expensive especially when
|
||
|
it causes a file read for a large file map.
|
||
|
---
|
||
|
daemon/lookup.c | 6 ++-
|
||
|
include/automount.h | 9 ++++
|
||
|
lib/cache.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++-
|
||
|
modules/lookup_file.c | 6 ++-
|
||
|
modules/lookup_hosts.c | 10 +++--
|
||
|
modules/lookup_ldap.c | 6 ++-
|
||
|
modules/lookup_nisplus.c | 10 +++--
|
||
|
modules/lookup_program.c | 10 +++--
|
||
|
modules/lookup_sss.c | 6 ++-
|
||
|
modules/lookup_yp.c | 6 ++-
|
||
|
10 files changed, 135 insertions(+), 19 deletions(-)
|
||
|
|
||
|
--- autofs-5.0.7.orig/daemon/lookup.c
|
||
|
+++ autofs-5.0.7/daemon/lookup.c
|
||
|
@@ -860,7 +860,11 @@ static void update_negative_cache(struct
|
||
|
int rv = CHE_FAIL;
|
||
|
|
||
|
cache_writelock(map->mc);
|
||
|
- rv = cache_update(map->mc, map, name, NULL, now);
|
||
|
+ me = cache_lookup_distinct(map->mc, name);
|
||
|
+ if (me)
|
||
|
+ rv = cache_push_mapent(me, NULL);
|
||
|
+ else
|
||
|
+ rv = cache_update(map->mc, map, name, NULL, now);
|
||
|
if (rv != CHE_FAIL) {
|
||
|
me = cache_lookup_distinct(map->mc, name);
|
||
|
me->status = now + ap->negative_timeout;
|
||
|
--- autofs-5.0.7.orig/include/automount.h
|
||
|
+++ autofs-5.0.7/include/automount.h
|
||
|
@@ -146,6 +146,12 @@ struct mapent_cache {
|
||
|
struct mapent **hash;
|
||
|
};
|
||
|
|
||
|
+struct stack {
|
||
|
+ char *mapent;
|
||
|
+ time_t age;
|
||
|
+ struct stack *next;
|
||
|
+};
|
||
|
+
|
||
|
struct mapent {
|
||
|
struct mapent *next;
|
||
|
struct list_head ino_index;
|
||
|
@@ -159,6 +165,7 @@ struct mapent {
|
||
|
struct mapent *parent;
|
||
|
char *key;
|
||
|
char *mapent;
|
||
|
+ struct stack *stack;
|
||
|
time_t age;
|
||
|
/* Time of last mount fail */
|
||
|
time_t status;
|
||
|
@@ -175,6 +182,8 @@ void cache_readlock(struct mapent_cache
|
||
|
void cache_writelock(struct mapent_cache *mc);
|
||
|
int cache_try_writelock(struct mapent_cache *mc);
|
||
|
void cache_unlock(struct mapent_cache *mc);
|
||
|
+int cache_push_mapent(struct mapent *me, char *mapent);
|
||
|
+int cache_pop_mapent(struct mapent *me);
|
||
|
struct mapent_cache *cache_init(struct autofs_point *ap, struct map_source *map);
|
||
|
struct mapent_cache *cache_init_null_cache(struct master *master);
|
||
|
int cache_set_ino_index(struct mapent_cache *mc, const char *key, dev_t dev, ino_t ino);
|
||
|
--- autofs-5.0.7.orig/lib/cache.c
|
||
|
+++ autofs-5.0.7/lib/cache.c
|
||
|
@@ -177,6 +177,69 @@ static inline void ino_index_unlock(stru
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
+/* Save the cache entry mapent field onto a stack and set a new mapent */
|
||
|
+int cache_push_mapent(struct mapent *me, char *mapent)
|
||
|
+{
|
||
|
+ struct stack *s;
|
||
|
+ char *new;
|
||
|
+
|
||
|
+ if (!me->mapent)
|
||
|
+ return CHE_FAIL;
|
||
|
+
|
||
|
+ if (!mapent)
|
||
|
+ new = NULL;
|
||
|
+ else {
|
||
|
+ new = strdup(mapent);
|
||
|
+ if (!new)
|
||
|
+ return CHE_FAIL;
|
||
|
+ }
|
||
|
+
|
||
|
+ s = malloc(sizeof(struct stack));
|
||
|
+ if (!s) {
|
||
|
+ if (new)
|
||
|
+ free(new);
|
||
|
+ return CHE_FAIL;
|
||
|
+ }
|
||
|
+ memset(s, 0, sizeof(*s));
|
||
|
+
|
||
|
+ s->mapent = me->mapent;
|
||
|
+ s->age = me->age;
|
||
|
+ me->mapent = mapent;
|
||
|
+
|
||
|
+ if (me->stack)
|
||
|
+ s->next = me->stack;
|
||
|
+ me->stack = s;
|
||
|
+
|
||
|
+ return CHE_OK;
|
||
|
+}
|
||
|
+
|
||
|
+/* Restore cache entry mapent to a previously saved mapent, discard current */
|
||
|
+int cache_pop_mapent(struct mapent *me)
|
||
|
+{
|
||
|
+ struct stack *s = me->stack;
|
||
|
+ char *mapent;
|
||
|
+ time_t age;
|
||
|
+
|
||
|
+ if (!s || !s->mapent)
|
||
|
+ return CHE_FAIL;
|
||
|
+
|
||
|
+ mapent = s->mapent;
|
||
|
+ age = s->age;
|
||
|
+ me->stack = s->next;
|
||
|
+ free(s);
|
||
|
+
|
||
|
+ if (age < me->age) {
|
||
|
+ free(mapent);
|
||
|
+ return CHE_OK;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (me->mapent)
|
||
|
+ free(me->mapent);
|
||
|
+ me->mapent = mapent;
|
||
|
+
|
||
|
+ return CHE_OK;
|
||
|
+}
|
||
|
+
|
||
|
struct mapent_cache *cache_init(struct autofs_point *ap, struct map_source *map)
|
||
|
{
|
||
|
struct mapent_cache *mc;
|
||
|
@@ -578,6 +641,8 @@ int cache_add(struct mapent_cache *mc, s
|
||
|
} else
|
||
|
me->mapent = NULL;
|
||
|
|
||
|
+ me->stack = NULL;
|
||
|
+
|
||
|
me->age = age;
|
||
|
me->status = 0;
|
||
|
me->mc = mc;
|
||
|
@@ -689,7 +754,9 @@ void cache_update_negative(struct mapent
|
||
|
int rv = CHE_OK;
|
||
|
|
||
|
me = cache_lookup_distinct(mc, key);
|
||
|
- if (!me)
|
||
|
+ if (me)
|
||
|
+ rv = cache_push_mapent(me, NULL);
|
||
|
+ else
|
||
|
rv = cache_update(mc, ms, key, NULL, now);
|
||
|
if (rv != CHE_FAIL) {
|
||
|
me = cache_lookup_distinct(mc, key);
|
||
|
@@ -858,6 +925,7 @@ int cache_delete(struct mapent_cache *mc
|
||
|
pred = me;
|
||
|
me = me->next;
|
||
|
if (strcmp(this, me->key) == 0) {
|
||
|
+ struct stack *s = me->stack;
|
||
|
if (me->multi && !list_empty(&me->multi_list)) {
|
||
|
ret = CHE_FAIL;
|
||
|
goto done;
|
||
|
@@ -872,6 +940,13 @@ int cache_delete(struct mapent_cache *mc
|
||
|
free(me->key);
|
||
|
if (me->mapent)
|
||
|
free(me->mapent);
|
||
|
+ while (s) {
|
||
|
+ struct stack *next = s->next;
|
||
|
+ if (s->mapent)
|
||
|
+ free(s->mapent);
|
||
|
+ free(s);
|
||
|
+ s = next;
|
||
|
+ }
|
||
|
free(me);
|
||
|
me = pred;
|
||
|
}
|
||
|
@@ -882,6 +957,7 @@ int cache_delete(struct mapent_cache *mc
|
||
|
goto done;
|
||
|
|
||
|
if (strcmp(this, me->key) == 0) {
|
||
|
+ struct stack *s = me->stack;
|
||
|
if (me->multi && !list_empty(&me->multi_list)) {
|
||
|
ret = CHE_FAIL;
|
||
|
goto done;
|
||
|
@@ -896,6 +972,13 @@ int cache_delete(struct mapent_cache *mc
|
||
|
free(me->key);
|
||
|
if (me->mapent)
|
||
|
free(me->mapent);
|
||
|
+ while (s) {
|
||
|
+ struct stack *next = s->next;
|
||
|
+ if (s->mapent)
|
||
|
+ free(s->mapent);
|
||
|
+ free(s);
|
||
|
+ s = next;
|
||
|
+ }
|
||
|
free(me);
|
||
|
}
|
||
|
done:
|
||
|
--- autofs-5.0.7.orig/modules/lookup_file.c
|
||
|
+++ autofs-5.0.7/modules/lookup_file.c
|
||
|
@@ -988,8 +988,10 @@ int lookup_mount(struct autofs_point *ap
|
||
|
cache_writelock(smc);
|
||
|
sme = cache_lookup_distinct(smc, key);
|
||
|
/* Negative timeout expired for non-existent entry. */
|
||
|
- if (sme && !sme->mapent)
|
||
|
- cache_delete(smc, key);
|
||
|
+ if (sme && !sme->mapent) {
|
||
|
+ if (cache_pop_mapent(sme) == CHE_FAIL)
|
||
|
+ cache_delete(smc, key);
|
||
|
+ }
|
||
|
cache_unlock(smc);
|
||
|
}
|
||
|
}
|
||
|
--- autofs-5.0.7.orig/modules/lookup_hosts.c
|
||
|
+++ autofs-5.0.7/modules/lookup_hosts.c
|
||
|
@@ -155,7 +155,9 @@ static int do_parse_mount(struct autofs_
|
||
|
|
||
|
cache_writelock(mc);
|
||
|
me = cache_lookup_distinct(mc, name);
|
||
|
- if (!me)
|
||
|
+ if (me)
|
||
|
+ rv = cache_push_mapent(me, NULL);
|
||
|
+ else
|
||
|
rv = cache_update(mc, source, name, NULL, now);
|
||
|
if (rv != CHE_FAIL) {
|
||
|
me = cache_lookup_distinct(mc, name);
|
||
|
@@ -315,8 +317,10 @@ int lookup_mount(struct autofs_point *ap
|
||
|
cache_writelock(smc);
|
||
|
sme = cache_lookup_distinct(smc, name);
|
||
|
/* Negative timeout expired for non-existent entry. */
|
||
|
- if (sme && !sme->mapent)
|
||
|
- cache_delete(smc, name);
|
||
|
+ if (sme && !sme->mapent) {
|
||
|
+ if (cache_pop_mapent(sme) == CHE_FAIL)
|
||
|
+ cache_delete(smc, name);
|
||
|
+ }
|
||
|
cache_unlock(smc);
|
||
|
}
|
||
|
}
|
||
|
--- autofs-5.0.7.orig/modules/lookup_ldap.c
|
||
|
+++ autofs-5.0.7/modules/lookup_ldap.c
|
||
|
@@ -2937,8 +2937,10 @@ int lookup_mount(struct autofs_point *ap
|
||
|
cache_writelock(smc);
|
||
|
sme = cache_lookup_distinct(smc, key);
|
||
|
/* Negative timeout expired for non-existent entry. */
|
||
|
- if (sme && !sme->mapent)
|
||
|
- cache_delete(smc, key);
|
||
|
+ if (sme && !sme->mapent) {
|
||
|
+ if (cache_pop_mapent(sme) == CHE_FAIL)
|
||
|
+ cache_delete(smc, key);
|
||
|
+ }
|
||
|
cache_unlock(smc);
|
||
|
}
|
||
|
}
|
||
|
--- autofs-5.0.7.orig/modules/lookup_nisplus.c
|
||
|
+++ autofs-5.0.7/modules/lookup_nisplus.c
|
||
|
@@ -509,8 +509,10 @@ int lookup_mount(struct autofs_point *ap
|
||
|
cache_writelock(smc);
|
||
|
sme = cache_lookup_distinct(smc, key);
|
||
|
/* Negative timeout expired for non-existent entry. */
|
||
|
- if (sme && !sme->mapent)
|
||
|
- cache_delete(smc, key);
|
||
|
+ if (sme && !sme->mapent) {
|
||
|
+ if (cache_pop_mapent(sme) == CHE_FAIL)
|
||
|
+ cache_delete(smc, key);
|
||
|
+ }
|
||
|
cache_unlock(smc);
|
||
|
}
|
||
|
}
|
||
|
@@ -602,7 +604,9 @@ int lookup_mount(struct autofs_point *ap
|
||
|
return NSS_STATUS_TRYAGAIN;
|
||
|
cache_writelock(mc);
|
||
|
me = cache_lookup_distinct(mc, key);
|
||
|
- if (!me)
|
||
|
+ if (me)
|
||
|
+ rv = cache_push_mapent(me, NULL);
|
||
|
+ else
|
||
|
rv = cache_update(mc, source, key, NULL, now);
|
||
|
if (rv != CHE_FAIL) {
|
||
|
me = cache_lookup_distinct(mc, key);
|
||
|
--- autofs-5.0.7.orig/modules/lookup_program.c
|
||
|
+++ autofs-5.0.7/modules/lookup_program.c
|
||
|
@@ -156,8 +156,10 @@ int lookup_mount(struct autofs_point *ap
|
||
|
cache_writelock(smc);
|
||
|
sme = cache_lookup_distinct(smc, name);
|
||
|
/* Negative timeout expired for non-existent entry. */
|
||
|
- if (sme && !sme->mapent)
|
||
|
- cache_delete(smc, name);
|
||
|
+ if (sme && !sme->mapent) {
|
||
|
+ if (cache_pop_mapent(sme) == CHE_FAIL)
|
||
|
+ cache_delete(smc, name);
|
||
|
+ }
|
||
|
cache_unlock(smc);
|
||
|
}
|
||
|
}
|
||
|
@@ -451,7 +453,9 @@ out_free:
|
||
|
|
||
|
cache_writelock(mc);
|
||
|
me = cache_lookup_distinct(mc, name);
|
||
|
- if (!me)
|
||
|
+ if (me)
|
||
|
+ rv = cache_push_mapent(me, NULL);
|
||
|
+ else
|
||
|
rv = cache_update(mc, source, name, NULL, now);
|
||
|
if (rv != CHE_FAIL) {
|
||
|
me = cache_lookup_distinct(mc, name);
|
||
|
--- autofs-5.0.7.orig/modules/lookup_sss.c
|
||
|
+++ autofs-5.0.7/modules/lookup_sss.c
|
||
|
@@ -599,8 +599,10 @@ int lookup_mount(struct autofs_point *ap
|
||
|
cache_writelock(smc);
|
||
|
sme = cache_lookup_distinct(smc, key);
|
||
|
/* Negative timeout expired for non-existent entry. */
|
||
|
- if (sme && !sme->mapent)
|
||
|
- cache_delete(smc, key);
|
||
|
+ if (sme && !sme->mapent) {
|
||
|
+ if (cache_pop_mapent(sme) == CHE_FAIL)
|
||
|
+ cache_delete(smc, key);
|
||
|
+ }
|
||
|
cache_unlock(smc);
|
||
|
}
|
||
|
}
|
||
|
--- autofs-5.0.7.orig/modules/lookup_yp.c
|
||
|
+++ autofs-5.0.7/modules/lookup_yp.c
|
||
|
@@ -613,8 +613,10 @@ int lookup_mount(struct autofs_point *ap
|
||
|
cache_writelock(smc);
|
||
|
sme = cache_lookup_distinct(smc, key);
|
||
|
/* Negative timeout expired for non-existent entry. */
|
||
|
- if (sme && !sme->mapent)
|
||
|
- cache_delete(smc, key);
|
||
|
+ if (sme && !sme->mapent) {
|
||
|
+ if (cache_pop_mapent(sme) == CHE_FAIL)
|
||
|
+ cache_delete(smc, key);
|
||
|
+ }
|
||
|
cache_unlock(smc);
|
||
|
}
|
||
|
}
|