@ -69,24 +69,40 @@ static match_table_t f2fs_tokens = {
} ;
/* Sysfs support for f2fs */
enum {
GC_THREAD , /* struct f2fs_gc_thread */
SM_INFO , /* struct f2fs_sm_info */
} ;
struct f2fs_attr {
struct attribute attr ;
ssize_t ( * show ) ( struct f2fs_attr * , struct f2fs_sb_info * , char * ) ;
ssize_t ( * store ) ( struct f2fs_attr * , struct f2fs_sb_info * ,
const char * , size_t ) ;
int struct_type ;
int offset ;
} ;
static unsigned char * __struct_ptr ( struct f2fs_sb_info * sbi , int struct_type )
{
if ( struct_type = = GC_THREAD )
return ( unsigned char * ) sbi - > gc_thread ;
else if ( struct_type = = SM_INFO )
return ( unsigned char * ) SM_I ( sbi ) ;
return NULL ;
}
static ssize_t f2fs_sbi_show ( struct f2fs_attr * a ,
struct f2fs_sb_info * sbi , char * buf )
{
struct f2fs_gc_kthread * gc_kth = sbi - > gc_thread ;
unsigned char * ptr = NULL ;
unsigned int * ui ;
if ( ! gc_kth )
ptr = __struct_ptr ( sbi , a - > struct_type ) ;
if ( ! ptr )
return - EINVAL ;
ui = ( unsigned int * ) ( ( ( cha r * ) gc_kth ) + a - > offset ) ;
ui = ( unsigned int * ) ( pt r + a - > offset ) ;
return snprintf ( buf , PAGE_SIZE , " %u \n " , * ui ) ;
}
@ -95,15 +111,16 @@ static ssize_t f2fs_sbi_store(struct f2fs_attr *a,
struct f2fs_sb_info * sbi ,
const char * buf , size_t count )
{
struct f2fs_gc_kthread * gc_kth = sbi - > gc_thread ;
unsigned char * ptr ;
unsigned long t ;
unsigned int * ui ;
ssize_t ret ;
if ( ! gc_kth )
ptr = __struct_ptr ( sbi , a - > struct_type ) ;
if ( ! ptr )
return - EINVAL ;
ui = ( unsigned int * ) ( ( ( cha r * ) gc_kth ) + a - > offset ) ;
ui = ( unsigned int * ) ( pt r + a - > offset ) ;
ret = kstrtoul ( skip_spaces ( buf ) , 0 , & t ) ;
if ( ret < 0 )
@ -139,21 +156,25 @@ static void f2fs_sb_release(struct kobject *kobj)
complete ( & sbi - > s_kobj_unregister ) ;
}
# define F2FS_ATTR_OFFSET(_name, _mode, _show, _store, _elname ) \
# define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset ) \
static struct f2fs_attr f2fs_attr_ # # _name = { \
. attr = { . name = __stringify ( _name ) , . mode = _mode } , \
. show = _show , \
. store = _store , \
. offset = offsetof ( struct f2fs_gc_kthread , _elname ) , \
. struct_type = _struct_type , \
. offset = _offset \
}
# define F2FS_RW_ATTR(name, elname) \
F2FS_ATTR_OFFSET ( name , 0644 , f2fs_sbi_show , f2fs_sbi_store , elname )
# define F2FS_RW_ATTR(struct_type, struct_name, name, elname) \
F2FS_ATTR_OFFSET ( struct_type , name , 0644 , \
f2fs_sbi_show , f2fs_sbi_store , \
offsetof ( struct struct_name , elname ) )
F2FS_RW_ATTR ( gc_min_sleep_time , min_sleep_time ) ;
F2FS_RW_ATTR ( gc_max_sleep_time , max_sleep_time ) ;
F2FS_RW_ATTR ( gc_no_gc_sleep_time , no_gc_sleep_time ) ;
F2FS_RW_ATTR ( gc_idle , gc_idle ) ;
F2FS_RW_ATTR ( GC_THREAD , f2fs_gc_kthread , gc_min_sleep_time , min_sleep_time ) ;
F2FS_RW_ATTR ( GC_THREAD , f2fs_gc_kthread , gc_max_sleep_time , max_sleep_time ) ;
F2FS_RW_ATTR ( GC_THREAD , f2fs_gc_kthread , gc_no_gc_sleep_time , no_gc_sleep_time ) ;
F2FS_RW_ATTR ( GC_THREAD , f2fs_gc_kthread , gc_idle , gc_idle ) ;
F2FS_RW_ATTR ( SM_INFO , f2fs_sm_info , reclaim_segments , rec_prefree_segments ) ;
# define ATTR_LIST(name) (&f2fs_attr_##name.attr)
static struct attribute * f2fs_attrs [ ] = {
@ -161,6 +182,7 @@ static struct attribute *f2fs_attrs[] = {
ATTR_LIST ( gc_max_sleep_time ) ,
ATTR_LIST ( gc_no_gc_sleep_time ) ,
ATTR_LIST ( gc_idle ) ,
ATTR_LIST ( reclaim_segments ) ,
NULL ,
} ;