root/include/linux/sunrpc/cache.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. seconds_since_boot
  2. convert_to_wallclock
  3. cache_get
  4. cache_get_rcu
  5. cache_put
  6. cache_is_expired
  7. get_int
  8. get_uint
  9. get_time
  10. get_expiry

   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/proc_fs.h>
  18 
  19 /*
  20  * Each cache requires:
  21  *  - A 'struct cache_detail' which contains information specific to the cache
  22  *    for common code to use.
  23  *  - An item structure that must contain a "struct cache_head"
  24  *  - A lookup function defined using DefineCacheLookup
  25  *  - A 'put' function that can release a cache item. It will only
  26  *    be called after cache_put has succeed, so there are guarantee
  27  *    to be no references.
  28  *  - A function to calculate a hash of an item's key.
  29  *
  30  * as well as assorted code fragments (e.g. compare keys) and numbers
  31  * (e.g. hash size, goal_age, etc).
  32  *
  33  * Each cache must be registered so that it can be cleaned regularly.
  34  * When the cache is unregistered, it is flushed completely.
  35  *
  36  * Entries have a ref count and a 'hashed' flag which counts the existence
  37  * in the hash table.
  38  * We only expire entries when refcount is zero.
  39  * Existence in the cache is counted  the refcount.
  40  */
  41 
  42 /* Every cache item has a common header that is used
  43  * for expiring and refreshing entries.
  44  * 
  45  */
  46 struct cache_head {
  47         struct hlist_node       cache_list;
  48         time_t          expiry_time;    /* After time time, don't use the data */
  49         time_t          last_refresh;   /* If CACHE_PENDING, this is when upcall was
  50                                          * sent, else this is when update was
  51                                          * received, though it is alway set to
  52                                          * be *after* ->flush_time.
  53                                          */
  54         struct kref     ref;
  55         unsigned long   flags;
  56 };
  57 #define CACHE_VALID     0       /* Entry contains valid data */
  58 #define CACHE_NEGATIVE  1       /* Negative entry - there is no match for the key */
  59 #define CACHE_PENDING   2       /* An upcall has been sent but no reply received yet*/
  60 #define CACHE_CLEANED   3       /* Entry has been cleaned from cache */
  61 
  62 #define CACHE_NEW_EXPIRY 120    /* keep new things pending confirmation for 120 seconds */
  63 
  64 struct cache_detail {
  65         struct module *         owner;
  66         int                     hash_size;
  67         struct hlist_head *     hash_table;
  68         spinlock_t              hash_lock;
  69 
  70         char                    *name;
  71         void                    (*cache_put)(struct kref *);
  72 
  73         int                     (*cache_upcall)(struct cache_detail *,
  74                                                 struct cache_head *);
  75 
  76         void                    (*cache_request)(struct cache_detail *cd,
  77                                                  struct cache_head *ch,
  78                                                  char **bpp, int *blen);
  79 
  80         int                     (*cache_parse)(struct cache_detail *,
  81                                                char *buf, int len);
  82 
  83         int                     (*cache_show)(struct seq_file *m,
  84                                               struct cache_detail *cd,
  85                                               struct cache_head *h);
  86         void                    (*warn_no_listener)(struct cache_detail *cd,
  87                                               int has_died);
  88 
  89         struct cache_head *     (*alloc)(void);
  90         void                    (*flush)(void);
  91         int                     (*match)(struct cache_head *orig, struct cache_head *new);
  92         void                    (*init)(struct cache_head *orig, struct cache_head *new);
  93         void                    (*update)(struct cache_head *orig, struct cache_head *new);
  94 
  95         /* fields below this comment are for internal use
  96          * and should not be touched by cache owners
  97          */
  98         time_t                  flush_time;             /* flush all cache items with
  99                                                          * last_refresh at or earlier
 100                                                          * than this.  last_refresh
 101                                                          * is never set at or earlier
 102                                                          * than this.
 103                                                          */
 104         struct list_head        others;
 105         time_t                  nextcheck;
 106         int                     entries;
 107 
 108         /* fields for communication over channel */
 109         struct list_head        queue;
 110 
 111         atomic_t                writers;                /* how many time is /channel open */
 112         time_t                  last_close;             /* if no writers, when did last close */
 113         time_t                  last_warn;              /* when we last warned about no writers */
 114 
 115         union {
 116                 struct proc_dir_entry   *procfs;
 117                 struct dentry           *pipefs;
 118         };
 119         struct net              *net;
 120 };
 121 
 122 
 123 /* this must be embedded in any request structure that
 124  * identifies an object that will want a callback on
 125  * a cache fill
 126  */
 127 struct cache_req {
 128         struct cache_deferred_req *(*defer)(struct cache_req *req);
 129         int thread_wait;  /* How long (jiffies) we can block the
 130                            * current thread to wait for updates.
 131                            */
 132 };
 133 /* this must be embedded in a deferred_request that is being
 134  * delayed awaiting cache-fill
 135  */
 136 struct cache_deferred_req {
 137         struct hlist_node       hash;   /* on hash chain */
 138         struct list_head        recent; /* on fifo */
 139         struct cache_head       *item;  /* cache item we wait on */
 140         void                    *owner; /* we might need to discard all defered requests
 141                                          * owned by someone */
 142         void                    (*revisit)(struct cache_deferred_req *req,
 143                                            int too_many);
 144 };
 145 
 146 /*
 147  * timestamps kept in the cache are expressed in seconds
 148  * since boot.  This is the best for measuring differences in
 149  * real time.
 150  */
 151 static inline time_t seconds_since_boot(void)
 152 {
 153         struct timespec boot;
 154         getboottime(&boot);
 155         return get_seconds() - boot.tv_sec;
 156 }
 157 
 158 static inline time_t convert_to_wallclock(time_t sinceboot)
 159 {
 160         struct timespec boot;
 161         getboottime(&boot);
 162         return boot.tv_sec + sinceboot;
 163 }
 164 
 165 extern const struct file_operations cache_file_operations_pipefs;
 166 extern const struct file_operations content_file_operations_pipefs;
 167 extern const struct file_operations cache_flush_operations_pipefs;
 168 
 169 extern struct cache_head *
 170 sunrpc_cache_lookup_rcu(struct cache_detail *detail,
 171                         struct cache_head *key, int hash);
 172 extern struct cache_head *
 173 sunrpc_cache_update(struct cache_detail *detail,
 174                     struct cache_head *new, struct cache_head *old, int hash);
 175 
 176 extern int
 177 sunrpc_cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h);
 178 
 179 
 180 extern void cache_clean_deferred(void *owner);
 181 
 182 static inline struct cache_head  *cache_get(struct cache_head *h)
 183 {
 184         kref_get(&h->ref);
 185         return h;
 186 }
 187 
 188 static inline struct cache_head  *cache_get_rcu(struct cache_head *h)
 189 {
 190         if (kref_get_unless_zero(&h->ref))
 191                 return h;
 192         return NULL;
 193 }
 194 
 195 static inline void cache_put(struct cache_head *h, struct cache_detail *cd)
 196 {
 197         if (kref_read(&h->ref) <= 2 &&
 198             h->expiry_time < cd->nextcheck)
 199                 cd->nextcheck = h->expiry_time;
 200         kref_put(&h->ref, cd->cache_put);
 201 }
 202 
 203 static inline bool cache_is_expired(struct cache_detail *detail, struct cache_head *h)
 204 {
 205         if (!test_bit(CACHE_VALID, &h->flags))
 206                 return false;
 207 
 208         return  (h->expiry_time < seconds_since_boot()) ||
 209                 (detail->flush_time >= h->last_refresh);
 210 }
 211 
 212 extern int cache_check(struct cache_detail *detail,
 213                        struct cache_head *h, struct cache_req *rqstp);
 214 extern void cache_flush(void);
 215 extern void cache_purge(struct cache_detail *detail);
 216 #define NEVER (0x7FFFFFFF)
 217 extern void __init cache_initialize(void);
 218 extern int cache_register_net(struct cache_detail *cd, struct net *net);
 219 extern void cache_unregister_net(struct cache_detail *cd, struct net *net);
 220 
 221 extern struct cache_detail *cache_create_net(const struct cache_detail *tmpl, struct net *net);
 222 extern void cache_destroy_net(struct cache_detail *cd, struct net *net);
 223 
 224 extern void sunrpc_init_cache_detail(struct cache_detail *cd);
 225 extern void sunrpc_destroy_cache_detail(struct cache_detail *cd);
 226 extern int sunrpc_cache_register_pipefs(struct dentry *parent, const char *,
 227                                         umode_t, struct cache_detail *);
 228 extern void sunrpc_cache_unregister_pipefs(struct cache_detail *);
 229 extern void sunrpc_cache_unhash(struct cache_detail *, struct cache_head *);
 230 
 231 /* Must store cache_detail in seq_file->private if using next three functions */
 232 extern void *cache_seq_start_rcu(struct seq_file *file, loff_t *pos);
 233 extern void *cache_seq_next_rcu(struct seq_file *file, void *p, loff_t *pos);
 234 extern void cache_seq_stop_rcu(struct seq_file *file, void *p);
 235 
 236 extern void qword_add(char **bpp, int *lp, char *str);
 237 extern void qword_addhex(char **bpp, int *lp, char *buf, int blen);
 238 extern int qword_get(char **bpp, char *dest, int bufsize);
 239 
 240 static inline int get_int(char **bpp, int *anint)
 241 {
 242         char buf[50];
 243         char *ep;
 244         int rv;
 245         int len = qword_get(bpp, buf, sizeof(buf));
 246 
 247         if (len < 0)
 248                 return -EINVAL;
 249         if (len == 0)
 250                 return -ENOENT;
 251 
 252         rv = simple_strtol(buf, &ep, 0);
 253         if (*ep)
 254                 return -EINVAL;
 255 
 256         *anint = rv;
 257         return 0;
 258 }
 259 
 260 static inline int get_uint(char **bpp, unsigned int *anint)
 261 {
 262         char buf[50];
 263         int len = qword_get(bpp, buf, sizeof(buf));
 264 
 265         if (len < 0)
 266                 return -EINVAL;
 267         if (len == 0)
 268                 return -ENOENT;
 269 
 270         if (kstrtouint(buf, 0, anint))
 271                 return -EINVAL;
 272 
 273         return 0;
 274 }
 275 
 276 static inline int get_time(char **bpp, time_t *time)
 277 {
 278         char buf[50];
 279         long long ll;
 280         int len = qword_get(bpp, buf, sizeof(buf));
 281 
 282         if (len < 0)
 283                 return -EINVAL;
 284         if (len == 0)
 285                 return -ENOENT;
 286 
 287         if (kstrtoll(buf, 0, &ll))
 288                 return -EINVAL;
 289 
 290         *time = (time_t)ll;
 291         return 0;
 292 }
 293 
 294 static inline time_t get_expiry(char **bpp)
 295 {
 296         time_t rv;
 297         struct timespec boot;
 298 
 299         if (get_time(bpp, &rv))
 300                 return 0;
 301         if (rv < 0)
 302                 return 0;
 303         getboottime(&boot);
 304         return rv - boot.tv_sec;
 305 }
 306 
 307 #endif /*  _LINUX_SUNRPC_CACHE_H_ */

/* [<][>][^][v][top][bottom][index][help] */