home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / linux / sunrpc / cache.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  6.0 KB  |  203 lines

  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.     time_t            recv_time;
  124.     void            *owner; /* we might need to discard all defered requests
  125.                      * owned by someone */
  126.     void            (*revisit)(struct cache_deferred_req *req,
  127.                        int too_many);
  128. };
  129.  
  130.  
  131. extern struct cache_head *
  132. sunrpc_cache_lookup(struct cache_detail *detail,
  133.             struct cache_head *key, int hash);
  134. extern struct cache_head *
  135. sunrpc_cache_update(struct cache_detail *detail,
  136.             struct cache_head *new, struct cache_head *old, int hash);
  137.  
  138.  
  139. #define cache_for_each(pos, detail, index, member)                         \
  140.     for (({read_lock(&(detail)->hash_lock); index = (detail)->hash_size;}) ;        \
  141.          ({if (index==0)read_unlock(&(detail)->hash_lock); index--;});            \
  142.         )                                        \
  143.         for (pos = container_of((detail)->hash_table[index], typeof(*pos), member);    \
  144.              &pos->member;                                \
  145.              pos = container_of(pos->member.next, typeof(*pos), member))
  146.  
  147.          
  148.  
  149. extern void cache_clean_deferred(void *owner);
  150.  
  151. static inline struct cache_head  *cache_get(struct cache_head *h)
  152. {
  153.     kref_get(&h->ref);
  154.     return h;
  155. }
  156.  
  157.  
  158. static inline void cache_put(struct cache_head *h, struct cache_detail *cd)
  159. {
  160.     if (atomic_read(&h->ref.refcount) <= 2 &&
  161.         h->expiry_time < cd->nextcheck)
  162.         cd->nextcheck = h->expiry_time;
  163.     kref_put(&h->ref, cd->cache_put);
  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 void cache_register(struct cache_detail *cd);
  172. extern int 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_ */
  203.