1
2
3
4
5
6
7
8
9
10
11
12
13#ifndef _LINUX_SUNRPC_CACHE_H_
14#define _LINUX_SUNRPC_CACHE_H_
15
16#include <linux/kref.h>
17#include <linux/slab.h>
18#include <linux/atomic.h>
19#include <linux/proc_fs.h>
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48struct cache_head {
49 struct cache_head * next;
50 time_t expiry_time;
51 time_t last_refresh;
52
53
54 struct kref ref;
55 unsigned long flags;
56};
57#define CACHE_VALID 0
58#define CACHE_NEGATIVE 1
59#define CACHE_PENDING 2
60
61#define CACHE_NEW_EXPIRY 120
62
63struct cache_detail_procfs {
64 struct proc_dir_entry *proc_ent;
65 struct proc_dir_entry *flush_ent, *channel_ent, *content_ent;
66};
67
68struct cache_detail_pipefs {
69 struct dentry *dir;
70};
71
72struct cache_detail {
73 struct module * owner;
74 int hash_size;
75 struct cache_head ** hash_table;
76 rwlock_t hash_lock;
77
78 atomic_t inuse;
79
80 char *name;
81 void (*cache_put)(struct kref *);
82
83 int (*cache_upcall)(struct cache_detail *,
84 struct cache_head *);
85
86 void (*cache_request)(struct cache_detail *cd,
87 struct cache_head *ch,
88 char **bpp, int *blen);
89
90 int (*cache_parse)(struct cache_detail *,
91 char *buf, int len);
92
93 int (*cache_show)(struct seq_file *m,
94 struct cache_detail *cd,
95 struct cache_head *h);
96 void (*warn_no_listener)(struct cache_detail *cd,
97 int has_died);
98
99 struct cache_head * (*alloc)(void);
100 int (*match)(struct cache_head *orig, struct cache_head *new);
101 void (*init)(struct cache_head *orig, struct cache_head *new);
102 void (*update)(struct cache_head *orig, struct cache_head *new);
103
104
105
106
107 time_t flush_time;
108
109 struct list_head others;
110 time_t nextcheck;
111 int entries;
112
113
114 struct list_head queue;
115
116 atomic_t readers;
117 time_t last_close;
118 time_t last_warn;
119
120 union {
121 struct cache_detail_procfs procfs;
122 struct cache_detail_pipefs pipefs;
123 } u;
124 struct net *net;
125};
126
127
128
129
130
131
132struct cache_req {
133 struct cache_deferred_req *(*defer)(struct cache_req *req);
134 int thread_wait;
135
136
137};
138
139
140
141struct cache_deferred_req {
142 struct hlist_node hash;
143 struct list_head recent;
144 struct cache_head *item;
145 void *owner;
146
147 void (*revisit)(struct cache_deferred_req *req,
148 int too_many);
149};
150
151
152extern const struct file_operations cache_file_operations_pipefs;
153extern const struct file_operations content_file_operations_pipefs;
154extern const struct file_operations cache_flush_operations_pipefs;
155
156extern struct cache_head *
157sunrpc_cache_lookup(struct cache_detail *detail,
158 struct cache_head *key, int hash);
159extern struct cache_head *
160sunrpc_cache_update(struct cache_detail *detail,
161 struct cache_head *new, struct cache_head *old, int hash);
162
163extern int
164sunrpc_cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h);
165
166
167extern void cache_clean_deferred(void *owner);
168
169static inline struct cache_head *cache_get(struct cache_head *h)
170{
171 kref_get(&h->ref);
172 return h;
173}
174
175
176static inline void cache_put(struct cache_head *h, struct cache_detail *cd)
177{
178 if (atomic_read(&h->ref.refcount) <= 2 &&
179 h->expiry_time < cd->nextcheck)
180 cd->nextcheck = h->expiry_time;
181 kref_put(&h->ref, cd->cache_put);
182}
183
184static inline int cache_valid(struct cache_head *h)
185{
186
187
188
189
190
191
192 return (h->expiry_time != 0 && test_bit(CACHE_VALID, &h->flags));
193}
194
195extern int cache_check(struct cache_detail *detail,
196 struct cache_head *h, struct cache_req *rqstp);
197extern void cache_flush(void);
198extern void cache_purge(struct cache_detail *detail);
199#define NEVER (0x7FFFFFFF)
200extern void __init cache_initialize(void);
201extern int cache_register_net(struct cache_detail *cd, struct net *net);
202extern void cache_unregister_net(struct cache_detail *cd, struct net *net);
203
204extern struct cache_detail *cache_create_net(struct cache_detail *tmpl, struct net *net);
205extern void cache_destroy_net(struct cache_detail *cd, struct net *net);
206
207extern void sunrpc_init_cache_detail(struct cache_detail *cd);
208extern void sunrpc_destroy_cache_detail(struct cache_detail *cd);
209extern int sunrpc_cache_register_pipefs(struct dentry *parent, const char *,
210 umode_t, struct cache_detail *);
211extern void sunrpc_cache_unregister_pipefs(struct cache_detail *);
212
213extern void qword_add(char **bpp, int *lp, char *str);
214extern void qword_addhex(char **bpp, int *lp, char *buf, int blen);
215extern int qword_get(char **bpp, char *dest, int bufsize);
216
217static inline int get_int(char **bpp, int *anint)
218{
219 char buf[50];
220 char *ep;
221 int rv;
222 int len = qword_get(bpp, buf, sizeof(buf));
223
224 if (len < 0)
225 return -EINVAL;
226 if (len == 0)
227 return -ENOENT;
228
229 rv = simple_strtol(buf, &ep, 0);
230 if (*ep)
231 return -EINVAL;
232
233 *anint = rv;
234 return 0;
235}
236
237static inline int get_uint(char **bpp, unsigned int *anint)
238{
239 char buf[50];
240 int len = qword_get(bpp, buf, sizeof(buf));
241
242 if (len < 0)
243 return -EINVAL;
244 if (len == 0)
245 return -ENOENT;
246
247 if (kstrtouint(buf, 0, anint))
248 return -EINVAL;
249
250 return 0;
251}
252
253
254
255
256
257
258static inline time_t seconds_since_boot(void)
259{
260 struct timespec boot;
261 getboottime(&boot);
262 return get_seconds() - boot.tv_sec;
263}
264
265static inline time_t convert_to_wallclock(time_t sinceboot)
266{
267 struct timespec boot;
268 getboottime(&boot);
269 return boot.tv_sec + sinceboot;
270}
271
272static inline time_t get_expiry(char **bpp)
273{
274 int rv;
275 struct timespec boot;
276
277 if (get_int(bpp, &rv))
278 return 0;
279 if (rv < 0)
280 return 0;
281 getboottime(&boot);
282 return rv - boot.tv_sec;
283}
284
285#endif
286