Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * include/linux/sunrpc/cache.h
0004  *
0005  * Generic code for various authentication-related caches
0006  * used by sunrpc clients and servers.
0007  *
0008  * Copyright (C) 2002 Neil Brown <neilb@cse.unsw.edu.au>
0009  */
0010 
0011 #ifndef _LINUX_SUNRPC_CACHE_H_
0012 #define _LINUX_SUNRPC_CACHE_H_
0013 
0014 #include <linux/kref.h>
0015 #include <linux/slab.h>
0016 #include <linux/atomic.h>
0017 #include <linux/kstrtox.h>
0018 #include <linux/proc_fs.h>
0019 
0020 /*
0021  * Each cache requires:
0022  *  - A 'struct cache_detail' which contains information specific to the cache
0023  *    for common code to use.
0024  *  - An item structure that must contain a "struct cache_head"
0025  *  - A lookup function defined using DefineCacheLookup
0026  *  - A 'put' function that can release a cache item. It will only
0027  *    be called after cache_put has succeed, so there are guarantee
0028  *    to be no references.
0029  *  - A function to calculate a hash of an item's key.
0030  *
0031  * as well as assorted code fragments (e.g. compare keys) and numbers
0032  * (e.g. hash size, goal_age, etc).
0033  *
0034  * Each cache must be registered so that it can be cleaned regularly.
0035  * When the cache is unregistered, it is flushed completely.
0036  *
0037  * Entries have a ref count and a 'hashed' flag which counts the existence
0038  * in the hash table.
0039  * We only expire entries when refcount is zero.
0040  * Existence in the cache is counted  the refcount.
0041  */
0042 
0043 /* Every cache item has a common header that is used
0044  * for expiring and refreshing entries.
0045  * 
0046  */
0047 struct cache_head {
0048     struct hlist_node   cache_list;
0049     time64_t    expiry_time;    /* After time expiry_time, don't use
0050                      * the data */
0051     time64_t    last_refresh;   /* If CACHE_PENDING, this is when upcall was
0052                      * sent, else this is when update was
0053                      * received, though it is alway set to
0054                      * be *after* ->flush_time.
0055                      */
0056     struct kref ref;
0057     unsigned long   flags;
0058 };
0059 #define CACHE_VALID 0   /* Entry contains valid data */
0060 #define CACHE_NEGATIVE  1   /* Negative entry - there is no match for the key */
0061 #define CACHE_PENDING   2   /* An upcall has been sent but no reply received yet*/
0062 #define CACHE_CLEANED   3   /* Entry has been cleaned from cache */
0063 
0064 #define CACHE_NEW_EXPIRY 120    /* keep new things pending confirmation for 120 seconds */
0065 
0066 struct cache_detail {
0067     struct module *     owner;
0068     int         hash_size;
0069     struct hlist_head * hash_table;
0070     spinlock_t      hash_lock;
0071 
0072     char            *name;
0073     void            (*cache_put)(struct kref *);
0074 
0075     int         (*cache_upcall)(struct cache_detail *,
0076                         struct cache_head *);
0077 
0078     void            (*cache_request)(struct cache_detail *cd,
0079                          struct cache_head *ch,
0080                          char **bpp, int *blen);
0081 
0082     int         (*cache_parse)(struct cache_detail *,
0083                            char *buf, int len);
0084 
0085     int         (*cache_show)(struct seq_file *m,
0086                           struct cache_detail *cd,
0087                           struct cache_head *h);
0088     void            (*warn_no_listener)(struct cache_detail *cd,
0089                           int has_died);
0090 
0091     struct cache_head * (*alloc)(void);
0092     void            (*flush)(void);
0093     int         (*match)(struct cache_head *orig, struct cache_head *new);
0094     void            (*init)(struct cache_head *orig, struct cache_head *new);
0095     void            (*update)(struct cache_head *orig, struct cache_head *new);
0096 
0097     /* fields below this comment are for internal use
0098      * and should not be touched by cache owners
0099      */
0100     time64_t        flush_time;     /* flush all cache items with
0101                              * last_refresh at or earlier
0102                              * than this.  last_refresh
0103                              * is never set at or earlier
0104                              * than this.
0105                              */
0106     struct list_head    others;
0107     time64_t        nextcheck;
0108     int         entries;
0109 
0110     /* fields for communication over channel */
0111     struct list_head    queue;
0112 
0113     atomic_t        writers;        /* how many time is /channel open */
0114     time64_t        last_close;     /* if no writers, when did last close */
0115     time64_t        last_warn;      /* when we last warned about no writers */
0116 
0117     union {
0118         struct proc_dir_entry   *procfs;
0119         struct dentry       *pipefs;
0120     };
0121     struct net      *net;
0122 };
0123 
0124 /* this must be embedded in any request structure that
0125  * identifies an object that will want a callback on
0126  * a cache fill
0127  */
0128 struct cache_req {
0129     struct cache_deferred_req *(*defer)(struct cache_req *req);
0130     unsigned long   thread_wait;    /* How long (jiffies) we can block the
0131                      * current thread to wait for updates.
0132                      */
0133 };
0134 
0135 /* this must be embedded in a deferred_request that is being
0136  * delayed awaiting cache-fill
0137  */
0138 struct cache_deferred_req {
0139     struct hlist_node   hash;   /* on hash chain */
0140     struct list_head    recent; /* on fifo */
0141     struct cache_head   *item;  /* cache item we wait on */
0142     void            *owner; /* we might need to discard all defered requests
0143                      * owned by someone */
0144     void            (*revisit)(struct cache_deferred_req *req,
0145                        int too_many);
0146 };
0147 
0148 /*
0149  * timestamps kept in the cache are expressed in seconds
0150  * since boot.  This is the best for measuring differences in
0151  * real time.
0152  * This reimplemnts ktime_get_boottime_seconds() in a slightly
0153  * faster but less accurate way. When we end up converting
0154  * back to wallclock (CLOCK_REALTIME), that error often
0155  * cancels out during the reverse operation.
0156  */
0157 static inline time64_t seconds_since_boot(void)
0158 {
0159     struct timespec64 boot;
0160     getboottime64(&boot);
0161     return ktime_get_real_seconds() - boot.tv_sec;
0162 }
0163 
0164 static inline time64_t convert_to_wallclock(time64_t sinceboot)
0165 {
0166     struct timespec64 boot;
0167     getboottime64(&boot);
0168     return boot.tv_sec + sinceboot;
0169 }
0170 
0171 extern const struct file_operations cache_file_operations_pipefs;
0172 extern const struct file_operations content_file_operations_pipefs;
0173 extern const struct file_operations cache_flush_operations_pipefs;
0174 
0175 extern struct cache_head *
0176 sunrpc_cache_lookup_rcu(struct cache_detail *detail,
0177             struct cache_head *key, int hash);
0178 extern struct cache_head *
0179 sunrpc_cache_update(struct cache_detail *detail,
0180             struct cache_head *new, struct cache_head *old, int hash);
0181 
0182 extern int
0183 sunrpc_cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h);
0184 extern int
0185 sunrpc_cache_pipe_upcall_timeout(struct cache_detail *detail,
0186                  struct cache_head *h);
0187 
0188 
0189 extern void cache_clean_deferred(void *owner);
0190 
0191 static inline struct cache_head  *cache_get(struct cache_head *h)
0192 {
0193     kref_get(&h->ref);
0194     return h;
0195 }
0196 
0197 static inline struct cache_head  *cache_get_rcu(struct cache_head *h)
0198 {
0199     if (kref_get_unless_zero(&h->ref))
0200         return h;
0201     return NULL;
0202 }
0203 
0204 static inline void cache_put(struct cache_head *h, struct cache_detail *cd)
0205 {
0206     if (kref_read(&h->ref) <= 2 &&
0207         h->expiry_time < cd->nextcheck)
0208         cd->nextcheck = h->expiry_time;
0209     kref_put(&h->ref, cd->cache_put);
0210 }
0211 
0212 static inline bool cache_is_expired(struct cache_detail *detail, struct cache_head *h)
0213 {
0214     if (h->expiry_time < seconds_since_boot())
0215         return true;
0216     if (!test_bit(CACHE_VALID, &h->flags))
0217         return false;
0218     return detail->flush_time >= h->last_refresh;
0219 }
0220 
0221 extern int cache_check(struct cache_detail *detail,
0222                struct cache_head *h, struct cache_req *rqstp);
0223 extern void cache_flush(void);
0224 extern void cache_purge(struct cache_detail *detail);
0225 #define NEVER (0x7FFFFFFF)
0226 extern void __init cache_initialize(void);
0227 extern int cache_register_net(struct cache_detail *cd, struct net *net);
0228 extern void cache_unregister_net(struct cache_detail *cd, struct net *net);
0229 
0230 extern struct cache_detail *cache_create_net(const struct cache_detail *tmpl, struct net *net);
0231 extern void cache_destroy_net(struct cache_detail *cd, struct net *net);
0232 
0233 extern void sunrpc_init_cache_detail(struct cache_detail *cd);
0234 extern void sunrpc_destroy_cache_detail(struct cache_detail *cd);
0235 extern int sunrpc_cache_register_pipefs(struct dentry *parent, const char *,
0236                     umode_t, struct cache_detail *);
0237 extern void sunrpc_cache_unregister_pipefs(struct cache_detail *);
0238 extern void sunrpc_cache_unhash(struct cache_detail *, struct cache_head *);
0239 
0240 /* Must store cache_detail in seq_file->private if using next three functions */
0241 extern void *cache_seq_start_rcu(struct seq_file *file, loff_t *pos);
0242 extern void *cache_seq_next_rcu(struct seq_file *file, void *p, loff_t *pos);
0243 extern void cache_seq_stop_rcu(struct seq_file *file, void *p);
0244 
0245 extern void qword_add(char **bpp, int *lp, char *str);
0246 extern void qword_addhex(char **bpp, int *lp, char *buf, int blen);
0247 extern int qword_get(char **bpp, char *dest, int bufsize);
0248 
0249 static inline int get_int(char **bpp, int *anint)
0250 {
0251     char buf[50];
0252     char *ep;
0253     int rv;
0254     int len = qword_get(bpp, buf, sizeof(buf));
0255 
0256     if (len < 0)
0257         return -EINVAL;
0258     if (len == 0)
0259         return -ENOENT;
0260 
0261     rv = simple_strtol(buf, &ep, 0);
0262     if (*ep)
0263         return -EINVAL;
0264 
0265     *anint = rv;
0266     return 0;
0267 }
0268 
0269 static inline int get_uint(char **bpp, unsigned int *anint)
0270 {
0271     char buf[50];
0272     int len = qword_get(bpp, buf, sizeof(buf));
0273 
0274     if (len < 0)
0275         return -EINVAL;
0276     if (len == 0)
0277         return -ENOENT;
0278 
0279     if (kstrtouint(buf, 0, anint))
0280         return -EINVAL;
0281 
0282     return 0;
0283 }
0284 
0285 static inline int get_time(char **bpp, time64_t *time)
0286 {
0287     char buf[50];
0288     long long ll;
0289     int len = qword_get(bpp, buf, sizeof(buf));
0290 
0291     if (len < 0)
0292         return -EINVAL;
0293     if (len == 0)
0294         return -ENOENT;
0295 
0296     if (kstrtoll(buf, 0, &ll))
0297         return -EINVAL;
0298 
0299     *time = ll;
0300     return 0;
0301 }
0302 
0303 static inline time64_t get_expiry(char **bpp)
0304 {
0305     time64_t rv;
0306     struct timespec64 boot;
0307 
0308     if (get_time(bpp, &rv))
0309         return 0;
0310     if (rv < 0)
0311         return 0;
0312     getboottime64(&boot);
0313     return rv - boot.tv_sec;
0314 }
0315 
0316 #endif /*  _LINUX_SUNRPC_CACHE_H_ */