|
1 /* |
|
2 * include/linux/sunrpc/cache.h |
|
3 * |
|
4 * Generic code for various authentication-related caches |
|
5 * used by sunrpc clients and servers. |
|
6 * |
|
7 * Copyright (C) 2002 Neil Brown <neilb@cse.unsw.edu.au> |
|
8 * |
|
9 * Released under terms in GPL version 2. See COPYING. |
|
10 * |
|
11 */ |
|
12 |
|
13 #ifndef _LINUX_SUNRPC_CACHE_H_ |
|
14 #define _LINUX_SUNRPC_CACHE_H_ |
|
15 |
|
16 #include <linux/slab.h> |
|
17 #include <asm/atomic.h> |
|
18 #include <linux/proc_fs.h> |
|
19 |
|
20 /* |
|
21 * Each cache requires: |
|
22 * - A 'struct cache_detail' which contains information specific to the cache |
|
23 * for common code to use. |
|
24 * - An item structure that must contain a "struct cache_head" |
|
25 * - A lookup function defined using DefineCacheLookup |
|
26 * - A 'put' function that can release a cache item. It will only |
|
27 * be called after cache_put has succeed, so there are guarantee |
|
28 * to be no references. |
|
29 * - A function to calculate a hash of an item's key. |
|
30 * |
|
31 * as well as assorted code fragments (e.g. compare keys) and numbers |
|
32 * (e.g. hash size, goal_age, etc). |
|
33 * |
|
34 * Each cache must be registered so that it can be cleaned regularly. |
|
35 * When the cache is unregistered, it is flushed completely. |
|
36 * |
|
37 * Entries have a ref count and a 'hashed' flag which counts the existance |
|
38 * in the hash table. |
|
39 * We only expire entries when refcount is zero. |
|
40 * Existance in the cache is counted the refcount. |
|
41 */ |
|
42 |
|
43 /* Every cache item has a common header that is used |
|
44 * for expiring and refreshing entries. |
|
45 * |
|
46 */ |
|
47 struct cache_head { |
|
48 struct cache_head * next; |
|
49 time_t expiry_time; /* After time time, don't use the data */ |
|
50 time_t last_refresh; /* If CACHE_PENDING, this is when upcall |
|
51 * was sent, else this is when update was received |
|
52 */ |
|
53 struct kref ref; |
|
54 unsigned long flags; |
|
55 }; |
|
56 #define CACHE_VALID 0 /* Entry contains valid data */ |
|
57 #define CACHE_NEGATIVE 1 /* Negative entry - there is no match for the key */ |
|
58 #define CACHE_PENDING 2 /* An upcall has been sent but no reply received yet*/ |
|
59 |
|
60 #define CACHE_NEW_EXPIRY 120 /* keep new things pending confirmation for 120 seconds */ |
|
61 |
|
62 struct cache_detail { |
|
63 struct module * owner; |
|
64 int hash_size; |
|
65 struct cache_head ** hash_table; |
|
66 rwlock_t hash_lock; |
|
67 |
|
68 atomic_t inuse; /* active user-space update or lookup */ |
|
69 |
|
70 char *name; |
|
71 void (*cache_put)(struct kref *); |
|
72 |
|
73 void (*cache_request)(struct cache_detail *cd, |
|
74 struct cache_head *h, |
|
75 char **bpp, int *blen); |
|
76 int (*cache_parse)(struct cache_detail *, |
|
77 char *buf, int len); |
|
78 |
|
79 int (*cache_show)(struct seq_file *m, |
|
80 struct cache_detail *cd, |
|
81 struct cache_head *h); |
|
82 |
|
83 struct cache_head * (*alloc)(void); |
|
84 int (*match)(struct cache_head *orig, struct cache_head *new); |
|
85 void (*init)(struct cache_head *orig, struct cache_head *new); |
|
86 void (*update)(struct cache_head *orig, struct cache_head *new); |
|
87 |
|
88 /* fields below this comment are for internal use |
|
89 * and should not be touched by cache owners |
|
90 */ |
|
91 time_t flush_time; /* flush all cache items with last_refresh |
|
92 * earlier than this */ |
|
93 struct list_head others; |
|
94 time_t nextcheck; |
|
95 int entries; |
|
96 |
|
97 /* fields for communication over channel */ |
|
98 struct list_head queue; |
|
99 struct proc_dir_entry *proc_ent; |
|
100 struct proc_dir_entry *flush_ent, *channel_ent, *content_ent; |
|
101 |
|
102 atomic_t readers; /* how many time is /chennel open */ |
|
103 time_t last_close; /* if no readers, when did last close */ |
|
104 time_t last_warn; /* when we last warned about no readers */ |
|
105 void (*warn_no_listener)(struct cache_detail *cd); |
|
106 }; |
|
107 |
|
108 |
|
109 /* this must be embedded in any request structure that |
|
110 * identifies an object that will want a callback on |
|
111 * a cache fill |
|
112 */ |
|
113 struct cache_req { |
|
114 struct cache_deferred_req *(*defer)(struct cache_req *req); |
|
115 }; |
|
116 /* this must be embedded in a deferred_request that is being |
|
117 * delayed awaiting cache-fill |
|
118 */ |
|
119 struct cache_deferred_req { |
|
120 struct list_head hash; /* on hash chain */ |
|
121 struct list_head recent; /* on fifo */ |
|
122 struct cache_head *item; /* cache item we wait on */ |
|
123 void *owner; /* we might need to discard all defered requests |
|
124 * owned by someone */ |
|
125 void (*revisit)(struct cache_deferred_req *req, |
|
126 int too_many); |
|
127 }; |
|
128 |
|
129 |
|
130 extern struct cache_head * |
|
131 sunrpc_cache_lookup(struct cache_detail *detail, |
|
132 struct cache_head *key, int hash); |
|
133 extern struct cache_head * |
|
134 sunrpc_cache_update(struct cache_detail *detail, |
|
135 struct cache_head *new, struct cache_head *old, int hash); |
|
136 |
|
137 |
|
138 extern void cache_clean_deferred(void *owner); |
|
139 |
|
140 static inline struct cache_head *cache_get(struct cache_head *h) |
|
141 { |
|
142 kref_get(&h->ref); |
|
143 return h; |
|
144 } |
|
145 |
|
146 |
|
147 static inline void cache_put(struct cache_head *h, struct cache_detail *cd) |
|
148 { |
|
149 if (atomic_read(&h->ref.refcount) <= 2 && |
|
150 h->expiry_time < cd->nextcheck) |
|
151 cd->nextcheck = h->expiry_time; |
|
152 kref_put(&h->ref, cd->cache_put); |
|
153 } |
|
154 |
|
155 static inline int cache_valid(struct cache_head *h) |
|
156 { |
|
157 /* If an item has been unhashed pending removal when |
|
158 * the refcount drops to 0, the expiry_time will be |
|
159 * set to 0. We don't want to consider such items |
|
160 * valid in this context even though CACHE_VALID is |
|
161 * set. |
|
162 */ |
|
163 return (h->expiry_time != 0 && test_bit(CACHE_VALID, &h->flags)); |
|
164 } |
|
165 |
|
166 extern int cache_check(struct cache_detail *detail, |
|
167 struct cache_head *h, struct cache_req *rqstp); |
|
168 extern void cache_flush(void); |
|
169 extern void cache_purge(struct cache_detail *detail); |
|
170 #define NEVER (0x7FFFFFFF) |
|
171 extern int cache_register(struct cache_detail *cd); |
|
172 extern void cache_unregister(struct cache_detail *cd); |
|
173 |
|
174 extern void qword_add(char **bpp, int *lp, char *str); |
|
175 extern void qword_addhex(char **bpp, int *lp, char *buf, int blen); |
|
176 extern int qword_get(char **bpp, char *dest, int bufsize); |
|
177 |
|
178 static inline int get_int(char **bpp, int *anint) |
|
179 { |
|
180 char buf[50]; |
|
181 char *ep; |
|
182 int rv; |
|
183 int len = qword_get(bpp, buf, 50); |
|
184 if (len < 0) return -EINVAL; |
|
185 if (len ==0) return -ENOENT; |
|
186 rv = simple_strtol(buf, &ep, 0); |
|
187 if (*ep) return -EINVAL; |
|
188 *anint = rv; |
|
189 return 0; |
|
190 } |
|
191 |
|
192 static inline time_t get_expiry(char **bpp) |
|
193 { |
|
194 int rv; |
|
195 if (get_int(bpp, &rv)) |
|
196 return 0; |
|
197 if (rv < 0) |
|
198 return 0; |
|
199 return rv; |
|
200 } |
|
201 |
|
202 #endif /* _LINUX_SUNRPC_CACHE_H_ */ |