This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / fs / cachefiles / internal.h
1 /* internal.h: general netfs cache on cache files internal defs
2  *
3  * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells (dhowells@redhat.com)
5  *
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.
10  *
11  *
12  * CacheFiles layout:
13  *
14  *      /..../CacheDir/
15  *              index
16  *              0/
17  *              1/
18  *              2/
19  *                index
20  *                0/
21  *                1/
22  *                2/
23  *                  index
24  *                  0
25  *                  1
26  *                  2
27  */
28
29 #include <linux/fscache-cache.h>
30 #include <linux/timer.h>
31 #include <linux/wait.h>
32 #include <linux/workqueue.h>
33
34 struct cachefiles_cache;
35 struct cachefiles_object;
36
37 extern unsigned long cachefiles_debug;
38 #define CACHEFILES_DEBUG_KENTER 1
39 #define CACHEFILES_DEBUG_KLEAVE 2
40 #define CACHEFILES_DEBUG_KDEBUG 4
41
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;
45
46 /*****************************************************************************/
47 /*
48  * node records
49  */
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 */
59         spinlock_t                      work_lock;
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) */
67 };
68
69 extern kmem_cache_t *cachefiles_object_jar;
70
71 /*****************************************************************************/
72 /*
73  * Cache files cache definition
74  */
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 */
91         unsigned long                   flags;
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 */
97 };
98
99 /*****************************************************************************/
100 /*
101  * backing file read tracking
102  */
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;
110         void                            *context;
111 };
112
113 /*****************************************************************************/
114 /*
115  * backing file write tracking
116  */
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;
122         void                            *context;
123 };
124
125 /*****************************************************************************/
126 /*
127  * auxiliary data xattr buffer
128  */
129 struct cachefiles_xattr {
130         uint16_t                        len;
131         uint8_t                         type;
132         uint8_t                         data[];
133 };
134
135
136 /* cf-bind.c */
137 extern int cachefiles_proc_bind(struct cachefiles_cache *cache, char *args);
138 extern void cachefiles_proc_unbind(struct cachefiles_cache *cache);
139
140 /* cf-interface.c */
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);
144
145 /* cf-key.c */
146 extern char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type);
147
148 /* cf-namei.c */
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,
153                                      char *key,
154                                      struct cachefiles_xattr *auxdata);
155 extern struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
156                                                struct dentry *dir,
157                                                const char *name);
158
159 extern int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
160                            char *filename);
161
162 /* cf-sysctl.c */
163 extern int __init cachefiles_sysctl_init(void);
164 extern void __exit cachefiles_sysctl_cleanup(void);
165
166 /* cf-xattr.c */
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);
174
175
176 /*****************************************************************************/
177 /*
178  * error handling
179  */
180 #define kerror(FMT,...) printk(KERN_ERR "CacheFiles: "FMT"\n" ,##__VA_ARGS__);
181
182 #define cachefiles_io_error(___cache, FMT, ...)         \
183 do {                                                    \
184         kerror("I/O Error: " FMT ,##__VA_ARGS__);       \
185         fscache_io_error(&(___cache)->cache);           \
186         set_bit(CACHEFILES_DEAD, &(___cache)->flags);   \
187 } while(0)
188
189 #define cachefiles_io_error_obj(object, FMT, ...)                       \
190 do {                                                                    \
191         struct cachefiles_cache *___cache;                              \
192                                                                         \
193         ___cache = container_of((object)->fscache.cache,                \
194                                 struct cachefiles_cache, cache);        \
195         cachefiles_io_error(___cache, FMT ,##__VA_ARGS__);              \
196 } while(0)
197
198
199 /*****************************************************************************/
200 /*
201  * debug tracing
202  */
203 #define dbgprintk(FMT,...) \
204         printk("[%-6.6s] "FMT"\n",current->comm ,##__VA_ARGS__)
205
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, ...)
210 {
211 }
212
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__)
216
217
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__)
222
223 #elif defined(CONFIG_CACHEFILES_DEBUG)
224 #define _enter(FMT,...)                                 \
225 do {                                                    \
226         if (cachefiles_debug & CACHEFILES_DEBUG_KENTER) \
227                 kenter(FMT,##__VA_ARGS__);              \
228 } while (0)
229
230 #define _leave(FMT,...)                                 \
231 do {                                                    \
232         if (cachefiles_debug & CACHEFILES_DEBUG_KLEAVE) \
233                 kleave(FMT,##__VA_ARGS__);              \
234 } while (0)
235
236 #define _debug(FMT,...)                                 \
237 do {                                                    \
238         if (cachefiles_debug & CACHEFILES_DEBUG_KDEBUG) \
239                 kdebug(FMT,##__VA_ARGS__);              \
240 } while (0)
241
242 #else
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__)
246 #endif
247
248 #if 1 // defined(__KDEBUGALL)
249
250 #define ASSERT(X)                                                       \
251 do {                                                                    \
252         if (unlikely(!(X))) {                                           \
253                 printk(KERN_ERR "\n");                                  \
254                 printk(KERN_ERR "CacheFiles: Assertion failed\n");      \
255                 BUG();                                                  \
256         }                                                               \
257 } while(0)
258
259 #define ASSERTCMP(X, OP, Y)                                             \
260 do {                                                                    \
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));         \
266                 BUG();                                                  \
267         }                                                               \
268 } while(0)
269
270 #define ASSERTIF(C, X)                                                  \
271 do {                                                                    \
272         if (unlikely((C) && !(X))) {                                    \
273                 printk(KERN_ERR "\n");                                  \
274                 printk(KERN_ERR "CacheFiles: Assertion failed\n");      \
275                 BUG();                                                  \
276         }                                                               \
277 } while(0)
278
279 #define ASSERTIFCMP(C, X, OP, Y)                                        \
280 do {                                                                    \
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));         \
286                 BUG();                                                  \
287         }                                                               \
288 } while(0)
289
290 #else
291
292 #define ASSERT(X)                               \
293 do {                                            \
294 } while(0)
295
296 #define ASSERTCMP(X, OP, Y)                     \
297 do {                                            \
298 } while(0)
299
300 #define ASSERTIF(C, X)                          \
301 do {                                            \
302 } while(0)
303
304 #define ASSERTIFCMP(C, X, OP, Y)                \
305 do {                                            \
306 } while(0)
307
308 #endif