18
18
#include "gc.h"
19
19
20
20
static struct proc_dir_entry * f2fs_proc_root ;
21
- static struct kset * f2fs_kset ;
22
21
23
22
/* Sysfs support for f2fs */
24
23
enum {
@@ -41,6 +40,7 @@ struct f2fs_attr {
41
40
const char * , size_t );
42
41
int struct_type ;
43
42
int offset ;
43
+ int id ;
44
44
};
45
45
46
46
static unsigned char * __struct_ptr (struct f2fs_sb_info * sbi , int struct_type )
@@ -76,6 +76,34 @@ static ssize_t lifetime_write_kbytes_show(struct f2fs_attr *a,
76
76
BD_PART_WRITTEN (sbi )));
77
77
}
78
78
79
+ static ssize_t features_show (struct f2fs_attr * a ,
80
+ struct f2fs_sb_info * sbi , char * buf )
81
+ {
82
+ struct super_block * sb = sbi -> sb ;
83
+ int len = 0 ;
84
+
85
+ if (!sb -> s_bdev -> bd_part )
86
+ return snprintf (buf , PAGE_SIZE , "0\n" );
87
+
88
+ if (f2fs_sb_has_crypto (sb ))
89
+ len += snprintf (buf , PAGE_SIZE - len , "%s" ,
90
+ "encryption" );
91
+ if (f2fs_sb_mounted_blkzoned (sb ))
92
+ len += snprintf (buf + len , PAGE_SIZE - len , "%s%s" ,
93
+ len ? ", " : "" , "blkzoned" );
94
+ if (f2fs_sb_has_extra_attr (sb ))
95
+ len += snprintf (buf + len , PAGE_SIZE - len , "%s%s" ,
96
+ len ? ", " : "" , "extra_attr" );
97
+ if (f2fs_sb_has_project_quota (sb ))
98
+ len += snprintf (buf + len , PAGE_SIZE - len , "%s%s" ,
99
+ len ? ", " : "" , "projquota" );
100
+ if (f2fs_sb_has_inode_chksum (sb ))
101
+ len += snprintf (buf + len , PAGE_SIZE - len , "%s%s" ,
102
+ len ? ", " : "" , "inode_checksum" );
103
+ len += snprintf (buf + len , PAGE_SIZE - len , "\n" );
104
+ return len ;
105
+ }
106
+
79
107
static ssize_t f2fs_sbi_show (struct f2fs_attr * a ,
80
108
struct f2fs_sb_info * sbi , char * buf )
81
109
{
@@ -155,6 +183,30 @@ static void f2fs_sb_release(struct kobject *kobj)
155
183
complete (& sbi -> s_kobj_unregister );
156
184
}
157
185
186
+ enum feat_id {
187
+ FEAT_CRYPTO = 0 ,
188
+ FEAT_BLKZONED ,
189
+ FEAT_ATOMIC_WRITE ,
190
+ FEAT_EXTRA_ATTR ,
191
+ FEAT_PROJECT_QUOTA ,
192
+ FEAT_INODE_CHECKSUM ,
193
+ };
194
+
195
+ static ssize_t f2fs_feature_show (struct f2fs_attr * a ,
196
+ struct f2fs_sb_info * sbi , char * buf )
197
+ {
198
+ switch (a -> id ) {
199
+ case FEAT_CRYPTO :
200
+ case FEAT_BLKZONED :
201
+ case FEAT_ATOMIC_WRITE :
202
+ case FEAT_EXTRA_ATTR :
203
+ case FEAT_PROJECT_QUOTA :
204
+ case FEAT_INODE_CHECKSUM :
205
+ return snprintf (buf , PAGE_SIZE , "supported\n" );
206
+ }
207
+ return 0 ;
208
+ }
209
+
158
210
#define F2FS_ATTR_OFFSET (_struct_type , _name , _mode , _show , _store , _offset ) \
159
211
static struct f2fs_attr f2fs_attr_##_name = { \
160
212
.attr = {.name = __stringify(_name), .mode = _mode }, \
@@ -172,6 +224,13 @@ static struct f2fs_attr f2fs_attr_##_name = { \
172
224
#define F2FS_GENERAL_RO_ATTR (name ) \
173
225
static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL)
174
226
227
+ #define F2FS_FEATURE_RO_ATTR (_name , _id ) \
228
+ static struct f2fs_attr f2fs_attr_##_name = { \
229
+ .attr = {.name = __stringify(_name), .mode = 0444 }, \
230
+ .show = f2fs_feature_show, \
231
+ .id = _id, \
232
+ }
233
+
175
234
F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread , gc_min_sleep_time , min_sleep_time );
176
235
F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread , gc_max_sleep_time , max_sleep_time );
177
236
F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread , gc_no_gc_sleep_time , no_gc_sleep_time );
@@ -196,6 +255,18 @@ F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate);
196
255
F2FS_RW_ATTR (FAULT_INFO_TYPE , f2fs_fault_info , inject_type , inject_type );
197
256
#endif
198
257
F2FS_GENERAL_RO_ATTR (lifetime_write_kbytes );
258
+ F2FS_GENERAL_RO_ATTR (features );
259
+
260
+ #ifdef CONFIG_F2FS_FS_ENCRYPTION
261
+ F2FS_FEATURE_RO_ATTR (encryption , FEAT_CRYPTO );
262
+ #endif
263
+ #ifdef CONFIG_BLK_DEV_ZONED
264
+ F2FS_FEATURE_RO_ATTR (block_zoned , FEAT_BLKZONED );
265
+ #endif
266
+ F2FS_FEATURE_RO_ATTR (atomic_write , FEAT_ATOMIC_WRITE );
267
+ F2FS_FEATURE_RO_ATTR (extra_attr , FEAT_EXTRA_ATTR );
268
+ F2FS_FEATURE_RO_ATTR (project_quota , FEAT_PROJECT_QUOTA );
269
+ F2FS_FEATURE_RO_ATTR (inode_checksum , FEAT_INODE_CHECKSUM );
199
270
200
271
#define ATTR_LIST (name ) (&f2fs_attr_##name.attr)
201
272
static struct attribute * f2fs_attrs [] = {
@@ -222,21 +293,53 @@ static struct attribute *f2fs_attrs[] = {
222
293
ATTR_LIST (inject_type ),
223
294
#endif
224
295
ATTR_LIST (lifetime_write_kbytes ),
296
+ ATTR_LIST (features ),
225
297
ATTR_LIST (reserved_blocks ),
226
298
NULL ,
227
299
};
228
300
301
+ static struct attribute * f2fs_feat_attrs [] = {
302
+ #ifdef CONFIG_F2FS_FS_ENCRYPTION
303
+ ATTR_LIST (encryption ),
304
+ #endif
305
+ #ifdef CONFIG_BLK_DEV_ZONED
306
+ ATTR_LIST (block_zoned ),
307
+ #endif
308
+ ATTR_LIST (atomic_write ),
309
+ ATTR_LIST (extra_attr ),
310
+ ATTR_LIST (project_quota ),
311
+ ATTR_LIST (inode_checksum ),
312
+ NULL ,
313
+ };
314
+
229
315
static const struct sysfs_ops f2fs_attr_ops = {
230
316
.show = f2fs_attr_show ,
231
317
.store = f2fs_attr_store ,
232
318
};
233
319
234
- static struct kobj_type f2fs_ktype = {
320
+ static struct kobj_type f2fs_sb_ktype = {
235
321
.default_attrs = f2fs_attrs ,
236
322
.sysfs_ops = & f2fs_attr_ops ,
237
323
.release = f2fs_sb_release ,
238
324
};
239
325
326
+ static struct kobj_type f2fs_ktype = {
327
+ .sysfs_ops = & f2fs_attr_ops ,
328
+ };
329
+
330
+ static struct kset f2fs_kset = {
331
+ .kobj = {.ktype = & f2fs_ktype },
332
+ };
333
+
334
+ static struct kobj_type f2fs_feat_ktype = {
335
+ .default_attrs = f2fs_feat_attrs ,
336
+ .sysfs_ops = & f2fs_attr_ops ,
337
+ };
338
+
339
+ static struct kobject f2fs_feat = {
340
+ .kset = & f2fs_kset ,
341
+ };
342
+
240
343
static int segment_info_seq_show (struct seq_file * seq , void * offset )
241
344
{
242
345
struct super_block * sb = seq -> private ;
@@ -306,25 +409,43 @@ F2FS_PROC_FILE_DEF(segment_bits);
306
409
307
410
int __init f2fs_init_sysfs (void )
308
411
{
309
- f2fs_proc_root = proc_mkdir ( "fs/f2fs" , NULL ) ;
412
+ int ret ;
310
413
311
- f2fs_kset = kset_create_and_add ("f2fs" , NULL , fs_kobj );
312
- if (!f2fs_kset )
313
- return - ENOMEM ;
314
- return 0 ;
414
+ kobject_set_name (& f2fs_kset .kobj , "f2fs" );
415
+ f2fs_kset .kobj .parent = fs_kobj ;
416
+ ret = kset_register (& f2fs_kset );
417
+ if (ret )
418
+ return ret ;
419
+
420
+ ret = kobject_init_and_add (& f2fs_feat , & f2fs_feat_ktype ,
421
+ NULL , "features" );
422
+ if (ret )
423
+ kset_unregister (& f2fs_kset );
424
+ else
425
+ f2fs_proc_root = proc_mkdir ("fs/f2fs" , NULL );
426
+ return ret ;
315
427
}
316
428
317
429
void f2fs_exit_sysfs (void )
318
430
{
319
- kset_unregister (f2fs_kset );
431
+ kobject_put (& f2fs_feat );
432
+ kset_unregister (& f2fs_kset );
320
433
remove_proc_entry ("fs/f2fs" , NULL );
434
+ f2fs_proc_root = NULL ;
321
435
}
322
436
323
437
int f2fs_register_sysfs (struct f2fs_sb_info * sbi )
324
438
{
325
439
struct super_block * sb = sbi -> sb ;
326
440
int err ;
327
441
442
+ sbi -> s_kobj .kset = & f2fs_kset ;
443
+ init_completion (& sbi -> s_kobj_unregister );
444
+ err = kobject_init_and_add (& sbi -> s_kobj , & f2fs_sb_ktype , NULL ,
445
+ "%s" , sb -> s_id );
446
+ if (err )
447
+ return err ;
448
+
328
449
if (f2fs_proc_root )
329
450
sbi -> s_proc = proc_mkdir (sb -> s_id , f2fs_proc_root );
330
451
@@ -334,32 +455,15 @@ int f2fs_register_sysfs(struct f2fs_sb_info *sbi)
334
455
proc_create_data ("segment_bits" , S_IRUGO , sbi -> s_proc ,
335
456
& f2fs_seq_segment_bits_fops , sb );
336
457
}
337
-
338
- sbi -> s_kobj .kset = f2fs_kset ;
339
- init_completion (& sbi -> s_kobj_unregister );
340
- err = kobject_init_and_add (& sbi -> s_kobj , & f2fs_ktype , NULL ,
341
- "%s" , sb -> s_id );
342
- if (err )
343
- goto err_out ;
344
458
return 0 ;
345
- err_out :
346
- if (sbi -> s_proc ) {
347
- remove_proc_entry ("segment_info" , sbi -> s_proc );
348
- remove_proc_entry ("segment_bits" , sbi -> s_proc );
349
- remove_proc_entry (sb -> s_id , f2fs_proc_root );
350
- }
351
- return err ;
352
459
}
353
460
354
461
void f2fs_unregister_sysfs (struct f2fs_sb_info * sbi )
355
462
{
356
- kobject_del (& sbi -> s_kobj );
357
- kobject_put (& sbi -> s_kobj );
358
- wait_for_completion (& sbi -> s_kobj_unregister );
359
-
360
463
if (sbi -> s_proc ) {
361
464
remove_proc_entry ("segment_info" , sbi -> s_proc );
362
465
remove_proc_entry ("segment_bits" , sbi -> s_proc );
363
466
remove_proc_entry (sbi -> sb -> s_id , f2fs_proc_root );
364
467
}
468
+ kobject_del (& sbi -> s_kobj );
365
469
}
0 commit comments