Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/fs/cachefiles/internal.h
15109 views
1
/* General netfs cache on cache files internal defs
2
*
3
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4
* Written by David Howells ([email protected])
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public Licence
8
* as published by the Free Software Foundation; either version
9
* 2 of the Licence, or (at your option) any later version.
10
*/
11
12
#include <linux/fscache-cache.h>
13
#include <linux/timer.h>
14
#include <linux/wait.h>
15
#include <linux/workqueue.h>
16
#include <linux/security.h>
17
18
struct cachefiles_cache;
19
struct cachefiles_object;
20
21
extern unsigned cachefiles_debug;
22
#define CACHEFILES_DEBUG_KENTER 1
23
#define CACHEFILES_DEBUG_KLEAVE 2
24
#define CACHEFILES_DEBUG_KDEBUG 4
25
26
/*
27
* node records
28
*/
29
struct cachefiles_object {
30
struct fscache_object fscache; /* fscache handle */
31
struct cachefiles_lookup_data *lookup_data; /* cached lookup data */
32
struct dentry *dentry; /* the file/dir representing this object */
33
struct dentry *backer; /* backing file */
34
loff_t i_size; /* object size */
35
unsigned long flags;
36
#define CACHEFILES_OBJECT_ACTIVE 0 /* T if marked active */
37
#define CACHEFILES_OBJECT_BURIED 1 /* T if preemptively buried */
38
atomic_t usage; /* object usage count */
39
uint8_t type; /* object type */
40
uint8_t new; /* T if object new */
41
spinlock_t work_lock;
42
struct rb_node active_node; /* link in active tree (dentry is key) */
43
};
44
45
extern struct kmem_cache *cachefiles_object_jar;
46
47
/*
48
* Cache files cache definition
49
*/
50
struct cachefiles_cache {
51
struct fscache_cache cache; /* FS-Cache record */
52
struct vfsmount *mnt; /* mountpoint holding the cache */
53
struct dentry *graveyard; /* directory into which dead objects go */
54
struct file *cachefilesd; /* manager daemon handle */
55
const struct cred *cache_cred; /* security override for accessing cache */
56
struct mutex daemon_mutex; /* command serialisation mutex */
57
wait_queue_head_t daemon_pollwq; /* poll waitqueue for daemon */
58
struct rb_root active_nodes; /* active nodes (can't be culled) */
59
rwlock_t active_lock; /* lock for active_nodes */
60
atomic_t gravecounter; /* graveyard uniquifier */
61
unsigned frun_percent; /* when to stop culling (% files) */
62
unsigned fcull_percent; /* when to start culling (% files) */
63
unsigned fstop_percent; /* when to stop allocating (% files) */
64
unsigned brun_percent; /* when to stop culling (% blocks) */
65
unsigned bcull_percent; /* when to start culling (% blocks) */
66
unsigned bstop_percent; /* when to stop allocating (% blocks) */
67
unsigned bsize; /* cache's block size */
68
unsigned bshift; /* min(ilog2(PAGE_SIZE / bsize), 0) */
69
uint64_t frun; /* when to stop culling */
70
uint64_t fcull; /* when to start culling */
71
uint64_t fstop; /* when to stop allocating */
72
sector_t brun; /* when to stop culling */
73
sector_t bcull; /* when to start culling */
74
sector_t bstop; /* when to stop allocating */
75
unsigned long flags;
76
#define CACHEFILES_READY 0 /* T if cache prepared */
77
#define CACHEFILES_DEAD 1 /* T if cache dead */
78
#define CACHEFILES_CULLING 2 /* T if cull engaged */
79
#define CACHEFILES_STATE_CHANGED 3 /* T if state changed (poll trigger) */
80
char *rootdirname; /* name of cache root directory */
81
char *secctx; /* LSM security context */
82
char *tag; /* cache binding tag */
83
};
84
85
/*
86
* backing file read tracking
87
*/
88
struct cachefiles_one_read {
89
wait_queue_t monitor; /* link into monitored waitqueue */
90
struct page *back_page; /* backing file page we're waiting for */
91
struct page *netfs_page; /* netfs page we're going to fill */
92
struct fscache_retrieval *op; /* retrieval op covering this */
93
struct list_head op_link; /* link in op's todo list */
94
};
95
96
/*
97
* backing file write tracking
98
*/
99
struct cachefiles_one_write {
100
struct page *netfs_page; /* netfs page to copy */
101
struct cachefiles_object *object;
102
struct list_head obj_link; /* link in object's lists */
103
fscache_rw_complete_t end_io_func;
104
void *context;
105
};
106
107
/*
108
* auxiliary data xattr buffer
109
*/
110
struct cachefiles_xattr {
111
uint16_t len;
112
uint8_t type;
113
uint8_t data[];
114
};
115
116
/*
117
* note change of state for daemon
118
*/
119
static inline void cachefiles_state_changed(struct cachefiles_cache *cache)
120
{
121
set_bit(CACHEFILES_STATE_CHANGED, &cache->flags);
122
wake_up_all(&cache->daemon_pollwq);
123
}
124
125
/*
126
* bind.c
127
*/
128
extern int cachefiles_daemon_bind(struct cachefiles_cache *cache, char *args);
129
extern void cachefiles_daemon_unbind(struct cachefiles_cache *cache);
130
131
/*
132
* daemon.c
133
*/
134
extern const struct file_operations cachefiles_daemon_fops;
135
136
extern int cachefiles_has_space(struct cachefiles_cache *cache,
137
unsigned fnr, unsigned bnr);
138
139
/*
140
* interface.c
141
*/
142
extern const struct fscache_cache_ops cachefiles_cache_ops;
143
144
/*
145
* key.c
146
*/
147
extern char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type);
148
149
/*
150
* namei.c
151
*/
152
extern int cachefiles_delete_object(struct cachefiles_cache *cache,
153
struct cachefiles_object *object);
154
extern int cachefiles_walk_to_object(struct cachefiles_object *parent,
155
struct cachefiles_object *object,
156
const char *key,
157
struct cachefiles_xattr *auxdata);
158
extern struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
159
struct dentry *dir,
160
const char *name);
161
162
extern int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
163
char *filename);
164
165
extern int cachefiles_check_in_use(struct cachefiles_cache *cache,
166
struct dentry *dir, char *filename);
167
168
/*
169
* proc.c
170
*/
171
#ifdef CONFIG_CACHEFILES_HISTOGRAM
172
extern atomic_t cachefiles_lookup_histogram[HZ];
173
extern atomic_t cachefiles_mkdir_histogram[HZ];
174
extern atomic_t cachefiles_create_histogram[HZ];
175
176
extern int __init cachefiles_proc_init(void);
177
extern void cachefiles_proc_cleanup(void);
178
static inline
179
void cachefiles_hist(atomic_t histogram[], unsigned long start_jif)
180
{
181
unsigned long jif = jiffies - start_jif;
182
if (jif >= HZ)
183
jif = HZ - 1;
184
atomic_inc(&histogram[jif]);
185
}
186
187
#else
188
#define cachefiles_proc_init() (0)
189
#define cachefiles_proc_cleanup() do {} while (0)
190
#define cachefiles_hist(hist, start_jif) do {} while (0)
191
#endif
192
193
/*
194
* rdwr.c
195
*/
196
extern int cachefiles_read_or_alloc_page(struct fscache_retrieval *,
197
struct page *, gfp_t);
198
extern int cachefiles_read_or_alloc_pages(struct fscache_retrieval *,
199
struct list_head *, unsigned *,
200
gfp_t);
201
extern int cachefiles_allocate_page(struct fscache_retrieval *, struct page *,
202
gfp_t);
203
extern int cachefiles_allocate_pages(struct fscache_retrieval *,
204
struct list_head *, unsigned *, gfp_t);
205
extern int cachefiles_write_page(struct fscache_storage *, struct page *);
206
extern void cachefiles_uncache_page(struct fscache_object *, struct page *);
207
208
/*
209
* security.c
210
*/
211
extern int cachefiles_get_security_ID(struct cachefiles_cache *cache);
212
extern int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
213
struct dentry *root,
214
const struct cred **_saved_cred);
215
216
static inline void cachefiles_begin_secure(struct cachefiles_cache *cache,
217
const struct cred **_saved_cred)
218
{
219
*_saved_cred = override_creds(cache->cache_cred);
220
}
221
222
static inline void cachefiles_end_secure(struct cachefiles_cache *cache,
223
const struct cred *saved_cred)
224
{
225
revert_creds(saved_cred);
226
}
227
228
/*
229
* xattr.c
230
*/
231
extern int cachefiles_check_object_type(struct cachefiles_object *object);
232
extern int cachefiles_set_object_xattr(struct cachefiles_object *object,
233
struct cachefiles_xattr *auxdata);
234
extern int cachefiles_update_object_xattr(struct cachefiles_object *object,
235
struct cachefiles_xattr *auxdata);
236
extern int cachefiles_check_object_xattr(struct cachefiles_object *object,
237
struct cachefiles_xattr *auxdata);
238
extern int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
239
struct dentry *dentry);
240
241
242
/*
243
* error handling
244
*/
245
#define kerror(FMT, ...) printk(KERN_ERR "CacheFiles: "FMT"\n", ##__VA_ARGS__)
246
247
#define cachefiles_io_error(___cache, FMT, ...) \
248
do { \
249
kerror("I/O Error: " FMT, ##__VA_ARGS__); \
250
fscache_io_error(&(___cache)->cache); \
251
set_bit(CACHEFILES_DEAD, &(___cache)->flags); \
252
} while (0)
253
254
#define cachefiles_io_error_obj(object, FMT, ...) \
255
do { \
256
struct cachefiles_cache *___cache; \
257
\
258
___cache = container_of((object)->fscache.cache, \
259
struct cachefiles_cache, cache); \
260
cachefiles_io_error(___cache, FMT, ##__VA_ARGS__); \
261
} while (0)
262
263
264
/*
265
* debug tracing
266
*/
267
#define dbgprintk(FMT, ...) \
268
printk(KERN_DEBUG "[%-6.6s] "FMT"\n", current->comm, ##__VA_ARGS__)
269
270
#define kenter(FMT, ...) dbgprintk("==> %s("FMT")", __func__, ##__VA_ARGS__)
271
#define kleave(FMT, ...) dbgprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
272
#define kdebug(FMT, ...) dbgprintk(FMT, ##__VA_ARGS__)
273
274
275
#if defined(__KDEBUG)
276
#define _enter(FMT, ...) kenter(FMT, ##__VA_ARGS__)
277
#define _leave(FMT, ...) kleave(FMT, ##__VA_ARGS__)
278
#define _debug(FMT, ...) kdebug(FMT, ##__VA_ARGS__)
279
280
#elif defined(CONFIG_CACHEFILES_DEBUG)
281
#define _enter(FMT, ...) \
282
do { \
283
if (cachefiles_debug & CACHEFILES_DEBUG_KENTER) \
284
kenter(FMT, ##__VA_ARGS__); \
285
} while (0)
286
287
#define _leave(FMT, ...) \
288
do { \
289
if (cachefiles_debug & CACHEFILES_DEBUG_KLEAVE) \
290
kleave(FMT, ##__VA_ARGS__); \
291
} while (0)
292
293
#define _debug(FMT, ...) \
294
do { \
295
if (cachefiles_debug & CACHEFILES_DEBUG_KDEBUG) \
296
kdebug(FMT, ##__VA_ARGS__); \
297
} while (0)
298
299
#else
300
#define _enter(FMT, ...) no_printk("==> %s("FMT")", __func__, ##__VA_ARGS__)
301
#define _leave(FMT, ...) no_printk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
302
#define _debug(FMT, ...) no_printk(FMT, ##__VA_ARGS__)
303
#endif
304
305
#if 1 /* defined(__KDEBUGALL) */
306
307
#define ASSERT(X) \
308
do { \
309
if (unlikely(!(X))) { \
310
printk(KERN_ERR "\n"); \
311
printk(KERN_ERR "CacheFiles: Assertion failed\n"); \
312
BUG(); \
313
} \
314
} while (0)
315
316
#define ASSERTCMP(X, OP, Y) \
317
do { \
318
if (unlikely(!((X) OP (Y)))) { \
319
printk(KERN_ERR "\n"); \
320
printk(KERN_ERR "CacheFiles: Assertion failed\n"); \
321
printk(KERN_ERR "%lx " #OP " %lx is false\n", \
322
(unsigned long)(X), (unsigned long)(Y)); \
323
BUG(); \
324
} \
325
} while (0)
326
327
#define ASSERTIF(C, X) \
328
do { \
329
if (unlikely((C) && !(X))) { \
330
printk(KERN_ERR "\n"); \
331
printk(KERN_ERR "CacheFiles: Assertion failed\n"); \
332
BUG(); \
333
} \
334
} while (0)
335
336
#define ASSERTIFCMP(C, X, OP, Y) \
337
do { \
338
if (unlikely((C) && !((X) OP (Y)))) { \
339
printk(KERN_ERR "\n"); \
340
printk(KERN_ERR "CacheFiles: Assertion failed\n"); \
341
printk(KERN_ERR "%lx " #OP " %lx is false\n", \
342
(unsigned long)(X), (unsigned long)(Y)); \
343
BUG(); \
344
} \
345
} while (0)
346
347
#else
348
349
#define ASSERT(X) do {} while (0)
350
#define ASSERTCMP(X, OP, Y) do {} while (0)
351
#define ASSERTIF(C, X) do {} while (0)
352
#define ASSERTIFCMP(C, X, OP, Y) do {} while (0)
353
354
#endif
355
356