18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/* General netfs cache on cache files internal defs
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
58c2ecf20Sopenharmony_ci * Written by David Howells (dhowells@redhat.com)
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#ifdef pr_fmt
98c2ecf20Sopenharmony_ci#undef pr_fmt
108c2ecf20Sopenharmony_ci#endif
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#define pr_fmt(fmt) "CacheFiles: " fmt
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#include <linux/fscache-cache.h>
168c2ecf20Sopenharmony_ci#include <linux/timer.h>
178c2ecf20Sopenharmony_ci#include <linux/wait_bit.h>
188c2ecf20Sopenharmony_ci#include <linux/cred.h>
198c2ecf20Sopenharmony_ci#include <linux/workqueue.h>
208c2ecf20Sopenharmony_ci#include <linux/security.h>
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_cistruct cachefiles_cache;
238c2ecf20Sopenharmony_cistruct cachefiles_object;
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ciextern unsigned cachefiles_debug;
268c2ecf20Sopenharmony_ci#define CACHEFILES_DEBUG_KENTER	1
278c2ecf20Sopenharmony_ci#define CACHEFILES_DEBUG_KLEAVE	2
288c2ecf20Sopenharmony_ci#define CACHEFILES_DEBUG_KDEBUG	4
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci#define cachefiles_gfp (__GFP_RECLAIM | __GFP_NORETRY | __GFP_NOMEMALLOC)
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci/*
338c2ecf20Sopenharmony_ci * node records
348c2ecf20Sopenharmony_ci */
358c2ecf20Sopenharmony_cistruct cachefiles_object {
368c2ecf20Sopenharmony_ci	struct fscache_object		fscache;	/* fscache handle */
378c2ecf20Sopenharmony_ci	struct cachefiles_lookup_data	*lookup_data;	/* cached lookup data */
388c2ecf20Sopenharmony_ci	struct dentry			*dentry;	/* the file/dir representing this object */
398c2ecf20Sopenharmony_ci	struct dentry			*backer;	/* backing file */
408c2ecf20Sopenharmony_ci	loff_t				i_size;		/* object size */
418c2ecf20Sopenharmony_ci	unsigned long			flags;
428c2ecf20Sopenharmony_ci#define CACHEFILES_OBJECT_ACTIVE	0		/* T if marked active */
438c2ecf20Sopenharmony_ci	atomic_t			usage;		/* object usage count */
448c2ecf20Sopenharmony_ci	uint8_t				type;		/* object type */
458c2ecf20Sopenharmony_ci	uint8_t				new;		/* T if object new */
468c2ecf20Sopenharmony_ci	spinlock_t			work_lock;
478c2ecf20Sopenharmony_ci	struct rb_node			active_node;	/* link in active tree (dentry is key) */
488c2ecf20Sopenharmony_ci};
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ciextern struct kmem_cache *cachefiles_object_jar;
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci/*
538c2ecf20Sopenharmony_ci * Cache files cache definition
548c2ecf20Sopenharmony_ci */
558c2ecf20Sopenharmony_cistruct cachefiles_cache {
568c2ecf20Sopenharmony_ci	struct fscache_cache		cache;		/* FS-Cache record */
578c2ecf20Sopenharmony_ci	struct vfsmount			*mnt;		/* mountpoint holding the cache */
588c2ecf20Sopenharmony_ci	struct dentry			*graveyard;	/* directory into which dead objects go */
598c2ecf20Sopenharmony_ci	struct file			*cachefilesd;	/* manager daemon handle */
608c2ecf20Sopenharmony_ci	const struct cred		*cache_cred;	/* security override for accessing cache */
618c2ecf20Sopenharmony_ci	struct mutex			daemon_mutex;	/* command serialisation mutex */
628c2ecf20Sopenharmony_ci	wait_queue_head_t		daemon_pollwq;	/* poll waitqueue for daemon */
638c2ecf20Sopenharmony_ci	struct rb_root			active_nodes;	/* active nodes (can't be culled) */
648c2ecf20Sopenharmony_ci	rwlock_t			active_lock;	/* lock for active_nodes */
658c2ecf20Sopenharmony_ci	atomic_t			gravecounter;	/* graveyard uniquifier */
668c2ecf20Sopenharmony_ci	atomic_t			f_released;	/* number of objects released lately */
678c2ecf20Sopenharmony_ci	atomic_long_t			b_released;	/* number of blocks released lately */
688c2ecf20Sopenharmony_ci	unsigned			frun_percent;	/* when to stop culling (% files) */
698c2ecf20Sopenharmony_ci	unsigned			fcull_percent;	/* when to start culling (% files) */
708c2ecf20Sopenharmony_ci	unsigned			fstop_percent;	/* when to stop allocating (% files) */
718c2ecf20Sopenharmony_ci	unsigned			brun_percent;	/* when to stop culling (% blocks) */
728c2ecf20Sopenharmony_ci	unsigned			bcull_percent;	/* when to start culling (% blocks) */
738c2ecf20Sopenharmony_ci	unsigned			bstop_percent;	/* when to stop allocating (% blocks) */
748c2ecf20Sopenharmony_ci	unsigned			bsize;		/* cache's block size */
758c2ecf20Sopenharmony_ci	unsigned			bshift;		/* min(ilog2(PAGE_SIZE / bsize), 0) */
768c2ecf20Sopenharmony_ci	uint64_t			frun;		/* when to stop culling */
778c2ecf20Sopenharmony_ci	uint64_t			fcull;		/* when to start culling */
788c2ecf20Sopenharmony_ci	uint64_t			fstop;		/* when to stop allocating */
798c2ecf20Sopenharmony_ci	sector_t			brun;		/* when to stop culling */
808c2ecf20Sopenharmony_ci	sector_t			bcull;		/* when to start culling */
818c2ecf20Sopenharmony_ci	sector_t			bstop;		/* when to stop allocating */
828c2ecf20Sopenharmony_ci	unsigned long			flags;
838c2ecf20Sopenharmony_ci#define CACHEFILES_READY		0	/* T if cache prepared */
848c2ecf20Sopenharmony_ci#define CACHEFILES_DEAD			1	/* T if cache dead */
858c2ecf20Sopenharmony_ci#define CACHEFILES_CULLING		2	/* T if cull engaged */
868c2ecf20Sopenharmony_ci#define CACHEFILES_STATE_CHANGED	3	/* T if state changed (poll trigger) */
878c2ecf20Sopenharmony_ci	char				*rootdirname;	/* name of cache root directory */
888c2ecf20Sopenharmony_ci	char				*secctx;	/* LSM security context */
898c2ecf20Sopenharmony_ci	char				*tag;		/* cache binding tag */
908c2ecf20Sopenharmony_ci};
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci/*
938c2ecf20Sopenharmony_ci * backing file read tracking
948c2ecf20Sopenharmony_ci */
958c2ecf20Sopenharmony_cistruct cachefiles_one_read {
968c2ecf20Sopenharmony_ci	wait_queue_entry_t			monitor;	/* link into monitored waitqueue */
978c2ecf20Sopenharmony_ci	struct page			*back_page;	/* backing file page we're waiting for */
988c2ecf20Sopenharmony_ci	struct page			*netfs_page;	/* netfs page we're going to fill */
998c2ecf20Sopenharmony_ci	struct fscache_retrieval	*op;		/* retrieval op covering this */
1008c2ecf20Sopenharmony_ci	struct list_head		op_link;	/* link in op's todo list */
1018c2ecf20Sopenharmony_ci};
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci/*
1048c2ecf20Sopenharmony_ci * backing file write tracking
1058c2ecf20Sopenharmony_ci */
1068c2ecf20Sopenharmony_cistruct cachefiles_one_write {
1078c2ecf20Sopenharmony_ci	struct page			*netfs_page;	/* netfs page to copy */
1088c2ecf20Sopenharmony_ci	struct cachefiles_object	*object;
1098c2ecf20Sopenharmony_ci	struct list_head		obj_link;	/* link in object's lists */
1108c2ecf20Sopenharmony_ci	fscache_rw_complete_t		end_io_func;
1118c2ecf20Sopenharmony_ci	void				*context;
1128c2ecf20Sopenharmony_ci};
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci/*
1158c2ecf20Sopenharmony_ci * auxiliary data xattr buffer
1168c2ecf20Sopenharmony_ci */
1178c2ecf20Sopenharmony_cistruct cachefiles_xattr {
1188c2ecf20Sopenharmony_ci	uint16_t			len;
1198c2ecf20Sopenharmony_ci	uint8_t				type;
1208c2ecf20Sopenharmony_ci	uint8_t				data[];
1218c2ecf20Sopenharmony_ci};
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci#include <trace/events/cachefiles.h>
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci/*
1268c2ecf20Sopenharmony_ci * note change of state for daemon
1278c2ecf20Sopenharmony_ci */
1288c2ecf20Sopenharmony_cistatic inline void cachefiles_state_changed(struct cachefiles_cache *cache)
1298c2ecf20Sopenharmony_ci{
1308c2ecf20Sopenharmony_ci	set_bit(CACHEFILES_STATE_CHANGED, &cache->flags);
1318c2ecf20Sopenharmony_ci	wake_up_all(&cache->daemon_pollwq);
1328c2ecf20Sopenharmony_ci}
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci/*
1358c2ecf20Sopenharmony_ci * bind.c
1368c2ecf20Sopenharmony_ci */
1378c2ecf20Sopenharmony_ciextern int cachefiles_daemon_bind(struct cachefiles_cache *cache, char *args);
1388c2ecf20Sopenharmony_ciextern void cachefiles_daemon_unbind(struct cachefiles_cache *cache);
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci/*
1418c2ecf20Sopenharmony_ci * daemon.c
1428c2ecf20Sopenharmony_ci */
1438c2ecf20Sopenharmony_ciextern const struct file_operations cachefiles_daemon_fops;
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ciextern int cachefiles_has_space(struct cachefiles_cache *cache,
1468c2ecf20Sopenharmony_ci				unsigned fnr, unsigned bnr);
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci/*
1498c2ecf20Sopenharmony_ci * interface.c
1508c2ecf20Sopenharmony_ci */
1518c2ecf20Sopenharmony_ciextern const struct fscache_cache_ops cachefiles_cache_ops;
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci/*
1548c2ecf20Sopenharmony_ci * key.c
1558c2ecf20Sopenharmony_ci */
1568c2ecf20Sopenharmony_ciextern char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type);
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci/*
1598c2ecf20Sopenharmony_ci * namei.c
1608c2ecf20Sopenharmony_ci */
1618c2ecf20Sopenharmony_ciextern void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
1628c2ecf20Sopenharmony_ci					    struct cachefiles_object *object,
1638c2ecf20Sopenharmony_ci					    blkcnt_t i_blocks);
1648c2ecf20Sopenharmony_ciextern int cachefiles_delete_object(struct cachefiles_cache *cache,
1658c2ecf20Sopenharmony_ci				    struct cachefiles_object *object);
1668c2ecf20Sopenharmony_ciextern int cachefiles_walk_to_object(struct cachefiles_object *parent,
1678c2ecf20Sopenharmony_ci				     struct cachefiles_object *object,
1688c2ecf20Sopenharmony_ci				     const char *key,
1698c2ecf20Sopenharmony_ci				     struct cachefiles_xattr *auxdata);
1708c2ecf20Sopenharmony_ciextern struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
1718c2ecf20Sopenharmony_ci					       struct dentry *dir,
1728c2ecf20Sopenharmony_ci					       const char *name);
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ciextern int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
1758c2ecf20Sopenharmony_ci			   char *filename);
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ciextern int cachefiles_check_in_use(struct cachefiles_cache *cache,
1788c2ecf20Sopenharmony_ci				   struct dentry *dir, char *filename);
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci/*
1818c2ecf20Sopenharmony_ci * proc.c
1828c2ecf20Sopenharmony_ci */
1838c2ecf20Sopenharmony_ci#ifdef CONFIG_CACHEFILES_HISTOGRAM
1848c2ecf20Sopenharmony_ciextern atomic_t cachefiles_lookup_histogram[HZ];
1858c2ecf20Sopenharmony_ciextern atomic_t cachefiles_mkdir_histogram[HZ];
1868c2ecf20Sopenharmony_ciextern atomic_t cachefiles_create_histogram[HZ];
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ciextern int __init cachefiles_proc_init(void);
1898c2ecf20Sopenharmony_ciextern void cachefiles_proc_cleanup(void);
1908c2ecf20Sopenharmony_cistatic inline
1918c2ecf20Sopenharmony_civoid cachefiles_hist(atomic_t histogram[], unsigned long start_jif)
1928c2ecf20Sopenharmony_ci{
1938c2ecf20Sopenharmony_ci	unsigned long jif = jiffies - start_jif;
1948c2ecf20Sopenharmony_ci	if (jif >= HZ)
1958c2ecf20Sopenharmony_ci		jif = HZ - 1;
1968c2ecf20Sopenharmony_ci	atomic_inc(&histogram[jif]);
1978c2ecf20Sopenharmony_ci}
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_ci#else
2008c2ecf20Sopenharmony_ci#define cachefiles_proc_init()		(0)
2018c2ecf20Sopenharmony_ci#define cachefiles_proc_cleanup()	do {} while (0)
2028c2ecf20Sopenharmony_ci#define cachefiles_hist(hist, start_jif) do {} while (0)
2038c2ecf20Sopenharmony_ci#endif
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ci/*
2068c2ecf20Sopenharmony_ci * rdwr.c
2078c2ecf20Sopenharmony_ci */
2088c2ecf20Sopenharmony_ciextern int cachefiles_read_or_alloc_page(struct fscache_retrieval *,
2098c2ecf20Sopenharmony_ci					 struct page *, gfp_t);
2108c2ecf20Sopenharmony_ciextern int cachefiles_read_or_alloc_pages(struct fscache_retrieval *,
2118c2ecf20Sopenharmony_ci					  struct list_head *, unsigned *,
2128c2ecf20Sopenharmony_ci					  gfp_t);
2138c2ecf20Sopenharmony_ciextern int cachefiles_allocate_page(struct fscache_retrieval *, struct page *,
2148c2ecf20Sopenharmony_ci				    gfp_t);
2158c2ecf20Sopenharmony_ciextern int cachefiles_allocate_pages(struct fscache_retrieval *,
2168c2ecf20Sopenharmony_ci				     struct list_head *, unsigned *, gfp_t);
2178c2ecf20Sopenharmony_ciextern int cachefiles_write_page(struct fscache_storage *, struct page *);
2188c2ecf20Sopenharmony_ciextern void cachefiles_uncache_page(struct fscache_object *, struct page *);
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ci/*
2218c2ecf20Sopenharmony_ci * security.c
2228c2ecf20Sopenharmony_ci */
2238c2ecf20Sopenharmony_ciextern int cachefiles_get_security_ID(struct cachefiles_cache *cache);
2248c2ecf20Sopenharmony_ciextern int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
2258c2ecf20Sopenharmony_ci					       struct dentry *root,
2268c2ecf20Sopenharmony_ci					       const struct cred **_saved_cred);
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_cistatic inline void cachefiles_begin_secure(struct cachefiles_cache *cache,
2298c2ecf20Sopenharmony_ci					   const struct cred **_saved_cred)
2308c2ecf20Sopenharmony_ci{
2318c2ecf20Sopenharmony_ci	*_saved_cred = override_creds(cache->cache_cred);
2328c2ecf20Sopenharmony_ci}
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_cistatic inline void cachefiles_end_secure(struct cachefiles_cache *cache,
2358c2ecf20Sopenharmony_ci					 const struct cred *saved_cred)
2368c2ecf20Sopenharmony_ci{
2378c2ecf20Sopenharmony_ci	revert_creds(saved_cred);
2388c2ecf20Sopenharmony_ci}
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_ci/*
2418c2ecf20Sopenharmony_ci * xattr.c
2428c2ecf20Sopenharmony_ci */
2438c2ecf20Sopenharmony_ciextern int cachefiles_check_object_type(struct cachefiles_object *object);
2448c2ecf20Sopenharmony_ciextern int cachefiles_set_object_xattr(struct cachefiles_object *object,
2458c2ecf20Sopenharmony_ci				       struct cachefiles_xattr *auxdata);
2468c2ecf20Sopenharmony_ciextern int cachefiles_update_object_xattr(struct cachefiles_object *object,
2478c2ecf20Sopenharmony_ci					  struct cachefiles_xattr *auxdata);
2488c2ecf20Sopenharmony_ciextern int cachefiles_check_auxdata(struct cachefiles_object *object);
2498c2ecf20Sopenharmony_ciextern int cachefiles_check_object_xattr(struct cachefiles_object *object,
2508c2ecf20Sopenharmony_ci					 struct cachefiles_xattr *auxdata);
2518c2ecf20Sopenharmony_ciextern int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
2528c2ecf20Sopenharmony_ci					  struct dentry *dentry);
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_ci/*
2568c2ecf20Sopenharmony_ci * error handling
2578c2ecf20Sopenharmony_ci */
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci#define cachefiles_io_error(___cache, FMT, ...)		\
2608c2ecf20Sopenharmony_cido {							\
2618c2ecf20Sopenharmony_ci	pr_err("I/O Error: " FMT"\n", ##__VA_ARGS__);	\
2628c2ecf20Sopenharmony_ci	fscache_io_error(&(___cache)->cache);		\
2638c2ecf20Sopenharmony_ci	set_bit(CACHEFILES_DEAD, &(___cache)->flags);	\
2648c2ecf20Sopenharmony_ci} while (0)
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_ci#define cachefiles_io_error_obj(object, FMT, ...)			\
2678c2ecf20Sopenharmony_cido {									\
2688c2ecf20Sopenharmony_ci	struct cachefiles_cache *___cache;				\
2698c2ecf20Sopenharmony_ci									\
2708c2ecf20Sopenharmony_ci	___cache = container_of((object)->fscache.cache,		\
2718c2ecf20Sopenharmony_ci				struct cachefiles_cache, cache);	\
2728c2ecf20Sopenharmony_ci	cachefiles_io_error(___cache, FMT, ##__VA_ARGS__);		\
2738c2ecf20Sopenharmony_ci} while (0)
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci/*
2778c2ecf20Sopenharmony_ci * debug tracing
2788c2ecf20Sopenharmony_ci */
2798c2ecf20Sopenharmony_ci#define dbgprintk(FMT, ...) \
2808c2ecf20Sopenharmony_ci	printk(KERN_DEBUG "[%-6.6s] "FMT"\n", current->comm, ##__VA_ARGS__)
2818c2ecf20Sopenharmony_ci
2828c2ecf20Sopenharmony_ci#define kenter(FMT, ...) dbgprintk("==> %s("FMT")", __func__, ##__VA_ARGS__)
2838c2ecf20Sopenharmony_ci#define kleave(FMT, ...) dbgprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
2848c2ecf20Sopenharmony_ci#define kdebug(FMT, ...) dbgprintk(FMT, ##__VA_ARGS__)
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ci
2878c2ecf20Sopenharmony_ci#if defined(__KDEBUG)
2888c2ecf20Sopenharmony_ci#define _enter(FMT, ...) kenter(FMT, ##__VA_ARGS__)
2898c2ecf20Sopenharmony_ci#define _leave(FMT, ...) kleave(FMT, ##__VA_ARGS__)
2908c2ecf20Sopenharmony_ci#define _debug(FMT, ...) kdebug(FMT, ##__VA_ARGS__)
2918c2ecf20Sopenharmony_ci
2928c2ecf20Sopenharmony_ci#elif defined(CONFIG_CACHEFILES_DEBUG)
2938c2ecf20Sopenharmony_ci#define _enter(FMT, ...)				\
2948c2ecf20Sopenharmony_cido {							\
2958c2ecf20Sopenharmony_ci	if (cachefiles_debug & CACHEFILES_DEBUG_KENTER)	\
2968c2ecf20Sopenharmony_ci		kenter(FMT, ##__VA_ARGS__);		\
2978c2ecf20Sopenharmony_ci} while (0)
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_ci#define _leave(FMT, ...)				\
3008c2ecf20Sopenharmony_cido {							\
3018c2ecf20Sopenharmony_ci	if (cachefiles_debug & CACHEFILES_DEBUG_KLEAVE)	\
3028c2ecf20Sopenharmony_ci		kleave(FMT, ##__VA_ARGS__);		\
3038c2ecf20Sopenharmony_ci} while (0)
3048c2ecf20Sopenharmony_ci
3058c2ecf20Sopenharmony_ci#define _debug(FMT, ...)				\
3068c2ecf20Sopenharmony_cido {							\
3078c2ecf20Sopenharmony_ci	if (cachefiles_debug & CACHEFILES_DEBUG_KDEBUG)	\
3088c2ecf20Sopenharmony_ci		kdebug(FMT, ##__VA_ARGS__);		\
3098c2ecf20Sopenharmony_ci} while (0)
3108c2ecf20Sopenharmony_ci
3118c2ecf20Sopenharmony_ci#else
3128c2ecf20Sopenharmony_ci#define _enter(FMT, ...) no_printk("==> %s("FMT")", __func__, ##__VA_ARGS__)
3138c2ecf20Sopenharmony_ci#define _leave(FMT, ...) no_printk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
3148c2ecf20Sopenharmony_ci#define _debug(FMT, ...) no_printk(FMT, ##__VA_ARGS__)
3158c2ecf20Sopenharmony_ci#endif
3168c2ecf20Sopenharmony_ci
3178c2ecf20Sopenharmony_ci#if 1 /* defined(__KDEBUGALL) */
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_ci#define ASSERT(X)							\
3208c2ecf20Sopenharmony_cido {									\
3218c2ecf20Sopenharmony_ci	if (unlikely(!(X))) {						\
3228c2ecf20Sopenharmony_ci		pr_err("\n");						\
3238c2ecf20Sopenharmony_ci		pr_err("Assertion failed\n");		\
3248c2ecf20Sopenharmony_ci		BUG();							\
3258c2ecf20Sopenharmony_ci	}								\
3268c2ecf20Sopenharmony_ci} while (0)
3278c2ecf20Sopenharmony_ci
3288c2ecf20Sopenharmony_ci#define ASSERTCMP(X, OP, Y)						\
3298c2ecf20Sopenharmony_cido {									\
3308c2ecf20Sopenharmony_ci	if (unlikely(!((X) OP (Y)))) {					\
3318c2ecf20Sopenharmony_ci		pr_err("\n");						\
3328c2ecf20Sopenharmony_ci		pr_err("Assertion failed\n");		\
3338c2ecf20Sopenharmony_ci		pr_err("%lx " #OP " %lx is false\n",			\
3348c2ecf20Sopenharmony_ci		       (unsigned long)(X), (unsigned long)(Y));		\
3358c2ecf20Sopenharmony_ci		BUG();							\
3368c2ecf20Sopenharmony_ci	}								\
3378c2ecf20Sopenharmony_ci} while (0)
3388c2ecf20Sopenharmony_ci
3398c2ecf20Sopenharmony_ci#define ASSERTIF(C, X)							\
3408c2ecf20Sopenharmony_cido {									\
3418c2ecf20Sopenharmony_ci	if (unlikely((C) && !(X))) {					\
3428c2ecf20Sopenharmony_ci		pr_err("\n");						\
3438c2ecf20Sopenharmony_ci		pr_err("Assertion failed\n");		\
3448c2ecf20Sopenharmony_ci		BUG();							\
3458c2ecf20Sopenharmony_ci	}								\
3468c2ecf20Sopenharmony_ci} while (0)
3478c2ecf20Sopenharmony_ci
3488c2ecf20Sopenharmony_ci#define ASSERTIFCMP(C, X, OP, Y)					\
3498c2ecf20Sopenharmony_cido {									\
3508c2ecf20Sopenharmony_ci	if (unlikely((C) && !((X) OP (Y)))) {				\
3518c2ecf20Sopenharmony_ci		pr_err("\n");						\
3528c2ecf20Sopenharmony_ci		pr_err("Assertion failed\n");		\
3538c2ecf20Sopenharmony_ci		pr_err("%lx " #OP " %lx is false\n",			\
3548c2ecf20Sopenharmony_ci		       (unsigned long)(X), (unsigned long)(Y));		\
3558c2ecf20Sopenharmony_ci		BUG();							\
3568c2ecf20Sopenharmony_ci	}								\
3578c2ecf20Sopenharmony_ci} while (0)
3588c2ecf20Sopenharmony_ci
3598c2ecf20Sopenharmony_ci#else
3608c2ecf20Sopenharmony_ci
3618c2ecf20Sopenharmony_ci#define ASSERT(X)			do {} while (0)
3628c2ecf20Sopenharmony_ci#define ASSERTCMP(X, OP, Y)		do {} while (0)
3638c2ecf20Sopenharmony_ci#define ASSERTIF(C, X)			do {} while (0)
3648c2ecf20Sopenharmony_ci#define ASSERTIFCMP(C, X, OP, Y)	do {} while (0)
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_ci#endif
367