11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * include/linux/sunrpc/cache.h
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Generic code for various authentication-related caches
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * used by sunrpc clients and servers.
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2002 Neil Brown <neilb@cse.unsw.edu.au>
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Released under terms in GPL version 2.  See COPYING.
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef _LINUX_SUNRPC_CACHE_H_
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _LINUX_SUNRPC_CACHE_H_
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1657cc7215b70856dc6bae8e55b00ecd7b1d7429b1Alexey Dobriyan#include <linux/kref.h>
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h>
1860063497a95e716c9a689af3be2687d261f115b4Arun Sharma#include <linux/atomic.h>
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/proc_fs.h>
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Each cache requires:
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  - A 'struct cache_detail' which contains information specific to the cache
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    for common code to use.
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  - An item structure that must contain a "struct cache_head"
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  - A lookup function defined using DefineCacheLookup
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  - A 'put' function that can release a cache item. It will only
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    be called after cache_put has succeed, so there are guarantee
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    to be no references.
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  - A function to calculate a hash of an item's key.
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * as well as assorted code fragments (e.g. compare keys) and numbers
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (e.g. hash size, goal_age, etc).
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Each cache must be registered so that it can be cleaned regularly.
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * When the cache is unregistered, it is flushed completely.
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3825985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * Entries have a ref count and a 'hashed' flag which counts the existence
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * in the hash table.
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We only expire entries when refcount is zero.
4125985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * Existence in the cache is counted  the refcount.
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Every cache item has a common header that is used
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for expiring and refreshing entries.
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct cache_head {
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct cache_head * next;
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	time_t		expiry_time;	/* After time time, don't use the data */
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	time_t		last_refresh;   /* If CACHE_PENDING, this is when upcall
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					 * was sent, else this is when update was received
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					 */
54baab935ff3bdac20c558809da0d8e8f761840219NeilBrown	struct kref	ref;
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long	flags;
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define	CACHE_VALID	0	/* Entry contains valid data */
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define	CACHE_NEGATIVE	1	/* Negative entry - there is no match for the key */
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define	CACHE_PENDING	2	/* An upcall has been sent but no reply received yet*/
60013920eb5db97e99a4c30c8400f1c616e2a8b0a2NeilBrown#define	CACHE_CLEANED	3	/* Entry has been cleaned from cache */
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define	CACHE_NEW_EXPIRY 120	/* keep new things pending confirmation for 120 seconds */
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
64173912a6add00f4715774dcecf9ee53274c5924cTrond Myklebuststruct cache_detail_procfs {
65173912a6add00f4715774dcecf9ee53274c5924cTrond Myklebust	struct proc_dir_entry	*proc_ent;
66173912a6add00f4715774dcecf9ee53274c5924cTrond Myklebust	struct proc_dir_entry   *flush_ent, *channel_ent, *content_ent;
67173912a6add00f4715774dcecf9ee53274c5924cTrond Myklebust};
68173912a6add00f4715774dcecf9ee53274c5924cTrond Myklebust
698854e82d9accc80f43c0bc3ff06b5979ac858185Trond Myklebuststruct cache_detail_pipefs {
708854e82d9accc80f43c0bc3ff06b5979ac858185Trond Myklebust	struct dentry *dir;
718854e82d9accc80f43c0bc3ff06b5979ac858185Trond Myklebust};
728854e82d9accc80f43c0bc3ff06b5979ac858185Trond Myklebust
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct cache_detail {
74f35279d3f713e5c97b98cbdbf47d98f79942c11fBruce Allan	struct module *		owner;
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int			hash_size;
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct cache_head **	hash_table;
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	rwlock_t		hash_lock;
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	atomic_t		inuse; /* active user-space update or lookup */
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char			*name;
82baab935ff3bdac20c558809da0d8e8f761840219NeilBrown	void			(*cache_put)(struct kref *);
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
84bc74b4f5e63a09fb78e245794a0de1e5a2716bbeTrond Myklebust	int			(*cache_upcall)(struct cache_detail *,
85bc74b4f5e63a09fb78e245794a0de1e5a2716bbeTrond Myklebust						struct cache_head *);
86bc74b4f5e63a09fb78e245794a0de1e5a2716bbeTrond Myklebust
8773fb847a44224d5708550e4be7baba9da75e00afStanislav Kinsbursky	void			(*cache_request)(struct cache_detail *cd,
8873fb847a44224d5708550e4be7baba9da75e00afStanislav Kinsbursky						 struct cache_head *ch,
8973fb847a44224d5708550e4be7baba9da75e00afStanislav Kinsbursky						 char **bpp, int *blen);
9073fb847a44224d5708550e4be7baba9da75e00afStanislav Kinsbursky
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int			(*cache_parse)(struct cache_detail *,
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					       char *buf, int len);
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int			(*cache_show)(struct seq_file *m,
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					      struct cache_detail *cd,
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					      struct cache_head *h);
972da8ca26c6bfad685bfddf39728eac1c83906aa9Trond Myklebust	void			(*warn_no_listener)(struct cache_detail *cd,
982da8ca26c6bfad685bfddf39728eac1c83906aa9Trond Myklebust					      int has_died);
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10015a5f6bd23eddd5b3be80366f364be04fb1c1c99NeilBrown	struct cache_head *	(*alloc)(void);
10115a5f6bd23eddd5b3be80366f364be04fb1c1c99NeilBrown	int			(*match)(struct cache_head *orig, struct cache_head *new);
10215a5f6bd23eddd5b3be80366f364be04fb1c1c99NeilBrown	void			(*init)(struct cache_head *orig, struct cache_head *new);
10315a5f6bd23eddd5b3be80366f364be04fb1c1c99NeilBrown	void			(*update)(struct cache_head *orig, struct cache_head *new);
10415a5f6bd23eddd5b3be80366f364be04fb1c1c99NeilBrown
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* fields below this comment are for internal use
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * and should not be touched by cache owners
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	time_t			flush_time;		/* flush all cache items with last_refresh
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds							 * earlier than this */
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct list_head	others;
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	time_t			nextcheck;
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int			entries;
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* fields for communication over channel */
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct list_head	queue;
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	atomic_t		readers;		/* how many time is /chennel open */
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	time_t			last_close;		/* if no readers, when did last close */
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	time_t			last_warn;		/* when we last warned about no readers */
120173912a6add00f4715774dcecf9ee53274c5924cTrond Myklebust
121173912a6add00f4715774dcecf9ee53274c5924cTrond Myklebust	union {
122173912a6add00f4715774dcecf9ee53274c5924cTrond Myklebust		struct cache_detail_procfs procfs;
1238854e82d9accc80f43c0bc3ff06b5979ac858185Trond Myklebust		struct cache_detail_pipefs pipefs;
124173912a6add00f4715774dcecf9ee53274c5924cTrond Myklebust	} u;
1250a402d5a653ee2b613aaba3092a87b1e964622ceStanislav Kinsbursky	struct net		*net;
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* this must be embedded in any request structure that
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * identifies an object that will want a callback on
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * a cache fill
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct cache_req {
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct cache_deferred_req *(*defer)(struct cache_req *req);
135f16b6e8d838b2e2bb4561201311c66ac02ad67dfNeilBrown	int thread_wait;  /* How long (jiffies) we can block the
136f16b6e8d838b2e2bb4561201311c66ac02ad67dfNeilBrown			   * current thread to wait for updates.
137f16b6e8d838b2e2bb4561201311c66ac02ad67dfNeilBrown			   */
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* this must be embedded in a deferred_request that is being
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * delayed awaiting cache-fill
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct cache_deferred_req {
1431117449276bb909b029ed0b9ba13f53e4784db9dNeilBrown	struct hlist_node	hash;	/* on hash chain */
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct list_head	recent; /* on fifo */
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct cache_head	*item;  /* cache item we wait on */
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	void			*owner; /* we might need to discard all defered requests
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					 * owned by someone */
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	void			(*revisit)(struct cache_deferred_req *req,
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					   int too_many);
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1527715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrown/*
1537715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrown * timestamps kept in the cache are expressed in seconds
1547715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrown * since boot.  This is the best for measuring differences in
1557715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrown * real time.
1567715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrown */
1577715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrownstatic inline time_t seconds_since_boot(void)
1587715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrown{
1597715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrown	struct timespec boot;
1607715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrown	getboottime(&boot);
1617715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrown	return get_seconds() - boot.tv_sec;
1627715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrown}
1637715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrown
1647715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrownstatic inline time_t convert_to_wallclock(time_t sinceboot)
1657715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrown{
1667715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrown	struct timespec boot;
1677715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrown	getboottime(&boot);
1687715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrown	return boot.tv_sec + sinceboot;
1697715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrown}
1707d317f2c9f1e9dcf4f632fa98f91d1d4a36c4caeNeilBrown
1718854e82d9accc80f43c0bc3ff06b5979ac858185Trond Myklebustextern const struct file_operations cache_file_operations_pipefs;
1728854e82d9accc80f43c0bc3ff06b5979ac858185Trond Myklebustextern const struct file_operations content_file_operations_pipefs;
1738854e82d9accc80f43c0bc3ff06b5979ac858185Trond Myklebustextern const struct file_operations cache_flush_operations_pipefs;
1748854e82d9accc80f43c0bc3ff06b5979ac858185Trond Myklebust
17515a5f6bd23eddd5b3be80366f364be04fb1c1c99NeilBrownextern struct cache_head *
17615a5f6bd23eddd5b3be80366f364be04fb1c1c99NeilBrownsunrpc_cache_lookup(struct cache_detail *detail,
17715a5f6bd23eddd5b3be80366f364be04fb1c1c99NeilBrown		    struct cache_head *key, int hash);
17815a5f6bd23eddd5b3be80366f364be04fb1c1c99NeilBrownextern struct cache_head *
17915a5f6bd23eddd5b3be80366f364be04fb1c1c99NeilBrownsunrpc_cache_update(struct cache_detail *detail,
18015a5f6bd23eddd5b3be80366f364be04fb1c1c99NeilBrown		    struct cache_head *new, struct cache_head *old, int hash);
18115a5f6bd23eddd5b3be80366f364be04fb1c1c99NeilBrown
182bc74b4f5e63a09fb78e245794a0de1e5a2716bbeTrond Myklebustextern int
18321cd1254d3402a72927ed744e8ac1a7cf532f1eaStanislav Kinsburskysunrpc_cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h);
184bc74b4f5e63a09fb78e245794a0de1e5a2716bbeTrond Myklebust
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void cache_clean_deferred(void *owner);
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline struct cache_head  *cache_get(struct cache_head *h)
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
190baab935ff3bdac20c558809da0d8e8f761840219NeilBrown	kref_get(&h->ref);
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return h;
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
195baab935ff3bdac20c558809da0d8e8f761840219NeilBrownstatic inline void cache_put(struct cache_head *h, struct cache_detail *cd)
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
197baab935ff3bdac20c558809da0d8e8f761840219NeilBrown	if (atomic_read(&h->ref.refcount) <= 2 &&
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    h->expiry_time < cd->nextcheck)
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cd->nextcheck = h->expiry_time;
200baab935ff3bdac20c558809da0d8e8f761840219NeilBrown	kref_put(&h->ref, cd->cache_put);
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2037715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrownstatic inline int cache_is_expired(struct cache_detail *detail, struct cache_head *h)
2047b2b1fee30df7e2165525cd03f7d1d01a3a56794Greg Banks{
2057715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrown	return  (h->expiry_time < seconds_since_boot()) ||
2067715cde86857d4bb40f43f1ee971cf906eaf1b9cNeilBrown		(detail->flush_time > h->last_refresh);
2077b2b1fee30df7e2165525cd03f7d1d01a3a56794Greg Banks}
2087b2b1fee30df7e2165525cd03f7d1d01a3a56794Greg Banks
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern int cache_check(struct cache_detail *detail,
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       struct cache_head *h, struct cache_req *rqstp);
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void cache_flush(void);
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void cache_purge(struct cache_detail *detail);
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define NEVER (0x7FFFFFFF)
2148eab945c5616fc984e97b922d6a2559be93f39a1Artem Bityutskiyextern void __init cache_initialize(void);
215593ce16b943ea37d4ec62c377b32d7f3f4085e84Pavel Emelyanovextern int cache_register_net(struct cache_detail *cd, struct net *net);
216593ce16b943ea37d4ec62c377b32d7f3f4085e84Pavel Emelyanovextern void cache_unregister_net(struct cache_detail *cd, struct net *net);
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2180a402d5a653ee2b613aaba3092a87b1e964622ceStanislav Kinsburskyextern struct cache_detail *cache_create_net(struct cache_detail *tmpl, struct net *net);
2190a402d5a653ee2b613aaba3092a87b1e964622ceStanislav Kinsburskyextern void cache_destroy_net(struct cache_detail *cd, struct net *net);
2200a402d5a653ee2b613aaba3092a87b1e964622ceStanislav Kinsbursky
221820f9442e711a81749e70c40f149fc54c4ce0ca8Stanislav Kinsburskyextern void sunrpc_init_cache_detail(struct cache_detail *cd);
222820f9442e711a81749e70c40f149fc54c4ce0ca8Stanislav Kinsburskyextern void sunrpc_destroy_cache_detail(struct cache_detail *cd);
2238854e82d9accc80f43c0bc3ff06b5979ac858185Trond Myklebustextern int sunrpc_cache_register_pipefs(struct dentry *parent, const char *,
22464f1426f3c4f8dde9ac9bf3f3b19b88d17f2bae6Al Viro					umode_t, struct cache_detail *);
2258854e82d9accc80f43c0bc3ff06b5979ac858185Trond Myklebustextern void sunrpc_cache_unregister_pipefs(struct cache_detail *);
2268854e82d9accc80f43c0bc3ff06b5979ac858185Trond Myklebust
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void qword_add(char **bpp, int *lp, char *str);
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void qword_addhex(char **bpp, int *lp, char *buf, int blen);
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern int qword_get(char **bpp, char *dest, int bufsize);
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int get_int(char **bpp, int *anint)
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char buf[50];
234621eb19ce1ec216e03ad354cb0c4061736b2a436J. Bruce Fields	char *ep;
235621eb19ce1ec216e03ad354cb0c4061736b2a436J. Bruce Fields	int rv;
236d9c2ede63c74048dfddbb129c59ac01176b0ab71Eldad Zack	int len = qword_get(bpp, buf, sizeof(buf));
237d9c2ede63c74048dfddbb129c59ac01176b0ab71Eldad Zack
238d9c2ede63c74048dfddbb129c59ac01176b0ab71Eldad Zack	if (len < 0)
239d9c2ede63c74048dfddbb129c59ac01176b0ab71Eldad Zack		return -EINVAL;
240d9c2ede63c74048dfddbb129c59ac01176b0ab71Eldad Zack	if (len == 0)
241d9c2ede63c74048dfddbb129c59ac01176b0ab71Eldad Zack		return -ENOENT;
242d9c2ede63c74048dfddbb129c59ac01176b0ab71Eldad Zack
243621eb19ce1ec216e03ad354cb0c4061736b2a436J. Bruce Fields	rv = simple_strtol(buf, &ep, 0);
244621eb19ce1ec216e03ad354cb0c4061736b2a436J. Bruce Fields	if (*ep)
245d9c2ede63c74048dfddbb129c59ac01176b0ab71Eldad Zack		return -EINVAL;
246d9c2ede63c74048dfddbb129c59ac01176b0ab71Eldad Zack
247621eb19ce1ec216e03ad354cb0c4061736b2a436J. Bruce Fields	*anint = rv;
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
251a007c4c3e943ecc054a806c259d95420a188754bJ. Bruce Fieldsstatic inline int get_uint(char **bpp, unsigned int *anint)
252a007c4c3e943ecc054a806c259d95420a188754bJ. Bruce Fields{
253a007c4c3e943ecc054a806c259d95420a188754bJ. Bruce Fields	char buf[50];
254a007c4c3e943ecc054a806c259d95420a188754bJ. Bruce Fields	int len = qword_get(bpp, buf, sizeof(buf));
255a007c4c3e943ecc054a806c259d95420a188754bJ. Bruce Fields
256a007c4c3e943ecc054a806c259d95420a188754bJ. Bruce Fields	if (len < 0)
257a007c4c3e943ecc054a806c259d95420a188754bJ. Bruce Fields		return -EINVAL;
258a007c4c3e943ecc054a806c259d95420a188754bJ. Bruce Fields	if (len == 0)
259a007c4c3e943ecc054a806c259d95420a188754bJ. Bruce Fields		return -ENOENT;
260a007c4c3e943ecc054a806c259d95420a188754bJ. Bruce Fields
261a007c4c3e943ecc054a806c259d95420a188754bJ. Bruce Fields	if (kstrtouint(buf, 0, anint))
262a007c4c3e943ecc054a806c259d95420a188754bJ. Bruce Fields		return -EINVAL;
263a007c4c3e943ecc054a806c259d95420a188754bJ. Bruce Fields
264a007c4c3e943ecc054a806c259d95420a188754bJ. Bruce Fields	return 0;
265a007c4c3e943ecc054a806c259d95420a188754bJ. Bruce Fields}
266a007c4c3e943ecc054a806c259d95420a188754bJ. Bruce Fields
2672f74f972d4cc7d83408ea0c32d424edcb44887bfHarshula Jayasuriyastatic inline int get_time(char **bpp, time_t *time)
2682f74f972d4cc7d83408ea0c32d424edcb44887bfHarshula Jayasuriya{
2692f74f972d4cc7d83408ea0c32d424edcb44887bfHarshula Jayasuriya	char buf[50];
2702f74f972d4cc7d83408ea0c32d424edcb44887bfHarshula Jayasuriya	long long ll;
2712f74f972d4cc7d83408ea0c32d424edcb44887bfHarshula Jayasuriya	int len = qword_get(bpp, buf, sizeof(buf));
2722f74f972d4cc7d83408ea0c32d424edcb44887bfHarshula Jayasuriya
2732f74f972d4cc7d83408ea0c32d424edcb44887bfHarshula Jayasuriya	if (len < 0)
2742f74f972d4cc7d83408ea0c32d424edcb44887bfHarshula Jayasuriya		return -EINVAL;
2752f74f972d4cc7d83408ea0c32d424edcb44887bfHarshula Jayasuriya	if (len == 0)
2762f74f972d4cc7d83408ea0c32d424edcb44887bfHarshula Jayasuriya		return -ENOENT;
2772f74f972d4cc7d83408ea0c32d424edcb44887bfHarshula Jayasuriya
2782f74f972d4cc7d83408ea0c32d424edcb44887bfHarshula Jayasuriya	if (kstrtoll(buf, 0, &ll))
2792f74f972d4cc7d83408ea0c32d424edcb44887bfHarshula Jayasuriya		return -EINVAL;
2802f74f972d4cc7d83408ea0c32d424edcb44887bfHarshula Jayasuriya
2812f74f972d4cc7d83408ea0c32d424edcb44887bfHarshula Jayasuriya	*time = (time_t)ll;
2822f74f972d4cc7d83408ea0c32d424edcb44887bfHarshula Jayasuriya	return 0;
2832f74f972d4cc7d83408ea0c32d424edcb44887bfHarshula Jayasuriya}
2842f74f972d4cc7d83408ea0c32d424edcb44887bfHarshula Jayasuriya
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline time_t get_expiry(char **bpp)
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2872f74f972d4cc7d83408ea0c32d424edcb44887bfHarshula Jayasuriya	time_t rv;
288c5b29f885afe890f953f7f23424045cdad31d3e4NeilBrown	struct timespec boot;
289c5b29f885afe890f953f7f23424045cdad31d3e4NeilBrown
2902f74f972d4cc7d83408ea0c32d424edcb44887bfHarshula Jayasuriya	if (get_time(bpp, &rv))
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (rv < 0)
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
294c5b29f885afe890f953f7f23424045cdad31d3e4NeilBrown	getboottime(&boot);
295c5b29f885afe890f953f7f23424045cdad31d3e4NeilBrown	return rv - boot.tv_sec;
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /*  _LINUX_SUNRPC_CACHE_H_ */
299