162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* General netfs cache on cache files internal defs 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved. 562306a36Sopenharmony_ci * Written by David Howells (dhowells@redhat.com) 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#ifdef pr_fmt 962306a36Sopenharmony_ci#undef pr_fmt 1062306a36Sopenharmony_ci#endif 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#define pr_fmt(fmt) "CacheFiles: " fmt 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include <linux/fscache-cache.h> 1662306a36Sopenharmony_ci#include <linux/cred.h> 1762306a36Sopenharmony_ci#include <linux/security.h> 1862306a36Sopenharmony_ci#include <linux/xarray.h> 1962306a36Sopenharmony_ci#include <linux/cachefiles.h> 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#define CACHEFILES_DIO_BLOCK_SIZE 4096 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cistruct cachefiles_cache; 2462306a36Sopenharmony_cistruct cachefiles_object; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_cienum cachefiles_content { 2762306a36Sopenharmony_ci /* These values are saved on disk */ 2862306a36Sopenharmony_ci CACHEFILES_CONTENT_NO_DATA = 0, /* No content stored */ 2962306a36Sopenharmony_ci CACHEFILES_CONTENT_SINGLE = 1, /* Content is monolithic, all is present */ 3062306a36Sopenharmony_ci CACHEFILES_CONTENT_ALL = 2, /* Content is all present, no map */ 3162306a36Sopenharmony_ci CACHEFILES_CONTENT_BACKFS_MAP = 3, /* Content is piecemeal, mapped through backing fs */ 3262306a36Sopenharmony_ci CACHEFILES_CONTENT_DIRTY = 4, /* Content is dirty (only seen on disk) */ 3362306a36Sopenharmony_ci nr__cachefiles_content 3462306a36Sopenharmony_ci}; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci/* 3762306a36Sopenharmony_ci * Cached volume representation. 3862306a36Sopenharmony_ci */ 3962306a36Sopenharmony_cistruct cachefiles_volume { 4062306a36Sopenharmony_ci struct cachefiles_cache *cache; 4162306a36Sopenharmony_ci struct list_head cache_link; /* Link in cache->volumes */ 4262306a36Sopenharmony_ci struct fscache_volume *vcookie; /* The netfs's representation */ 4362306a36Sopenharmony_ci struct dentry *dentry; /* The volume dentry */ 4462306a36Sopenharmony_ci struct dentry *fanout[256]; /* Fanout subdirs */ 4562306a36Sopenharmony_ci}; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci/* 4862306a36Sopenharmony_ci * Backing file state. 4962306a36Sopenharmony_ci */ 5062306a36Sopenharmony_cistruct cachefiles_object { 5162306a36Sopenharmony_ci struct fscache_cookie *cookie; /* Netfs data storage object cookie */ 5262306a36Sopenharmony_ci struct cachefiles_volume *volume; /* Cache volume that holds this object */ 5362306a36Sopenharmony_ci struct list_head cache_link; /* Link in cache->*_list */ 5462306a36Sopenharmony_ci struct file *file; /* The file representing this object */ 5562306a36Sopenharmony_ci char *d_name; /* Backing file name */ 5662306a36Sopenharmony_ci int debug_id; 5762306a36Sopenharmony_ci spinlock_t lock; 5862306a36Sopenharmony_ci refcount_t ref; 5962306a36Sopenharmony_ci u8 d_name_len; /* Length of filename */ 6062306a36Sopenharmony_ci enum cachefiles_content content_info:8; /* Info about content presence */ 6162306a36Sopenharmony_ci unsigned long flags; 6262306a36Sopenharmony_ci#define CACHEFILES_OBJECT_USING_TMPFILE 0 /* Have an unlinked tmpfile */ 6362306a36Sopenharmony_ci#ifdef CONFIG_CACHEFILES_ONDEMAND 6462306a36Sopenharmony_ci int ondemand_id; 6562306a36Sopenharmony_ci#endif 6662306a36Sopenharmony_ci}; 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci#define CACHEFILES_ONDEMAND_ID_CLOSED -1 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci/* 7162306a36Sopenharmony_ci * Cache files cache definition 7262306a36Sopenharmony_ci */ 7362306a36Sopenharmony_cistruct cachefiles_cache { 7462306a36Sopenharmony_ci struct fscache_cache *cache; /* Cache cookie */ 7562306a36Sopenharmony_ci struct vfsmount *mnt; /* mountpoint holding the cache */ 7662306a36Sopenharmony_ci struct dentry *store; /* Directory into which live objects go */ 7762306a36Sopenharmony_ci struct dentry *graveyard; /* directory into which dead objects go */ 7862306a36Sopenharmony_ci struct file *cachefilesd; /* manager daemon handle */ 7962306a36Sopenharmony_ci struct list_head volumes; /* List of volume objects */ 8062306a36Sopenharmony_ci struct list_head object_list; /* List of active objects */ 8162306a36Sopenharmony_ci spinlock_t object_list_lock; /* Lock for volumes and object_list */ 8262306a36Sopenharmony_ci const struct cred *cache_cred; /* security override for accessing cache */ 8362306a36Sopenharmony_ci struct mutex daemon_mutex; /* command serialisation mutex */ 8462306a36Sopenharmony_ci wait_queue_head_t daemon_pollwq; /* poll waitqueue for daemon */ 8562306a36Sopenharmony_ci atomic_t gravecounter; /* graveyard uniquifier */ 8662306a36Sopenharmony_ci atomic_t f_released; /* number of objects released lately */ 8762306a36Sopenharmony_ci atomic_long_t b_released; /* number of blocks released lately */ 8862306a36Sopenharmony_ci atomic_long_t b_writing; /* Number of blocks being written */ 8962306a36Sopenharmony_ci unsigned frun_percent; /* when to stop culling (% files) */ 9062306a36Sopenharmony_ci unsigned fcull_percent; /* when to start culling (% files) */ 9162306a36Sopenharmony_ci unsigned fstop_percent; /* when to stop allocating (% files) */ 9262306a36Sopenharmony_ci unsigned brun_percent; /* when to stop culling (% blocks) */ 9362306a36Sopenharmony_ci unsigned bcull_percent; /* when to start culling (% blocks) */ 9462306a36Sopenharmony_ci unsigned bstop_percent; /* when to stop allocating (% blocks) */ 9562306a36Sopenharmony_ci unsigned bsize; /* cache's block size */ 9662306a36Sopenharmony_ci unsigned bshift; /* ilog2(bsize) */ 9762306a36Sopenharmony_ci uint64_t frun; /* when to stop culling */ 9862306a36Sopenharmony_ci uint64_t fcull; /* when to start culling */ 9962306a36Sopenharmony_ci uint64_t fstop; /* when to stop allocating */ 10062306a36Sopenharmony_ci sector_t brun; /* when to stop culling */ 10162306a36Sopenharmony_ci sector_t bcull; /* when to start culling */ 10262306a36Sopenharmony_ci sector_t bstop; /* when to stop allocating */ 10362306a36Sopenharmony_ci unsigned long flags; 10462306a36Sopenharmony_ci#define CACHEFILES_READY 0 /* T if cache prepared */ 10562306a36Sopenharmony_ci#define CACHEFILES_DEAD 1 /* T if cache dead */ 10662306a36Sopenharmony_ci#define CACHEFILES_CULLING 2 /* T if cull engaged */ 10762306a36Sopenharmony_ci#define CACHEFILES_STATE_CHANGED 3 /* T if state changed (poll trigger) */ 10862306a36Sopenharmony_ci#define CACHEFILES_ONDEMAND_MODE 4 /* T if in on-demand read mode */ 10962306a36Sopenharmony_ci char *rootdirname; /* name of cache root directory */ 11062306a36Sopenharmony_ci char *secctx; /* LSM security context */ 11162306a36Sopenharmony_ci char *tag; /* cache binding tag */ 11262306a36Sopenharmony_ci refcount_t unbind_pincount;/* refcount to do daemon unbind */ 11362306a36Sopenharmony_ci struct xarray reqs; /* xarray of pending on-demand requests */ 11462306a36Sopenharmony_ci unsigned long req_id_next; 11562306a36Sopenharmony_ci struct xarray ondemand_ids; /* xarray for ondemand_id allocation */ 11662306a36Sopenharmony_ci u32 ondemand_id_next; 11762306a36Sopenharmony_ci}; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_cistatic inline bool cachefiles_in_ondemand_mode(struct cachefiles_cache *cache) 12062306a36Sopenharmony_ci{ 12162306a36Sopenharmony_ci return IS_ENABLED(CONFIG_CACHEFILES_ONDEMAND) && 12262306a36Sopenharmony_ci test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags); 12362306a36Sopenharmony_ci} 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_cistruct cachefiles_req { 12662306a36Sopenharmony_ci struct cachefiles_object *object; 12762306a36Sopenharmony_ci struct completion done; 12862306a36Sopenharmony_ci int error; 12962306a36Sopenharmony_ci struct cachefiles_msg msg; 13062306a36Sopenharmony_ci}; 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci#define CACHEFILES_REQ_NEW XA_MARK_1 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci#include <trace/events/cachefiles.h> 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_cistatic inline 13762306a36Sopenharmony_cistruct file *cachefiles_cres_file(struct netfs_cache_resources *cres) 13862306a36Sopenharmony_ci{ 13962306a36Sopenharmony_ci return cres->cache_priv2; 14062306a36Sopenharmony_ci} 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_cistatic inline 14362306a36Sopenharmony_cistruct cachefiles_object *cachefiles_cres_object(struct netfs_cache_resources *cres) 14462306a36Sopenharmony_ci{ 14562306a36Sopenharmony_ci return fscache_cres_cookie(cres)->cache_priv; 14662306a36Sopenharmony_ci} 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci/* 14962306a36Sopenharmony_ci * note change of state for daemon 15062306a36Sopenharmony_ci */ 15162306a36Sopenharmony_cistatic inline void cachefiles_state_changed(struct cachefiles_cache *cache) 15262306a36Sopenharmony_ci{ 15362306a36Sopenharmony_ci set_bit(CACHEFILES_STATE_CHANGED, &cache->flags); 15462306a36Sopenharmony_ci wake_up_all(&cache->daemon_pollwq); 15562306a36Sopenharmony_ci} 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci/* 15862306a36Sopenharmony_ci * cache.c 15962306a36Sopenharmony_ci */ 16062306a36Sopenharmony_ciextern int cachefiles_add_cache(struct cachefiles_cache *cache); 16162306a36Sopenharmony_ciextern void cachefiles_withdraw_cache(struct cachefiles_cache *cache); 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_cienum cachefiles_has_space_for { 16462306a36Sopenharmony_ci cachefiles_has_space_check, 16562306a36Sopenharmony_ci cachefiles_has_space_for_write, 16662306a36Sopenharmony_ci cachefiles_has_space_for_create, 16762306a36Sopenharmony_ci}; 16862306a36Sopenharmony_ciextern int cachefiles_has_space(struct cachefiles_cache *cache, 16962306a36Sopenharmony_ci unsigned fnr, unsigned bnr, 17062306a36Sopenharmony_ci enum cachefiles_has_space_for reason); 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci/* 17362306a36Sopenharmony_ci * daemon.c 17462306a36Sopenharmony_ci */ 17562306a36Sopenharmony_ciextern const struct file_operations cachefiles_daemon_fops; 17662306a36Sopenharmony_ciextern void cachefiles_get_unbind_pincount(struct cachefiles_cache *cache); 17762306a36Sopenharmony_ciextern void cachefiles_put_unbind_pincount(struct cachefiles_cache *cache); 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci/* 18062306a36Sopenharmony_ci * error_inject.c 18162306a36Sopenharmony_ci */ 18262306a36Sopenharmony_ci#ifdef CONFIG_CACHEFILES_ERROR_INJECTION 18362306a36Sopenharmony_ciextern unsigned int cachefiles_error_injection_state; 18462306a36Sopenharmony_ciextern int cachefiles_register_error_injection(void); 18562306a36Sopenharmony_ciextern void cachefiles_unregister_error_injection(void); 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci#else 18862306a36Sopenharmony_ci#define cachefiles_error_injection_state 0 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_cistatic inline int cachefiles_register_error_injection(void) 19162306a36Sopenharmony_ci{ 19262306a36Sopenharmony_ci return 0; 19362306a36Sopenharmony_ci} 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_cistatic inline void cachefiles_unregister_error_injection(void) 19662306a36Sopenharmony_ci{ 19762306a36Sopenharmony_ci} 19862306a36Sopenharmony_ci#endif 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_cistatic inline int cachefiles_inject_read_error(void) 20262306a36Sopenharmony_ci{ 20362306a36Sopenharmony_ci return cachefiles_error_injection_state & 2 ? -EIO : 0; 20462306a36Sopenharmony_ci} 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_cistatic inline int cachefiles_inject_write_error(void) 20762306a36Sopenharmony_ci{ 20862306a36Sopenharmony_ci return cachefiles_error_injection_state & 2 ? -EIO : 20962306a36Sopenharmony_ci cachefiles_error_injection_state & 1 ? -ENOSPC : 21062306a36Sopenharmony_ci 0; 21162306a36Sopenharmony_ci} 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_cistatic inline int cachefiles_inject_remove_error(void) 21462306a36Sopenharmony_ci{ 21562306a36Sopenharmony_ci return cachefiles_error_injection_state & 2 ? -EIO : 0; 21662306a36Sopenharmony_ci} 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci/* 21962306a36Sopenharmony_ci * interface.c 22062306a36Sopenharmony_ci */ 22162306a36Sopenharmony_ciextern const struct fscache_cache_ops cachefiles_cache_ops; 22262306a36Sopenharmony_ciextern void cachefiles_see_object(struct cachefiles_object *object, 22362306a36Sopenharmony_ci enum cachefiles_obj_ref_trace why); 22462306a36Sopenharmony_ciextern struct cachefiles_object *cachefiles_grab_object(struct cachefiles_object *object, 22562306a36Sopenharmony_ci enum cachefiles_obj_ref_trace why); 22662306a36Sopenharmony_ciextern void cachefiles_put_object(struct cachefiles_object *object, 22762306a36Sopenharmony_ci enum cachefiles_obj_ref_trace why); 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci/* 23062306a36Sopenharmony_ci * io.c 23162306a36Sopenharmony_ci */ 23262306a36Sopenharmony_ciextern bool cachefiles_begin_operation(struct netfs_cache_resources *cres, 23362306a36Sopenharmony_ci enum fscache_want_state want_state); 23462306a36Sopenharmony_ciextern int __cachefiles_prepare_write(struct cachefiles_object *object, 23562306a36Sopenharmony_ci struct file *file, 23662306a36Sopenharmony_ci loff_t *_start, size_t *_len, 23762306a36Sopenharmony_ci bool no_space_allocated_yet); 23862306a36Sopenharmony_ciextern int __cachefiles_write(struct cachefiles_object *object, 23962306a36Sopenharmony_ci struct file *file, 24062306a36Sopenharmony_ci loff_t start_pos, 24162306a36Sopenharmony_ci struct iov_iter *iter, 24262306a36Sopenharmony_ci netfs_io_terminated_t term_func, 24362306a36Sopenharmony_ci void *term_func_priv); 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci/* 24662306a36Sopenharmony_ci * key.c 24762306a36Sopenharmony_ci */ 24862306a36Sopenharmony_ciextern bool cachefiles_cook_key(struct cachefiles_object *object); 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci/* 25162306a36Sopenharmony_ci * main.c 25262306a36Sopenharmony_ci */ 25362306a36Sopenharmony_ciextern struct kmem_cache *cachefiles_object_jar; 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci/* 25662306a36Sopenharmony_ci * namei.c 25762306a36Sopenharmony_ci */ 25862306a36Sopenharmony_ciextern void cachefiles_unmark_inode_in_use(struct cachefiles_object *object, 25962306a36Sopenharmony_ci struct file *file); 26062306a36Sopenharmony_ciextern int cachefiles_bury_object(struct cachefiles_cache *cache, 26162306a36Sopenharmony_ci struct cachefiles_object *object, 26262306a36Sopenharmony_ci struct dentry *dir, 26362306a36Sopenharmony_ci struct dentry *rep, 26462306a36Sopenharmony_ci enum fscache_why_object_killed why); 26562306a36Sopenharmony_ciextern int cachefiles_delete_object(struct cachefiles_object *object, 26662306a36Sopenharmony_ci enum fscache_why_object_killed why); 26762306a36Sopenharmony_ciextern bool cachefiles_look_up_object(struct cachefiles_object *object); 26862306a36Sopenharmony_ciextern struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, 26962306a36Sopenharmony_ci struct dentry *dir, 27062306a36Sopenharmony_ci const char *name, 27162306a36Sopenharmony_ci bool *_is_new); 27262306a36Sopenharmony_ciextern void cachefiles_put_directory(struct dentry *dir); 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ciextern int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir, 27562306a36Sopenharmony_ci char *filename); 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ciextern int cachefiles_check_in_use(struct cachefiles_cache *cache, 27862306a36Sopenharmony_ci struct dentry *dir, char *filename); 27962306a36Sopenharmony_ciextern struct file *cachefiles_create_tmpfile(struct cachefiles_object *object); 28062306a36Sopenharmony_ciextern bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache, 28162306a36Sopenharmony_ci struct cachefiles_object *object); 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci/* 28462306a36Sopenharmony_ci * ondemand.c 28562306a36Sopenharmony_ci */ 28662306a36Sopenharmony_ci#ifdef CONFIG_CACHEFILES_ONDEMAND 28762306a36Sopenharmony_ciextern ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache, 28862306a36Sopenharmony_ci char __user *_buffer, size_t buflen); 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ciextern int cachefiles_ondemand_copen(struct cachefiles_cache *cache, 29162306a36Sopenharmony_ci char *args); 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ciextern int cachefiles_ondemand_init_object(struct cachefiles_object *object); 29462306a36Sopenharmony_ciextern void cachefiles_ondemand_clean_object(struct cachefiles_object *object); 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ciextern int cachefiles_ondemand_read(struct cachefiles_object *object, 29762306a36Sopenharmony_ci loff_t pos, size_t len); 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci#else 30062306a36Sopenharmony_cistatic inline ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache, 30162306a36Sopenharmony_ci char __user *_buffer, size_t buflen) 30262306a36Sopenharmony_ci{ 30362306a36Sopenharmony_ci return -EOPNOTSUPP; 30462306a36Sopenharmony_ci} 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_cistatic inline int cachefiles_ondemand_init_object(struct cachefiles_object *object) 30762306a36Sopenharmony_ci{ 30862306a36Sopenharmony_ci return 0; 30962306a36Sopenharmony_ci} 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_cistatic inline void cachefiles_ondemand_clean_object(struct cachefiles_object *object) 31262306a36Sopenharmony_ci{ 31362306a36Sopenharmony_ci} 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_cistatic inline int cachefiles_ondemand_read(struct cachefiles_object *object, 31662306a36Sopenharmony_ci loff_t pos, size_t len) 31762306a36Sopenharmony_ci{ 31862306a36Sopenharmony_ci return -EOPNOTSUPP; 31962306a36Sopenharmony_ci} 32062306a36Sopenharmony_ci#endif 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci/* 32362306a36Sopenharmony_ci * security.c 32462306a36Sopenharmony_ci */ 32562306a36Sopenharmony_ciextern int cachefiles_get_security_ID(struct cachefiles_cache *cache); 32662306a36Sopenharmony_ciextern int cachefiles_determine_cache_security(struct cachefiles_cache *cache, 32762306a36Sopenharmony_ci struct dentry *root, 32862306a36Sopenharmony_ci const struct cred **_saved_cred); 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_cistatic inline void cachefiles_begin_secure(struct cachefiles_cache *cache, 33162306a36Sopenharmony_ci const struct cred **_saved_cred) 33262306a36Sopenharmony_ci{ 33362306a36Sopenharmony_ci *_saved_cred = override_creds(cache->cache_cred); 33462306a36Sopenharmony_ci} 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_cistatic inline void cachefiles_end_secure(struct cachefiles_cache *cache, 33762306a36Sopenharmony_ci const struct cred *saved_cred) 33862306a36Sopenharmony_ci{ 33962306a36Sopenharmony_ci revert_creds(saved_cred); 34062306a36Sopenharmony_ci} 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci/* 34362306a36Sopenharmony_ci * volume.c 34462306a36Sopenharmony_ci */ 34562306a36Sopenharmony_civoid cachefiles_acquire_volume(struct fscache_volume *volume); 34662306a36Sopenharmony_civoid cachefiles_free_volume(struct fscache_volume *volume); 34762306a36Sopenharmony_civoid cachefiles_withdraw_volume(struct cachefiles_volume *volume); 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci/* 35062306a36Sopenharmony_ci * xattr.c 35162306a36Sopenharmony_ci */ 35262306a36Sopenharmony_ciextern int cachefiles_set_object_xattr(struct cachefiles_object *object); 35362306a36Sopenharmony_ciextern int cachefiles_check_auxdata(struct cachefiles_object *object, 35462306a36Sopenharmony_ci struct file *file); 35562306a36Sopenharmony_ciextern int cachefiles_remove_object_xattr(struct cachefiles_cache *cache, 35662306a36Sopenharmony_ci struct cachefiles_object *object, 35762306a36Sopenharmony_ci struct dentry *dentry); 35862306a36Sopenharmony_ciextern void cachefiles_prepare_to_write(struct fscache_cookie *cookie); 35962306a36Sopenharmony_ciextern bool cachefiles_set_volume_xattr(struct cachefiles_volume *volume); 36062306a36Sopenharmony_ciextern int cachefiles_check_volume_xattr(struct cachefiles_volume *volume); 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci/* 36362306a36Sopenharmony_ci * Error handling 36462306a36Sopenharmony_ci */ 36562306a36Sopenharmony_ci#define cachefiles_io_error(___cache, FMT, ...) \ 36662306a36Sopenharmony_cido { \ 36762306a36Sopenharmony_ci pr_err("I/O Error: " FMT"\n", ##__VA_ARGS__); \ 36862306a36Sopenharmony_ci fscache_io_error((___cache)->cache); \ 36962306a36Sopenharmony_ci set_bit(CACHEFILES_DEAD, &(___cache)->flags); \ 37062306a36Sopenharmony_ci} while (0) 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci#define cachefiles_io_error_obj(object, FMT, ...) \ 37362306a36Sopenharmony_cido { \ 37462306a36Sopenharmony_ci struct cachefiles_cache *___cache; \ 37562306a36Sopenharmony_ci \ 37662306a36Sopenharmony_ci ___cache = (object)->volume->cache; \ 37762306a36Sopenharmony_ci cachefiles_io_error(___cache, FMT " [o=%08x]", ##__VA_ARGS__, \ 37862306a36Sopenharmony_ci (object)->debug_id); \ 37962306a36Sopenharmony_ci} while (0) 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci/* 38362306a36Sopenharmony_ci * Debug tracing 38462306a36Sopenharmony_ci */ 38562306a36Sopenharmony_ciextern unsigned cachefiles_debug; 38662306a36Sopenharmony_ci#define CACHEFILES_DEBUG_KENTER 1 38762306a36Sopenharmony_ci#define CACHEFILES_DEBUG_KLEAVE 2 38862306a36Sopenharmony_ci#define CACHEFILES_DEBUG_KDEBUG 4 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci#define dbgprintk(FMT, ...) \ 39162306a36Sopenharmony_ci printk(KERN_DEBUG "[%-6.6s] "FMT"\n", current->comm, ##__VA_ARGS__) 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci#define kenter(FMT, ...) dbgprintk("==> %s("FMT")", __func__, ##__VA_ARGS__) 39462306a36Sopenharmony_ci#define kleave(FMT, ...) dbgprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__) 39562306a36Sopenharmony_ci#define kdebug(FMT, ...) dbgprintk(FMT, ##__VA_ARGS__) 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci#if defined(__KDEBUG) 39962306a36Sopenharmony_ci#define _enter(FMT, ...) kenter(FMT, ##__VA_ARGS__) 40062306a36Sopenharmony_ci#define _leave(FMT, ...) kleave(FMT, ##__VA_ARGS__) 40162306a36Sopenharmony_ci#define _debug(FMT, ...) kdebug(FMT, ##__VA_ARGS__) 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci#elif defined(CONFIG_CACHEFILES_DEBUG) 40462306a36Sopenharmony_ci#define _enter(FMT, ...) \ 40562306a36Sopenharmony_cido { \ 40662306a36Sopenharmony_ci if (cachefiles_debug & CACHEFILES_DEBUG_KENTER) \ 40762306a36Sopenharmony_ci kenter(FMT, ##__VA_ARGS__); \ 40862306a36Sopenharmony_ci} while (0) 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ci#define _leave(FMT, ...) \ 41162306a36Sopenharmony_cido { \ 41262306a36Sopenharmony_ci if (cachefiles_debug & CACHEFILES_DEBUG_KLEAVE) \ 41362306a36Sopenharmony_ci kleave(FMT, ##__VA_ARGS__); \ 41462306a36Sopenharmony_ci} while (0) 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci#define _debug(FMT, ...) \ 41762306a36Sopenharmony_cido { \ 41862306a36Sopenharmony_ci if (cachefiles_debug & CACHEFILES_DEBUG_KDEBUG) \ 41962306a36Sopenharmony_ci kdebug(FMT, ##__VA_ARGS__); \ 42062306a36Sopenharmony_ci} while (0) 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci#else 42362306a36Sopenharmony_ci#define _enter(FMT, ...) no_printk("==> %s("FMT")", __func__, ##__VA_ARGS__) 42462306a36Sopenharmony_ci#define _leave(FMT, ...) no_printk("<== %s()"FMT"", __func__, ##__VA_ARGS__) 42562306a36Sopenharmony_ci#define _debug(FMT, ...) no_printk(FMT, ##__VA_ARGS__) 42662306a36Sopenharmony_ci#endif 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ci#if 1 /* defined(__KDEBUGALL) */ 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci#define ASSERT(X) \ 43162306a36Sopenharmony_cido { \ 43262306a36Sopenharmony_ci if (unlikely(!(X))) { \ 43362306a36Sopenharmony_ci pr_err("\n"); \ 43462306a36Sopenharmony_ci pr_err("Assertion failed\n"); \ 43562306a36Sopenharmony_ci BUG(); \ 43662306a36Sopenharmony_ci } \ 43762306a36Sopenharmony_ci} while (0) 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci#define ASSERTCMP(X, OP, Y) \ 44062306a36Sopenharmony_cido { \ 44162306a36Sopenharmony_ci if (unlikely(!((X) OP (Y)))) { \ 44262306a36Sopenharmony_ci pr_err("\n"); \ 44362306a36Sopenharmony_ci pr_err("Assertion failed\n"); \ 44462306a36Sopenharmony_ci pr_err("%lx " #OP " %lx is false\n", \ 44562306a36Sopenharmony_ci (unsigned long)(X), (unsigned long)(Y)); \ 44662306a36Sopenharmony_ci BUG(); \ 44762306a36Sopenharmony_ci } \ 44862306a36Sopenharmony_ci} while (0) 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci#define ASSERTIF(C, X) \ 45162306a36Sopenharmony_cido { \ 45262306a36Sopenharmony_ci if (unlikely((C) && !(X))) { \ 45362306a36Sopenharmony_ci pr_err("\n"); \ 45462306a36Sopenharmony_ci pr_err("Assertion failed\n"); \ 45562306a36Sopenharmony_ci BUG(); \ 45662306a36Sopenharmony_ci } \ 45762306a36Sopenharmony_ci} while (0) 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci#define ASSERTIFCMP(C, X, OP, Y) \ 46062306a36Sopenharmony_cido { \ 46162306a36Sopenharmony_ci if (unlikely((C) && !((X) OP (Y)))) { \ 46262306a36Sopenharmony_ci pr_err("\n"); \ 46362306a36Sopenharmony_ci pr_err("Assertion failed\n"); \ 46462306a36Sopenharmony_ci pr_err("%lx " #OP " %lx is false\n", \ 46562306a36Sopenharmony_ci (unsigned long)(X), (unsigned long)(Y)); \ 46662306a36Sopenharmony_ci BUG(); \ 46762306a36Sopenharmony_ci } \ 46862306a36Sopenharmony_ci} while (0) 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ci#else 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci#define ASSERT(X) do {} while (0) 47362306a36Sopenharmony_ci#define ASSERTCMP(X, OP, Y) do {} while (0) 47462306a36Sopenharmony_ci#define ASSERTIF(C, X) do {} while (0) 47562306a36Sopenharmony_ci#define ASSERTIFCMP(C, X, OP, Y) do {} while (0) 47662306a36Sopenharmony_ci 47762306a36Sopenharmony_ci#endif 478