1
2
3
4
5
6
7
8
9
10
11
12#ifdef pr_fmt
13#undef pr_fmt
14#endif
15
16#define pr_fmt(fmt) "CacheFiles: " fmt
17
18
19#include <linux/fscache-cache.h>
20#include <linux/timer.h>
21#include <linux/wait_bit.h>
22#include <linux/cred.h>
23#include <linux/workqueue.h>
24#include <linux/security.h>
25
26struct cachefiles_cache;
27struct cachefiles_object;
28
29extern unsigned cachefiles_debug;
30#define CACHEFILES_DEBUG_KENTER 1
31#define CACHEFILES_DEBUG_KLEAVE 2
32#define CACHEFILES_DEBUG_KDEBUG 4
33
34#define cachefiles_gfp (__GFP_RECLAIM | __GFP_NORETRY | __GFP_NOMEMALLOC)
35
36
37
38
39struct cachefiles_object {
40 struct fscache_object fscache;
41 struct cachefiles_lookup_data *lookup_data;
42 struct dentry *dentry;
43 struct dentry *backer;
44 loff_t i_size;
45 unsigned long flags;
46#define CACHEFILES_OBJECT_ACTIVE 0
47 atomic_t usage;
48 uint8_t type;
49 uint8_t new;
50 spinlock_t work_lock;
51 struct rb_node active_node;
52};
53
54extern struct kmem_cache *cachefiles_object_jar;
55
56
57
58
59struct cachefiles_cache {
60 struct fscache_cache cache;
61 struct vfsmount *mnt;
62 struct dentry *graveyard;
63 struct file *cachefilesd;
64 const struct cred *cache_cred;
65 struct mutex daemon_mutex;
66 wait_queue_head_t daemon_pollwq;
67 struct rb_root active_nodes;
68 rwlock_t active_lock;
69 atomic_t gravecounter;
70 atomic_t f_released;
71 atomic_long_t b_released;
72 unsigned frun_percent;
73 unsigned fcull_percent;
74 unsigned fstop_percent;
75 unsigned brun_percent;
76 unsigned bcull_percent;
77 unsigned bstop_percent;
78 unsigned bsize;
79 unsigned bshift;
80 uint64_t frun;
81 uint64_t fcull;
82 uint64_t fstop;
83 sector_t brun;
84 sector_t bcull;
85 sector_t bstop;
86 unsigned long flags;
87#define CACHEFILES_READY 0
88#define CACHEFILES_DEAD 1
89#define CACHEFILES_CULLING 2
90#define CACHEFILES_STATE_CHANGED 3
91 char *rootdirname;
92 char *secctx;
93 char *tag;
94};
95
96
97
98
99struct cachefiles_one_read {
100 wait_queue_entry_t monitor;
101 struct page *back_page;
102 struct page *netfs_page;
103 struct fscache_retrieval *op;
104 struct list_head op_link;
105};
106
107
108
109
110struct cachefiles_one_write {
111 struct page *netfs_page;
112 struct cachefiles_object *object;
113 struct list_head obj_link;
114 fscache_rw_complete_t end_io_func;
115 void *context;
116};
117
118
119
120
121struct cachefiles_xattr {
122 uint16_t len;
123 uint8_t type;
124 uint8_t data[];
125};
126
127#include <trace/events/cachefiles.h>
128
129
130
131
132static inline void cachefiles_state_changed(struct cachefiles_cache *cache)
133{
134 set_bit(CACHEFILES_STATE_CHANGED, &cache->flags);
135 wake_up_all(&cache->daemon_pollwq);
136}
137
138
139
140
141extern int cachefiles_daemon_bind(struct cachefiles_cache *cache, char *args);
142extern void cachefiles_daemon_unbind(struct cachefiles_cache *cache);
143
144
145
146
147extern const struct file_operations cachefiles_daemon_fops;
148
149extern int cachefiles_has_space(struct cachefiles_cache *cache,
150 unsigned fnr, unsigned bnr);
151
152
153
154
155extern const struct fscache_cache_ops cachefiles_cache_ops;
156
157
158
159
160extern char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type);
161
162
163
164
165extern void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
166 struct cachefiles_object *object,
167 blkcnt_t i_blocks);
168extern int cachefiles_delete_object(struct cachefiles_cache *cache,
169 struct cachefiles_object *object);
170extern int cachefiles_walk_to_object(struct cachefiles_object *parent,
171 struct cachefiles_object *object,
172 const char *key,
173 struct cachefiles_xattr *auxdata);
174extern struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
175 struct dentry *dir,
176 const char *name);
177
178extern int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
179 char *filename);
180
181extern int cachefiles_check_in_use(struct cachefiles_cache *cache,
182 struct dentry *dir, char *filename);
183
184
185
186
187#ifdef CONFIG_CACHEFILES_HISTOGRAM
188extern atomic_t cachefiles_lookup_histogram[HZ];
189extern atomic_t cachefiles_mkdir_histogram[HZ];
190extern atomic_t cachefiles_create_histogram[HZ];
191
192extern int __init cachefiles_proc_init(void);
193extern void cachefiles_proc_cleanup(void);
194static inline
195void cachefiles_hist(atomic_t histogram[], unsigned long start_jif)
196{
197 unsigned long jif = jiffies - start_jif;
198 if (jif >= HZ)
199 jif = HZ - 1;
200 atomic_inc(&histogram[jif]);
201}
202
203#else
204#define cachefiles_proc_init() (0)
205#define cachefiles_proc_cleanup() do {} while (0)
206#define cachefiles_hist(hist, start_jif) do {} while (0)
207#endif
208
209
210
211
212extern int cachefiles_read_or_alloc_page(struct fscache_retrieval *,
213 struct page *, gfp_t);
214extern int cachefiles_read_or_alloc_pages(struct fscache_retrieval *,
215 struct list_head *, unsigned *,
216 gfp_t);
217extern int cachefiles_allocate_page(struct fscache_retrieval *, struct page *,
218 gfp_t);
219extern int cachefiles_allocate_pages(struct fscache_retrieval *,
220 struct list_head *, unsigned *, gfp_t);
221extern int cachefiles_write_page(struct fscache_storage *, struct page *);
222extern void cachefiles_uncache_page(struct fscache_object *, struct page *);
223
224
225
226
227extern int cachefiles_get_security_ID(struct cachefiles_cache *cache);
228extern int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
229 struct dentry *root,
230 const struct cred **_saved_cred);
231
232static inline void cachefiles_begin_secure(struct cachefiles_cache *cache,
233 const struct cred **_saved_cred)
234{
235 *_saved_cred = override_creds(cache->cache_cred);
236}
237
238static inline void cachefiles_end_secure(struct cachefiles_cache *cache,
239 const struct cred *saved_cred)
240{
241 revert_creds(saved_cred);
242}
243
244
245
246
247extern int cachefiles_check_object_type(struct cachefiles_object *object);
248extern int cachefiles_set_object_xattr(struct cachefiles_object *object,
249 struct cachefiles_xattr *auxdata);
250extern int cachefiles_update_object_xattr(struct cachefiles_object *object,
251 struct cachefiles_xattr *auxdata);
252extern int cachefiles_check_auxdata(struct cachefiles_object *object);
253extern int cachefiles_check_object_xattr(struct cachefiles_object *object,
254 struct cachefiles_xattr *auxdata);
255extern int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
256 struct dentry *dentry);
257
258
259
260
261
262
263#define cachefiles_io_error(___cache, FMT, ...) \
264do { \
265 pr_err("I/O Error: " FMT"\n", ##__VA_ARGS__); \
266 fscache_io_error(&(___cache)->cache); \
267 set_bit(CACHEFILES_DEAD, &(___cache)->flags); \
268} while (0)
269
270#define cachefiles_io_error_obj(object, FMT, ...) \
271do { \
272 struct cachefiles_cache *___cache; \
273 \
274 ___cache = container_of((object)->fscache.cache, \
275 struct cachefiles_cache, cache); \
276 cachefiles_io_error(___cache, FMT, ##__VA_ARGS__); \
277} while (0)
278
279
280
281
282
283#define dbgprintk(FMT, ...) \
284 printk(KERN_DEBUG "[%-6.6s] "FMT"\n", current->comm, ##__VA_ARGS__)
285
286#define kenter(FMT, ...) dbgprintk("==> %s("FMT")", __func__, ##__VA_ARGS__)
287#define kleave(FMT, ...) dbgprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
288#define kdebug(FMT, ...) dbgprintk(FMT, ##__VA_ARGS__)
289
290
291#if defined(__KDEBUG)
292#define _enter(FMT, ...) kenter(FMT, ##__VA_ARGS__)
293#define _leave(FMT, ...) kleave(FMT, ##__VA_ARGS__)
294#define _debug(FMT, ...) kdebug(FMT, ##__VA_ARGS__)
295
296#elif defined(CONFIG_CACHEFILES_DEBUG)
297#define _enter(FMT, ...) \
298do { \
299 if (cachefiles_debug & CACHEFILES_DEBUG_KENTER) \
300 kenter(FMT, ##__VA_ARGS__); \
301} while (0)
302
303#define _leave(FMT, ...) \
304do { \
305 if (cachefiles_debug & CACHEFILES_DEBUG_KLEAVE) \
306 kleave(FMT, ##__VA_ARGS__); \
307} while (0)
308
309#define _debug(FMT, ...) \
310do { \
311 if (cachefiles_debug & CACHEFILES_DEBUG_KDEBUG) \
312 kdebug(FMT, ##__VA_ARGS__); \
313} while (0)
314
315#else
316#define _enter(FMT, ...) no_printk("==> %s("FMT")", __func__, ##__VA_ARGS__)
317#define _leave(FMT, ...) no_printk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
318#define _debug(FMT, ...) no_printk(FMT, ##__VA_ARGS__)
319#endif
320
321#if 1
322
323#define ASSERT(X) \
324do { \
325 if (unlikely(!(X))) { \
326 pr_err("\n"); \
327 pr_err("Assertion failed\n"); \
328 BUG(); \
329 } \
330} while (0)
331
332#define ASSERTCMP(X, OP, Y) \
333do { \
334 if (unlikely(!((X) OP (Y)))) { \
335 pr_err("\n"); \
336 pr_err("Assertion failed\n"); \
337 pr_err("%lx " #OP " %lx is false\n", \
338 (unsigned long)(X), (unsigned long)(Y)); \
339 BUG(); \
340 } \
341} while (0)
342
343#define ASSERTIF(C, X) \
344do { \
345 if (unlikely((C) && !(X))) { \
346 pr_err("\n"); \
347 pr_err("Assertion failed\n"); \
348 BUG(); \
349 } \
350} while (0)
351
352#define ASSERTIFCMP(C, X, OP, Y) \
353do { \
354 if (unlikely((C) && !((X) OP (Y)))) { \
355 pr_err("\n"); \
356 pr_err("Assertion failed\n"); \
357 pr_err("%lx " #OP " %lx is false\n", \
358 (unsigned long)(X), (unsigned long)(Y)); \
359 BUG(); \
360 } \
361} while (0)
362
363#else
364
365#define ASSERT(X) do {} while (0)
366#define ASSERTCMP(X, OP, Y) do {} while (0)
367#define ASSERTIF(C, X) do {} while (0)
368#define ASSERTIFCMP(C, X, OP, Y) do {} while (0)
369
370#endif
371