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.
343 lines
9.3 KiB
343 lines
9.3 KiB
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); |
|
} |
|
}
|
|
|