Commit cc6eb5ca authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] Include update mode in declaration of RPC information caches.

The sunrpc/cache.c caches which store nfsd export information
can be updated either "inplace" or by replacing the entry.

replacement is needed when an entry hold a reference to some
other object, so the reference counts work properly.

"inplace" can be used when no such references are held, and should be
used when the object could be refered to by another cache (as otherwise
the other cache would have to be updated whenever this one is).

Previously the type of update (inplace or replace) was specified
as an argument to the *_lookup operation.  This too easily lead to
inconsistancies.

With this patch, the update mode is specified when the cache is
declared.
parent 77c1283c
...@@ -156,7 +156,7 @@ int expkey_parse(struct cache_detail *cd, char *mesg, int mlen) ...@@ -156,7 +156,7 @@ int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
if (len == 0) { if (len == 0) {
struct svc_expkey *ek; struct svc_expkey *ek;
set_bit(CACHE_NEGATIVE, &key.h.flags); set_bit(CACHE_NEGATIVE, &key.h.flags);
ek = svc_expkey_lookup(&key, 2); ek = svc_expkey_lookup(&key, 1);
if (ek) if (ek)
expkey_put(&ek->h, &svc_expkey_cache); expkey_put(&ek->h, &svc_expkey_cache);
} else { } else {
...@@ -176,7 +176,7 @@ int expkey_parse(struct cache_detail *cd, char *mesg, int mlen) ...@@ -176,7 +176,7 @@ int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
key.ek_export = exp; key.ek_export = exp;
dprintk("And found export\n"); dprintk("And found export\n");
ek = svc_expkey_lookup(&key, 2); ek = svc_expkey_lookup(&key, 1);
if (ek) if (ek)
expkey_put(&ek->h, &svc_expkey_cache); expkey_put(&ek->h, &svc_expkey_cache);
exp_put(exp); exp_put(exp);
...@@ -231,7 +231,7 @@ static inline void svc_expkey_update(struct svc_expkey *new, struct svc_expkey * ...@@ -231,7 +231,7 @@ static inline void svc_expkey_update(struct svc_expkey *new, struct svc_expkey *
new->ek_export = item->ek_export; new->ek_export = item->ek_export;
} }
static DefineSimpleCacheLookup(svc_expkey) static DefineSimpleCacheLookup(svc_expkey,0) /* no inplace updates */
#define EXPORT_HASHBITS 8 #define EXPORT_HASHBITS 8
#define EXPORT_HASHMAX (1<< EXPORT_HASHBITS) #define EXPORT_HASHMAX (1<< EXPORT_HASHBITS)
...@@ -438,7 +438,7 @@ static inline void svc_export_update(struct svc_export *new, struct svc_export * ...@@ -438,7 +438,7 @@ static inline void svc_export_update(struct svc_export *new, struct svc_export *
new->ex_fsid = item->ex_fsid; new->ex_fsid = item->ex_fsid;
} }
static DefineSimpleCacheLookup(svc_export) static DefineSimpleCacheLookup(svc_export,1) /* allow inplace updates */
struct svc_expkey * struct svc_expkey *
......
...@@ -155,8 +155,9 @@ struct cache_deferred_req { ...@@ -155,8 +155,9 @@ struct cache_deferred_req {
* TEST tests if "tmp" matches "item" * TEST tests if "tmp" matches "item"
* INIT copies key information from "item" to "new" * INIT copies key information from "item" to "new"
* UPDATE copies content information from "item" to "tmp" * UPDATE copies content information from "item" to "tmp"
* INPLACE is true if updates can happen inplace rather than allocating a new structure
*/ */
#define DefineCacheLookup(RTN,MEMBER,FNAME,ARGS,SETUP,DETAIL,HASHFN,TEST,INIT,UPDATE) \ #define DefineCacheLookup(RTN,MEMBER,FNAME,ARGS,SETUP,DETAIL,HASHFN,TEST,INIT,UPDATE,INPLACE) \
RTN *FNAME ARGS \ RTN *FNAME ARGS \
{ \ { \
RTN *tmp, *new=NULL; \ RTN *tmp, *new=NULL; \
...@@ -170,12 +171,12 @@ RTN *FNAME ARGS \ ...@@ -170,12 +171,12 @@ RTN *FNAME ARGS \
tmp = container_of(*hp, RTN, MEMBER); \ tmp = container_of(*hp, RTN, MEMBER); \
if (TEST) { /* found a match */ \ if (TEST) { /* found a match */ \
\ \
if (set == 1 && test_bit(CACHE_VALID, &tmp->MEMBER.flags) && !new) \ if (set && !INPLACE && test_bit(CACHE_VALID, &tmp->MEMBER.flags) && !new) \
break; \ break; \
\ \
atomic_inc(&tmp->MEMBER.refcnt); \ atomic_inc(&tmp->MEMBER.refcnt); \
if (set) { \ if (set) { \
if (set == 1 && test_bit(CACHE_VALID, &tmp->MEMBER.flags))\ if (!INPLACE && test_bit(CACHE_VALID, &tmp->MEMBER.flags))\
{ /* need to swap in new */ \ { /* need to swap in new */ \
RTN *t2; \ RTN *t2; \
\ \
...@@ -194,7 +195,7 @@ RTN *FNAME ARGS \ ...@@ -194,7 +195,7 @@ RTN *FNAME ARGS \
else read_unlock(&(DETAIL)->hash_lock); \ else read_unlock(&(DETAIL)->hash_lock); \
if (set) \ if (set) \
cache_fresh(DETAIL, &tmp->MEMBER, item->MEMBER.expiry_time); \ cache_fresh(DETAIL, &tmp->MEMBER, item->MEMBER.expiry_time); \
if (set==1 && new) cache_fresh(DETAIL, &new->MEMBER, 0); \ if (set && !INPLACE && new) cache_fresh(DETAIL, &new->MEMBER, 0); \
if (new) (DETAIL)->cache_put(&new->MEMBER, DETAIL); \ if (new) (DETAIL)->cache_put(&new->MEMBER, DETAIL); \
return tmp; \ return tmp; \
} \ } \
...@@ -229,10 +230,10 @@ RTN *FNAME ARGS \ ...@@ -229,10 +230,10 @@ RTN *FNAME ARGS \
return NULL; \ return NULL; \
} }
#define DefineSimpleCacheLookup(STRUCT) \ #define DefineSimpleCacheLookup(STRUCT,INPLACE) \
DefineCacheLookup(struct STRUCT, h, STRUCT##_lookup, (struct STRUCT *item, int set), /*no setup */, \ DefineCacheLookup(struct STRUCT, h, STRUCT##_lookup, (struct STRUCT *item, int set), /*no setup */, \
& STRUCT##_cache, STRUCT##_hash(item), STRUCT##_match(item, tmp),\ & STRUCT##_cache, STRUCT##_hash(item), STRUCT##_match(item, tmp),\
STRUCT##_init(new, item), STRUCT##_update(tmp, item)) STRUCT##_init(new, item), STRUCT##_update(tmp, item),INPLACE)
#define cache_for_each(pos, detail, index, member) \ #define cache_for_each(pos, detail, index, member) \
for (({read_lock(&(detail)->hash_lock); index = (detail)->hash_size;}) ; \ for (({read_lock(&(detail)->hash_lock); index = (detail)->hash_size;}) ; \
......
...@@ -152,7 +152,8 @@ DefineCacheLookup(struct auth_domain, ...@@ -152,7 +152,8 @@ DefineCacheLookup(struct auth_domain,
auth_domain_match(tmp, item), auth_domain_match(tmp, item),
kfree(new); if(!set) return NULL; kfree(new); if(!set) return NULL;
new=item; atomic_inc(&new->h.refcnt), new=item; atomic_inc(&new->h.refcnt),
/* no update */ /* no update */,
0 /* no inplace updates */
) )
struct auth_domain *auth_domain_find(char *name) struct auth_domain *auth_domain_find(char *name)
......
...@@ -250,7 +250,7 @@ struct cache_detail ip_map_cache = { ...@@ -250,7 +250,7 @@ struct cache_detail ip_map_cache = {
.cache_show = ip_map_show, .cache_show = ip_map_show,
}; };
static DefineSimpleCacheLookup(ip_map) static DefineSimpleCacheLookup(ip_map, 0)
int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom) int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment