2021-11-26 14:32:29 +00:00
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* General netfs cache on cache files internal defs
*
* Copyright ( C ) 2021 Red Hat , Inc . All Rights Reserved .
* Written by David Howells ( dhowells @ redhat . com )
*/
# ifdef pr_fmt
# undef pr_fmt
# endif
# define pr_fmt(fmt) "CacheFiles: " fmt
# include <linux/fscache-cache.h>
# include <linux/cred.h>
# include <linux/security.h>
2021-11-26 14:45:38 +00:00
struct cachefiles_cache ;
struct cachefiles_object ;
/*
* Data file records .
*/
struct cachefiles_object {
int debug_id ; /* debugging ID */
} ;
/*
* Cache files cache definition
*/
struct cachefiles_cache {
2021-10-21 09:08:54 +01:00
struct fscache_cache * cache ; /* Cache cookie */
2021-11-26 14:45:38 +00:00
struct vfsmount * mnt ; /* mountpoint holding the cache */
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 */
atomic_t gravecounter ; /* graveyard uniquifier */
atomic_t f_released ; /* number of objects released lately */
atomic_long_t b_released ; /* number of blocks released lately */
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 */
} ;
2021-10-21 08:42:18 +01:00
# include <trace/events/cachefiles.h>
2021-11-26 14:32:29 +00:00
2021-11-26 15:12:07 +00:00
/*
* 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 ) ;
}
/*
* daemon . c
*/
extern const struct file_operations cachefiles_daemon_fops ;
2021-11-26 14:32:29 +00:00
/*
2021-10-21 08:15:26 +01:00
* error_inject . c
*/
# ifdef CONFIG_CACHEFILES_ERROR_INJECTION
extern unsigned int cachefiles_error_injection_state ;
extern int cachefiles_register_error_injection ( void ) ;
extern void cachefiles_unregister_error_injection ( void ) ;
# else
# define cachefiles_error_injection_state 0
static inline int cachefiles_register_error_injection ( void )
{
return 0 ;
}
static inline void cachefiles_unregister_error_injection ( void )
{
}
# endif
static inline int cachefiles_inject_read_error ( void )
{
return cachefiles_error_injection_state & 2 ? - EIO : 0 ;
}
static inline int cachefiles_inject_write_error ( void )
{
return cachefiles_error_injection_state & 2 ? - EIO :
cachefiles_error_injection_state & 1 ? - ENOSPC :
0 ;
}
static inline int cachefiles_inject_remove_error ( void )
{
return cachefiles_error_injection_state & 2 ? - EIO : 0 ;
}
2021-11-26 14:59:10 +00:00
/*
* security . c
*/
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 ) ;
}
2021-10-21 09:08:54 +01:00
/*
* Error handling
*/
# define cachefiles_io_error(___cache, FMT, ...) \
do { \
pr_err ( " I/O Error: " FMT " \n " , # # __VA_ARGS__ ) ; \
fscache_io_error ( ( ___cache ) - > cache ) ; \
set_bit ( CACHEFILES_DEAD , & ( ___cache ) - > flags ) ; \
} while ( 0 )
2021-10-21 08:15:26 +01:00
/*
* Debug tracing
2021-11-26 14:32:29 +00:00
*/
extern unsigned cachefiles_debug ;
# define CACHEFILES_DEBUG_KENTER 1
# define CACHEFILES_DEBUG_KLEAVE 2
# define CACHEFILES_DEBUG_KDEBUG 4
# define dbgprintk(FMT, ...) \
printk ( KERN_DEBUG " [%-6.6s] " FMT " \n " , current - > comm , # # __VA_ARGS__ )
# 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
# 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__)
# endif
# if 1 /* defined(__KDEBUGALL) */
# define ASSERT(X) \
do { \
if ( unlikely ( ! ( X ) ) ) { \
pr_err ( " \n " ) ; \
pr_err ( " Assertion failed \n " ) ; \
BUG ( ) ; \
} \
} while ( 0 )
# define ASSERTCMP(X, OP, Y) \
do { \
if ( unlikely ( ! ( ( X ) OP ( Y ) ) ) ) { \
pr_err ( " \n " ) ; \
pr_err ( " Assertion failed \n " ) ; \
pr_err ( " %lx " # OP " %lx is false \n " , \
( unsigned long ) ( X ) , ( unsigned long ) ( Y ) ) ; \
BUG ( ) ; \
} \
} while ( 0 )
# define ASSERTIF(C, X) \
do { \
if ( unlikely ( ( C ) & & ! ( X ) ) ) { \
pr_err ( " \n " ) ; \
pr_err ( " Assertion failed \n " ) ; \
BUG ( ) ; \
} \
} while ( 0 )
# define ASSERTIFCMP(C, X, OP, Y) \
do { \
if ( unlikely ( ( C ) & & ! ( ( X ) OP ( Y ) ) ) ) { \
pr_err ( " \n " ) ; \
pr_err ( " Assertion failed \n " ) ; \
pr_err ( " %lx " # OP " %lx is false \n " , \
( 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