Blame view

fs/cachefiles/internal.h 10.8 KB
b4d0d230c   Thomas Gleixner   treewide: Replace...
1
  /* SPDX-License-Identifier: GPL-2.0-or-later */
9ae326a69   David Howells   CacheFiles: A cac...
2
3
4
5
  /* General netfs cache on cache files internal defs
   *
   * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
   * Written by David Howells (dhowells@redhat.com)
9ae326a69   David Howells   CacheFiles: A cac...
6
   */
0227d6abb   Fabian Frederick   fs/cachefiles: re...
7
8
9
10
11
  #ifdef pr_fmt
  #undef pr_fmt
  #endif
  
  #define pr_fmt(fmt) "CacheFiles: " fmt
9ae326a69   David Howells   CacheFiles: A cac...
12
13
  #include <linux/fscache-cache.h>
  #include <linux/timer.h>
5dd43ce2f   Ingo Molnar   sched/wait: Split...
14
  #include <linux/wait_bit.h>
5b825c3af   Ingo Molnar   sched/headers: Pr...
15
  #include <linux/cred.h>
9ae326a69   David Howells   CacheFiles: A cac...
16
17
18
19
20
21
22
23
24
25
  #include <linux/workqueue.h>
  #include <linux/security.h>
  
  struct cachefiles_cache;
  struct cachefiles_object;
  
  extern unsigned cachefiles_debug;
  #define CACHEFILES_DEBUG_KENTER	1
  #define CACHEFILES_DEBUG_KLEAVE	2
  #define CACHEFILES_DEBUG_KDEBUG	4
71baba4b9   Mel Gorman   mm, page_alloc: r...
26
  #define cachefiles_gfp (__GFP_RECLAIM | __GFP_NORETRY | __GFP_NOMEMALLOC)
5f4f9f4af   David Howells   CacheFiles: Downg...
27

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