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