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