diff options
author | NeilBrown <neilb@suse.de> | 2006-03-27 04:15:02 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-27 11:44:41 -0500 |
commit | 15a5f6bd23eddd5b3be80366f364be04fb1c1c99 (patch) | |
tree | e3c4fa8eb9e8b21ebca33370b7a93eab11662a5d /net/sunrpc/cache.c | |
parent | 7d317f2c9f1e9dcf4f632fa98f91d1d4a36c4cae (diff) |
[PATCH] knfsd: Create cache_lookup function instead of using a macro to declare one
The C++-like 'template' approach proves to be too ugly and hard to work with.
The old 'template' won't go away until all users are updated.
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'net/sunrpc/cache.c')
-rw-r--r-- | net/sunrpc/cache.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 0acccfeeb284..4449dc52edf5 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c | |||
@@ -47,6 +47,104 @@ void cache_init(struct cache_head *h) | |||
47 | h->last_refresh = now; | 47 | h->last_refresh = now; |
48 | } | 48 | } |
49 | 49 | ||
50 | struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, | ||
51 | struct cache_head *key, int hash) | ||
52 | { | ||
53 | struct cache_head **head, **hp; | ||
54 | struct cache_head *new = NULL; | ||
55 | |||
56 | head = &detail->hash_table[hash]; | ||
57 | |||
58 | read_lock(&detail->hash_lock); | ||
59 | |||
60 | for (hp=head; *hp != NULL ; hp = &(*hp)->next) { | ||
61 | struct cache_head *tmp = *hp; | ||
62 | if (detail->match(tmp, key)) { | ||
63 | cache_get(tmp); | ||
64 | read_unlock(&detail->hash_lock); | ||
65 | return tmp; | ||
66 | } | ||
67 | } | ||
68 | read_unlock(&detail->hash_lock); | ||
69 | /* Didn't find anything, insert an empty entry */ | ||
70 | |||
71 | new = detail->alloc(); | ||
72 | if (!new) | ||
73 | return NULL; | ||
74 | cache_init(new); | ||
75 | |||
76 | write_lock(&detail->hash_lock); | ||
77 | |||
78 | /* check if entry appeared while we slept */ | ||
79 | for (hp=head; *hp != NULL ; hp = &(*hp)->next) { | ||
80 | struct cache_head *tmp = *hp; | ||
81 | if (detail->match(tmp, key)) { | ||
82 | cache_get(tmp); | ||
83 | write_unlock(&detail->hash_lock); | ||
84 | detail->cache_put(new, detail); | ||
85 | return tmp; | ||
86 | } | ||
87 | } | ||
88 | detail->init(new, key); | ||
89 | new->next = *head; | ||
90 | *head = new; | ||
91 | detail->entries++; | ||
92 | cache_get(new); | ||
93 | write_unlock(&detail->hash_lock); | ||
94 | |||
95 | return new; | ||
96 | } | ||
97 | EXPORT_SYMBOL(sunrpc_cache_lookup); | ||
98 | |||
99 | struct cache_head *sunrpc_cache_update(struct cache_detail *detail, | ||
100 | struct cache_head *new, struct cache_head *old, int hash) | ||
101 | { | ||
102 | /* The 'old' entry is to be replaced by 'new'. | ||
103 | * If 'old' is not VALID, we update it directly, | ||
104 | * otherwise we need to replace it | ||
105 | */ | ||
106 | struct cache_head **head; | ||
107 | struct cache_head *tmp; | ||
108 | |||
109 | if (!test_bit(CACHE_VALID, &old->flags)) { | ||
110 | write_lock(&detail->hash_lock); | ||
111 | if (!test_bit(CACHE_VALID, &old->flags)) { | ||
112 | if (test_bit(CACHE_NEGATIVE, &new->flags)) | ||
113 | set_bit(CACHE_NEGATIVE, &old->flags); | ||
114 | else | ||
115 | detail->update(old, new); | ||
116 | /* FIXME cache_fresh should come first */ | ||
117 | write_unlock(&detail->hash_lock); | ||
118 | cache_fresh(detail, old, new->expiry_time); | ||
119 | return old; | ||
120 | } | ||
121 | write_unlock(&detail->hash_lock); | ||
122 | } | ||
123 | /* We need to insert a new entry */ | ||
124 | tmp = detail->alloc(); | ||
125 | if (!tmp) { | ||
126 | detail->cache_put(old, detail); | ||
127 | return NULL; | ||
128 | } | ||
129 | cache_init(tmp); | ||
130 | detail->init(tmp, old); | ||
131 | head = &detail->hash_table[hash]; | ||
132 | |||
133 | write_lock(&detail->hash_lock); | ||
134 | if (test_bit(CACHE_NEGATIVE, &new->flags)) | ||
135 | set_bit(CACHE_NEGATIVE, &tmp->flags); | ||
136 | else | ||
137 | detail->update(tmp, new); | ||
138 | tmp->next = *head; | ||
139 | *head = tmp; | ||
140 | cache_get(tmp); | ||
141 | write_unlock(&detail->hash_lock); | ||
142 | cache_fresh(detail, tmp, new->expiry_time); | ||
143 | cache_fresh(detail, old, 0); | ||
144 | detail->cache_put(old, detail); | ||
145 | return tmp; | ||
146 | } | ||
147 | EXPORT_SYMBOL(sunrpc_cache_update); | ||
50 | 148 | ||
51 | static int cache_make_upcall(struct cache_detail *detail, struct cache_head *h); | 149 | static int cache_make_upcall(struct cache_detail *detail, struct cache_head *h); |
52 | /* | 150 | /* |