1
2
3
4
5
6
7
8#ifdef pr_fmt
9#undef pr_fmt
10#endif
11
12#define pr_fmt(fmt) "CacheFiles: " fmt
13
14
15#include <linux/fscache-cache.h>
16#include <linux/cred.h>
17#include <linux/security.h>
18
19#define CACHEFILES_DIO_BLOCK_SIZE 4096
20
21struct cachefiles_cache;
22struct cachefiles_object;
23
24enum cachefiles_content {
25
26 CACHEFILES_CONTENT_NO_DATA = 0,
27 CACHEFILES_CONTENT_SINGLE = 1,
28 CACHEFILES_CONTENT_ALL = 2,
29 CACHEFILES_CONTENT_BACKFS_MAP = 3,
30 CACHEFILES_CONTENT_DIRTY = 4,
31 nr__cachefiles_content
32};
33
34
35
36
37struct cachefiles_volume {
38 struct cachefiles_cache *cache;
39 struct list_head cache_link;
40 struct fscache_volume *vcookie;
41 struct dentry *dentry;
42 struct dentry *fanout[256];
43};
44
45
46
47
48struct cachefiles_object {
49 struct fscache_cookie *cookie;
50 struct cachefiles_volume *volume;
51 struct list_head cache_link;
52 struct file *file;
53 char *d_name;
54 int debug_id;
55 spinlock_t lock;
56 refcount_t ref;
57 u8 d_name_len;
58 enum cachefiles_content content_info:8;
59 unsigned long flags;
60#define CACHEFILES_OBJECT_USING_TMPFILE 0
61};
62
63
64
65
66struct cachefiles_cache {
67 struct fscache_cache *cache;
68 struct vfsmount *mnt;
69 struct dentry *store;
70 struct dentry *graveyard;
71 struct file *cachefilesd;
72 struct list_head volumes;
73 struct list_head object_list;
74 spinlock_t object_list_lock;
75 const struct cred *cache_cred;
76 struct mutex daemon_mutex;
77 wait_queue_head_t daemon_pollwq;
78 atomic_t gravecounter;
79 atomic_t f_released;
80 atomic_long_t b_released;
81 atomic_long_t b_writing;
82 unsigned frun_percent;
83 unsigned fcull_percent;
84 unsigned fstop_percent;
85 unsigned brun_percent;
86 unsigned bcull_percent;
87 unsigned bstop_percent;
88 unsigned bsize;
89 unsigned bshift;
90 uint64_t frun;
91 uint64_t fcull;
92 uint64_t fstop;
93 sector_t brun;
94 sector_t bcull;
95 sector_t bstop;
96 unsigned long flags;
97#define CACHEFILES_READY 0
98#define CACHEFILES_DEAD 1
99#define CACHEFILES_CULLING 2
100#define CACHEFILES_STATE_CHANGED 3
101 char *rootdirname;
102 char *secctx;
103 char *tag;
104};
105
106#include <trace/events/cachefiles.h>
107
108static inline
109struct file *cachefiles_cres_file(struct netfs_cache_resources *cres)
110{
111 return cres->cache_priv2;
112}
113
114static inline
115struct cachefiles_object *cachefiles_cres_object(struct netfs_cache_resources *cres)
116{
117 return fscache_cres_cookie(cres)->cache_priv;
118}
119
120
121
122
123static inline void cachefiles_state_changed(struct cachefiles_cache *cache)
124{
125 set_bit(CACHEFILES_STATE_CHANGED, &cache->flags);
126 wake_up_all(&cache->daemon_pollwq);
127}
128
129
130
131
132extern int cachefiles_add_cache(struct cachefiles_cache *cache);
133extern void cachefiles_withdraw_cache(struct cachefiles_cache *cache);
134
135enum cachefiles_has_space_for {
136 cachefiles_has_space_check,
137 cachefiles_has_space_for_write,
138 cachefiles_has_space_for_create,
139};
140extern int cachefiles_has_space(struct cachefiles_cache *cache,
141 unsigned fnr, unsigned bnr,
142 enum cachefiles_has_space_for reason);
143
144
145
146
147extern const struct file_operations cachefiles_daemon_fops;
148
149
150
151
152#ifdef CONFIG_CACHEFILES_ERROR_INJECTION
153extern unsigned int cachefiles_error_injection_state;
154extern int cachefiles_register_error_injection(void);
155extern void cachefiles_unregister_error_injection(void);
156
157#else
158#define cachefiles_error_injection_state 0
159
160static inline int cachefiles_register_error_injection(void)
161{
162 return 0;
163}
164
165static inline void cachefiles_unregister_error_injection(void)
166{
167}
168#endif
169
170
171static inline int cachefiles_inject_read_error(void)
172{
173 return cachefiles_error_injection_state & 2 ? -EIO : 0;
174}
175
176static inline int cachefiles_inject_write_error(void)
177{
178 return cachefiles_error_injection_state & 2 ? -EIO :
179 cachefiles_error_injection_state & 1 ? -ENOSPC :
180 0;
181}
182
183static inline int cachefiles_inject_remove_error(void)
184{
185 return cachefiles_error_injection_state & 2 ? -EIO : 0;
186}
187
188
189
190
191extern const struct fscache_cache_ops cachefiles_cache_ops;
192extern void cachefiles_see_object(struct cachefiles_object *object,
193 enum cachefiles_obj_ref_trace why);
194extern struct cachefiles_object *cachefiles_grab_object(struct cachefiles_object *object,
195 enum cachefiles_obj_ref_trace why);
196extern void cachefiles_put_object(struct cachefiles_object *object,
197 enum cachefiles_obj_ref_trace why);
198
199
200
201
202extern bool cachefiles_begin_operation(struct netfs_cache_resources *cres,
203 enum fscache_want_state want_state);
204
205
206
207
208extern bool cachefiles_cook_key(struct cachefiles_object *object);
209
210
211
212
213extern struct kmem_cache *cachefiles_object_jar;
214
215
216
217
218extern void cachefiles_unmark_inode_in_use(struct cachefiles_object *object,
219 struct file *file);
220extern int cachefiles_bury_object(struct cachefiles_cache *cache,
221 struct cachefiles_object *object,
222 struct dentry *dir,
223 struct dentry *rep,
224 enum fscache_why_object_killed why);
225extern int cachefiles_delete_object(struct cachefiles_object *object,
226 enum fscache_why_object_killed why);
227extern bool cachefiles_look_up_object(struct cachefiles_object *object);
228extern struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
229 struct dentry *dir,
230 const char *name,
231 bool *_is_new);
232extern void cachefiles_put_directory(struct dentry *dir);
233
234extern int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
235 char *filename);
236
237extern int cachefiles_check_in_use(struct cachefiles_cache *cache,
238 struct dentry *dir, char *filename);
239extern struct file *cachefiles_create_tmpfile(struct cachefiles_object *object);
240extern bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache,
241 struct cachefiles_object *object);
242
243
244
245
246extern int cachefiles_get_security_ID(struct cachefiles_cache *cache);
247extern int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
248 struct dentry *root,
249 const struct cred **_saved_cred);
250
251static inline void cachefiles_begin_secure(struct cachefiles_cache *cache,
252 const struct cred **_saved_cred)
253{
254 *_saved_cred = override_creds(cache->cache_cred);
255}
256
257static inline void cachefiles_end_secure(struct cachefiles_cache *cache,
258 const struct cred *saved_cred)
259{
260 revert_creds(saved_cred);
261}
262
263
264
265
266void cachefiles_acquire_volume(struct fscache_volume *volume);
267void cachefiles_free_volume(struct fscache_volume *volume);
268void cachefiles_withdraw_volume(struct cachefiles_volume *volume);
269
270
271
272
273extern int cachefiles_set_object_xattr(struct cachefiles_object *object);
274extern int cachefiles_check_auxdata(struct cachefiles_object *object,
275 struct file *file);
276extern int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
277 struct cachefiles_object *object,
278 struct dentry *dentry);
279extern void cachefiles_prepare_to_write(struct fscache_cookie *cookie);
280extern bool cachefiles_set_volume_xattr(struct cachefiles_volume *volume);
281extern int cachefiles_check_volume_xattr(struct cachefiles_volume *volume);
282
283
284
285
286#define cachefiles_io_error(___cache, FMT, ...) \
287do { \
288 pr_err("I/O Error: " FMT"\n", ##__VA_ARGS__); \
289 fscache_io_error((___cache)->cache); \
290 set_bit(CACHEFILES_DEAD, &(___cache)->flags); \
291} while (0)
292
293#define cachefiles_io_error_obj(object, FMT, ...) \
294do { \
295 struct cachefiles_cache *___cache; \
296 \
297 ___cache = (object)->volume->cache; \
298 cachefiles_io_error(___cache, FMT " [o=%08x]", ##__VA_ARGS__, \
299 (object)->debug_id); \
300} while (0)
301
302
303
304
305
306extern unsigned cachefiles_debug;
307#define CACHEFILES_DEBUG_KENTER 1
308#define CACHEFILES_DEBUG_KLEAVE 2
309#define CACHEFILES_DEBUG_KDEBUG 4
310
311#define dbgprintk(FMT, ...) \
312 printk(KERN_DEBUG "[%-6.6s] "FMT"\n", current->comm, ##__VA_ARGS__)
313
314#define kenter(FMT, ...) dbgprintk("==> %s("FMT")", __func__, ##__VA_ARGS__)
315#define kleave(FMT, ...) dbgprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
316#define kdebug(FMT, ...) dbgprintk(FMT, ##__VA_ARGS__)
317
318
319#if defined(__KDEBUG)
320#define _enter(FMT, ...) kenter(FMT, ##__VA_ARGS__)
321#define _leave(FMT, ...) kleave(FMT, ##__VA_ARGS__)
322#define _debug(FMT, ...) kdebug(FMT, ##__VA_ARGS__)
323
324#elif defined(CONFIG_CACHEFILES_DEBUG)
325#define _enter(FMT, ...) \
326do { \
327 if (cachefiles_debug & CACHEFILES_DEBUG_KENTER) \
328 kenter(FMT, ##__VA_ARGS__); \
329} while (0)
330
331#define _leave(FMT, ...) \
332do { \
333 if (cachefiles_debug & CACHEFILES_DEBUG_KLEAVE) \
334 kleave(FMT, ##__VA_ARGS__); \
335} while (0)
336
337#define _debug(FMT, ...) \
338do { \
339 if (cachefiles_debug & CACHEFILES_DEBUG_KDEBUG) \
340 kdebug(FMT, ##__VA_ARGS__); \
341} while (0)
342
343#else
344#define _enter(FMT, ...) no_printk("==> %s("FMT")", __func__, ##__VA_ARGS__)
345#define _leave(FMT, ...) no_printk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
346#define _debug(FMT, ...) no_printk(FMT, ##__VA_ARGS__)
347#endif
348
349#if 1
350
351#define ASSERT(X) \
352do { \
353 if (unlikely(!(X))) { \
354 pr_err("\n"); \
355 pr_err("Assertion failed\n"); \
356 BUG(); \
357 } \
358} while (0)
359
360#define ASSERTCMP(X, OP, Y) \
361do { \
362 if (unlikely(!((X) OP (Y)))) { \
363 pr_err("\n"); \
364 pr_err("Assertion failed\n"); \
365 pr_err("%lx " #OP " %lx is false\n", \
366 (unsigned long)(X), (unsigned long)(Y)); \
367 BUG(); \
368 } \
369} while (0)
370
371#define ASSERTIF(C, X) \
372do { \
373 if (unlikely((C) && !(X))) { \
374 pr_err("\n"); \
375 pr_err("Assertion failed\n"); \
376 BUG(); \
377 } \
378} while (0)
379
380#define ASSERTIFCMP(C, X, OP, Y) \
381do { \
382 if (unlikely((C) && !((X) OP (Y)))) { \
383 pr_err("\n"); \
384 pr_err("Assertion failed\n"); \
385 pr_err("%lx " #OP " %lx is false\n", \
386 (unsigned long)(X), (unsigned long)(Y)); \
387 BUG(); \
388 } \
389} while (0)
390
391#else
392
393#define ASSERT(X) do {} while (0)
394#define ASSERTCMP(X, OP, Y) do {} while (0)
395#define ASSERTIF(C, X) do {} while (0)
396#define ASSERTIFCMP(C, X, OP, Y) do {} while (0)
397
398#endif
399