1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * include/linux/sunrpc/cache.h
4 *
5 * Generic code for various authentication-related caches
6 * used by sunrpc clients and servers.
7 *
8 * Copyright (C) 2002 Neil Brown <neilb@cse.unsw.edu.au>
9 */
10
11#ifndef _LINUX_SUNRPC_CACHE_H_
12#define _LINUX_SUNRPC_CACHE_H_
13
14#include <linux/kref.h>
15#include <linux/slab.h>
16#include <linux/atomic.h>
17#include <linux/kstrtox.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 existence
38 * in the hash table.
39 * We only expire entries when refcount is zero.
40 * Existence 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 */
47struct cache_head {
48	struct hlist_node	cache_list;
49	time64_t	expiry_time;	/* After time expiry_time, don't use
50					 * the data */
51	time64_t	last_refresh;   /* If CACHE_PENDING, this is when upcall was
52					 * sent, else this is when update was
53					 * received, though it is alway set to
54					 * be *after* ->flush_time.
55					 */
56	struct kref	ref;
57	unsigned long	flags;
58};
59
60/* cache_head.flags */
61enum {
62	CACHE_VALID,		/* Entry contains valid data */
63	CACHE_NEGATIVE,		/* Negative entry - there is no match for the key */
64	CACHE_PENDING,		/* An upcall has been sent but no reply received yet*/
65	CACHE_CLEANED,		/* Entry has been cleaned from cache */
66};
67
68#define	CACHE_NEW_EXPIRY 120	/* keep new things pending confirmation for 120 seconds */
69
70struct cache_detail {
71	struct module *		owner;
72	int			hash_size;
73	struct hlist_head *	hash_table;
74	spinlock_t		hash_lock;
75
76	char			*name;
77	void			(*cache_put)(struct kref *);
78
79	int			(*cache_upcall)(struct cache_detail *,
80						struct cache_head *);
81
82	void			(*cache_request)(struct cache_detail *cd,
83						 struct cache_head *ch,
84						 char **bpp, int *blen);
85
86	int			(*cache_parse)(struct cache_detail *,
87					       char *buf, int len);
88
89	int			(*cache_show)(struct seq_file *m,
90					      struct cache_detail *cd,
91					      struct cache_head *h);
92	void			(*warn_no_listener)(struct cache_detail *cd,
93					      int has_died);
94
95	struct cache_head *	(*alloc)(void);
96	void			(*flush)(void);
97	int			(*match)(struct cache_head *orig, struct cache_head *new);
98	void			(*init)(struct cache_head *orig, struct cache_head *new);
99	void			(*update)(struct cache_head *orig, struct cache_head *new);
100
101	/* fields below this comment are for internal use
102	 * and should not be touched by cache owners
103	 */
104	time64_t		flush_time;		/* flush all cache items with
105							 * last_refresh at or earlier
106							 * than this.  last_refresh
107							 * is never set at or earlier
108							 * than this.
109							 */
110	struct list_head	others;
111	time64_t		nextcheck;
112	int			entries;
113
114	/* fields for communication over channel */
115	struct list_head	queue;
116
117	atomic_t		writers;		/* how many time is /channel open */
118	time64_t		last_close;		/* if no writers, when did last close */
119	time64_t		last_warn;		/* when we last warned about no writers */
120
121	union {
122		struct proc_dir_entry	*procfs;
123		struct dentry		*pipefs;
124	};
125	struct net		*net;
126};
127
128/* this must be embedded in any request structure that
129 * identifies an object that will want a callback on
130 * a cache fill
131 */
132struct cache_req {
133	struct cache_deferred_req *(*defer)(struct cache_req *req);
134	unsigned long	thread_wait;	/* How long (jiffies) we can block the
135					 * current thread to wait for updates.
136					 */
137};
138
139/* this must be embedded in a deferred_request that is being
140 * delayed awaiting cache-fill
141 */
142struct cache_deferred_req {
143	struct hlist_node	hash;	/* on hash chain */
144	struct list_head	recent; /* on fifo */
145	struct cache_head	*item;  /* cache item we wait on */
146	void			*owner; /* we might need to discard all defered requests
147					 * owned by someone */
148	void			(*revisit)(struct cache_deferred_req *req,
149					   int too_many);
150};
151
152/*
153 * timestamps kept in the cache are expressed in seconds
154 * since boot.  This is the best for measuring differences in
155 * real time.
156 * This reimplemnts ktime_get_boottime_seconds() in a slightly
157 * faster but less accurate way. When we end up converting
158 * back to wallclock (CLOCK_REALTIME), that error often
159 * cancels out during the reverse operation.
160 */
161static inline time64_t seconds_since_boot(void)
162{
163	struct timespec64 boot;
164	getboottime64(&boot);
165	return ktime_get_real_seconds() - boot.tv_sec;
166}
167
168static inline time64_t convert_to_wallclock(time64_t sinceboot)
169{
170	struct timespec64 boot;
171	getboottime64(&boot);
172	return boot.tv_sec + sinceboot;
173}
174
175extern const struct file_operations cache_file_operations_pipefs;
176extern const struct file_operations content_file_operations_pipefs;
177extern const struct file_operations cache_flush_operations_pipefs;
178
179extern struct cache_head *
180sunrpc_cache_lookup_rcu(struct cache_detail *detail,
181			struct cache_head *key, int hash);
182extern struct cache_head *
183sunrpc_cache_update(struct cache_detail *detail,
184		    struct cache_head *new, struct cache_head *old, int hash);
185
186extern int
187sunrpc_cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h);
188extern int
189sunrpc_cache_pipe_upcall_timeout(struct cache_detail *detail,
190				 struct cache_head *h);
191
192
193extern void cache_clean_deferred(void *owner);
194
195static inline struct cache_head  *cache_get(struct cache_head *h)
196{
197	kref_get(&h->ref);
198	return h;
199}
200
201static inline struct cache_head  *cache_get_rcu(struct cache_head *h)
202{
203	if (kref_get_unless_zero(&h->ref))
204		return h;
205	return NULL;
206}
207
208static inline void cache_put(struct cache_head *h, struct cache_detail *cd)
209{
210	if (kref_read(&h->ref) <= 2 &&
211	    h->expiry_time < cd->nextcheck)
212		cd->nextcheck = h->expiry_time;
213	kref_put(&h->ref, cd->cache_put);
214}
215
216static inline bool cache_is_expired(struct cache_detail *detail, struct cache_head *h)
217{
218	if (h->expiry_time < seconds_since_boot())
219		return true;
220	if (!test_bit(CACHE_VALID, &h->flags))
221		return false;
222	return detail->flush_time >= h->last_refresh;
223}
224
225extern int cache_check(struct cache_detail *detail,
226		       struct cache_head *h, struct cache_req *rqstp);
227extern void cache_flush(void);
228extern void cache_purge(struct cache_detail *detail);
229#define NEVER (0x7FFFFFFF)
230extern void __init cache_initialize(void);
231extern int cache_register_net(struct cache_detail *cd, struct net *net);
232extern void cache_unregister_net(struct cache_detail *cd, struct net *net);
233
234extern struct cache_detail *cache_create_net(const struct cache_detail *tmpl, struct net *net);
235extern void cache_destroy_net(struct cache_detail *cd, struct net *net);
236
237extern void sunrpc_init_cache_detail(struct cache_detail *cd);
238extern void sunrpc_destroy_cache_detail(struct cache_detail *cd);
239extern int sunrpc_cache_register_pipefs(struct dentry *parent, const char *,
240					umode_t, struct cache_detail *);
241extern void sunrpc_cache_unregister_pipefs(struct cache_detail *);
242extern void sunrpc_cache_unhash(struct cache_detail *, struct cache_head *);
243
244/* Must store cache_detail in seq_file->private if using next three functions */
245extern void *cache_seq_start_rcu(struct seq_file *file, loff_t *pos);
246extern void *cache_seq_next_rcu(struct seq_file *file, void *p, loff_t *pos);
247extern void cache_seq_stop_rcu(struct seq_file *file, void *p);
248
249extern void qword_add(char **bpp, int *lp, char *str);
250extern void qword_addhex(char **bpp, int *lp, char *buf, int blen);
251extern int qword_get(char **bpp, char *dest, int bufsize);
252
253static inline int get_int(char **bpp, int *anint)
254{
255	char buf[50];
256	char *ep;
257	int rv;
258	int len = qword_get(bpp, buf, sizeof(buf));
259
260	if (len < 0)
261		return -EINVAL;
262	if (len == 0)
263		return -ENOENT;
264
265	rv = simple_strtol(buf, &ep, 0);
266	if (*ep)
267		return -EINVAL;
268
269	*anint = rv;
270	return 0;
271}
272
273static inline int get_uint(char **bpp, unsigned int *anint)
274{
275	char buf[50];
276	int len = qword_get(bpp, buf, sizeof(buf));
277
278	if (len < 0)
279		return -EINVAL;
280	if (len == 0)
281		return -ENOENT;
282
283	if (kstrtouint(buf, 0, anint))
284		return -EINVAL;
285
286	return 0;
287}
288
289static inline int get_time(char **bpp, time64_t *time)
290{
291	char buf[50];
292	long long ll;
293	int len = qword_get(bpp, buf, sizeof(buf));
294
295	if (len < 0)
296		return -EINVAL;
297	if (len == 0)
298		return -ENOENT;
299
300	if (kstrtoll(buf, 0, &ll))
301		return -EINVAL;
302
303	*time = ll;
304	return 0;
305}
306
307static inline int get_expiry(char **bpp, time64_t *rvp)
308{
309	int error;
310	struct timespec64 boot;
311
312	error = get_time(bpp, rvp);
313	if (error)
314		return error;
315
316	getboottime64(&boot);
317	(*rvp) -= boot.tv_sec;
318	return 0;
319}
320
321#endif /*  _LINUX_SUNRPC_CACHE_H_ */
322