1 /* internal.h: general netfs cache on cache files internal defs
3 * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
29 #include <linux/fscache-cache.h>
30 #include <linux/timer.h>
31 #include <linux/wait.h>
32 #include <linux/workqueue.h>
34 struct cachefiles_cache;
35 struct cachefiles_object;
37 extern unsigned long cachefiles_debug;
38 #define CACHEFILES_DEBUG_KENTER 1
39 #define CACHEFILES_DEBUG_KLEAVE 2
40 #define CACHEFILES_DEBUG_KDEBUG 4
42 extern struct fscache_cache_ops cachefiles_cache_ops;
43 extern struct proc_dir_entry *cachefiles_proc;
44 extern struct file_operations cachefiles_proc_fops;
46 /*****************************************************************************/
50 struct cachefiles_object {
51 struct fscache_object fscache; /* fscache handle */
52 struct dentry *dentry; /* the file/dir representing this object */
53 struct dentry *backer; /* backing file */
54 loff_t i_size; /* object size */
55 atomic_t usage; /* basic object usage count */
56 atomic_t fscache_usage; /* FSDEF object usage count */
57 uint8_t type; /* object type */
58 uint8_t new; /* T if object new */
60 struct rw_semaphore sem;
61 struct work_struct read_work; /* read page copier */
62 struct list_head read_list; /* pages to copy */
63 struct list_head read_pend_list; /* pages to pending read from backer */
64 struct work_struct write_work; /* page writer */
65 struct list_head write_list; /* pages to store */
66 struct rb_node active_node; /* link in active tree (dentry is key) */
69 extern kmem_cache_t *cachefiles_object_jar;
71 /*****************************************************************************/
73 * Cache files cache definition
75 struct cachefiles_cache {
76 struct fscache_cache cache; /* FS-Cache record */
77 struct vfsmount *mnt; /* mountpoint holding the cache */
78 struct dentry *graveyard; /* directory into which dead objects go */
79 struct file *cachefilesd; /* manager daemon handle */
80 struct rb_root active_nodes; /* active nodes (can't be culled) */
81 rwlock_t active_lock; /* lock for active_nodes */
82 atomic_t gravecounter; /* graveyard uniquifier */
83 unsigned brun_percent; /* when to stop culling (%) */
84 unsigned bcull_percent; /* when to start culling (%) */
85 unsigned bstop_percent; /* when to stop allocating (%) */
86 unsigned bsize; /* cache's block size */
87 unsigned bshift; /* min(log2 (PAGE_SIZE / bsize), 0) */
88 sector_t brun; /* when to stop culling */
89 sector_t bcull; /* when to start culling */
90 sector_t bstop; /* when to stop allocating */
92 #define CACHEFILES_READY 0 /* T if cache prepared */
93 #define CACHEFILES_DEAD 1 /* T if cache dead */
94 #define CACHEFILES_CULLING 2 /* T if cull engaged */
95 char *rootdirname; /* name of cache root directory */
96 char *tag; /* cache binding tag */
99 /*****************************************************************************/
101 * backing file read tracking
103 struct cachefiles_one_read {
104 wait_queue_t monitor; /* link into monitored waitqueue */
105 struct page *back_page; /* backing file page we're waiting for */
106 struct page *netfs_page; /* netfs page we're going to fill */
107 struct cachefiles_object *object;
108 struct list_head obj_link; /* link in object's lists */
109 fscache_rw_complete_t end_io_func;
113 /*****************************************************************************/
115 * backing file write tracking
117 struct cachefiles_one_write {
118 struct page *netfs_page; /* netfs page to copy */
119 struct cachefiles_object *object;
120 struct list_head obj_link; /* link in object's lists */
121 fscache_rw_complete_t end_io_func;
125 /*****************************************************************************/
127 * auxiliary data xattr buffer
129 struct cachefiles_xattr {
137 extern int cachefiles_proc_bind(struct cachefiles_cache *cache, char *args);
138 extern void cachefiles_proc_unbind(struct cachefiles_cache *cache);
141 extern void cachefiles_read_copier_work(void *_object);
142 extern void cachefiles_write_work(void *_object);
143 extern int cachefiles_has_space(struct cachefiles_cache *cache, unsigned nr);
146 extern char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type);
149 extern int cachefiles_delete_object(struct cachefiles_cache *cache,
150 struct cachefiles_object *object);
151 extern int cachefiles_walk_to_object(struct cachefiles_object *parent,
152 struct cachefiles_object *object,
154 struct cachefiles_xattr *auxdata);
155 extern struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
159 extern int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
163 extern int __init cachefiles_sysctl_init(void);
164 extern void __exit cachefiles_sysctl_cleanup(void);
167 extern int cachefiles_check_object_type(struct cachefiles_object *object);
168 extern int cachefiles_set_object_xattr(struct cachefiles_object *object,
169 struct cachefiles_xattr *auxdata);
170 extern int cachefiles_check_object_xattr(struct cachefiles_object *object,
171 struct cachefiles_xattr *auxdata);
172 extern int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
173 struct dentry *dentry);
176 /*****************************************************************************/
180 #define kerror(FMT,...) printk(KERN_ERR "CacheFiles: "FMT"\n" ,##__VA_ARGS__);
182 #define cachefiles_io_error(___cache, FMT, ...) \
184 kerror("I/O Error: " FMT ,##__VA_ARGS__); \
185 fscache_io_error(&(___cache)->cache); \
186 set_bit(CACHEFILES_DEAD, &(___cache)->flags); \
189 #define cachefiles_io_error_obj(object, FMT, ...) \
191 struct cachefiles_cache *___cache; \
193 ___cache = container_of((object)->fscache.cache, \
194 struct cachefiles_cache, cache); \
195 cachefiles_io_error(___cache, FMT ,##__VA_ARGS__); \
199 /*****************************************************************************/
203 #define dbgprintk(FMT,...) \
204 printk("[%-6.6s] "FMT"\n",current->comm ,##__VA_ARGS__)
206 /* make sure we maintain the format strings, even when debugging is disabled */
207 static inline void _dbprintk(const char *fmt, ...)
208 __attribute__((format(printf,1,2)));
209 static inline void _dbprintk(const char *fmt, ...)
213 #define kenter(FMT,...) dbgprintk("==> %s("FMT")",__FUNCTION__ ,##__VA_ARGS__)
214 #define kleave(FMT,...) dbgprintk("<== %s()"FMT"",__FUNCTION__ ,##__VA_ARGS__)
215 #define kdebug(FMT,...) dbgprintk(FMT ,##__VA_ARGS__)
218 #if defined(__KDEBUG)
219 #define _enter(FMT,...) kenter(FMT,##__VA_ARGS__)
220 #define _leave(FMT,...) kleave(FMT,##__VA_ARGS__)
221 #define _debug(FMT,...) kdebug(FMT,##__VA_ARGS__)
223 #elif defined(CONFIG_CACHEFILES_DEBUG)
224 #define _enter(FMT,...) \
226 if (cachefiles_debug & CACHEFILES_DEBUG_KENTER) \
227 kenter(FMT,##__VA_ARGS__); \
230 #define _leave(FMT,...) \
232 if (cachefiles_debug & CACHEFILES_DEBUG_KLEAVE) \
233 kleave(FMT,##__VA_ARGS__); \
236 #define _debug(FMT,...) \
238 if (cachefiles_debug & CACHEFILES_DEBUG_KDEBUG) \
239 kdebug(FMT,##__VA_ARGS__); \
243 #define _enter(FMT,...) _dbprintk("==> %s("FMT")",__FUNCTION__ ,##__VA_ARGS__)
244 #define _leave(FMT,...) _dbprintk("<== %s()"FMT"",__FUNCTION__ ,##__VA_ARGS__)
245 #define _debug(FMT,...) _dbprintk(FMT ,##__VA_ARGS__)
248 #if 1 // defined(__KDEBUGALL)
252 if (unlikely(!(X))) { \
253 printk(KERN_ERR "\n"); \
254 printk(KERN_ERR "CacheFiles: Assertion failed\n"); \
259 #define ASSERTCMP(X, OP, Y) \
261 if (unlikely(!((X) OP (Y)))) { \
262 printk(KERN_ERR "\n"); \
263 printk(KERN_ERR "CacheFiles: Assertion failed\n"); \
264 printk(KERN_ERR "%lx " #OP " %lx is false\n", \
265 (unsigned long)(X), (unsigned long)(Y)); \
270 #define ASSERTIF(C, X) \
272 if (unlikely((C) && !(X))) { \
273 printk(KERN_ERR "\n"); \
274 printk(KERN_ERR "CacheFiles: Assertion failed\n"); \
279 #define ASSERTIFCMP(C, X, OP, Y) \
281 if (unlikely((C) && !((X) OP (Y)))) { \
282 printk(KERN_ERR "\n"); \
283 printk(KERN_ERR "CacheFiles: Assertion failed\n"); \
284 printk(KERN_ERR "%lx " #OP " %lx is false\n", \
285 (unsigned long)(X), (unsigned long)(Y)); \
296 #define ASSERTCMP(X, OP, Y) \
300 #define ASSERTIF(C, X) \
304 #define ASSERTIFCMP(C, X, OP, Y) \