sysfs.c (f75f6ff2eaa626d32dd3225e3008f807741ad1c5) | sysfs.c (d9872a698c393e0d1abca86bf05b62712cbfc581) |
---|---|
1/* 2 * f2fs sysfs interface 3 * 4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. 5 * http://www.samsung.com/ 6 * Copyright (c) 2017 Chao Yu <chao@kernel.org> 7 * 8 * This program is free software; you can redistribute it and/or modify --- 4 unchanged lines hidden (view full) --- 13#include <linux/f2fs_fs.h> 14#include <linux/seq_file.h> 15 16#include "f2fs.h" 17#include "segment.h" 18#include "gc.h" 19 20static struct proc_dir_entry *f2fs_proc_root; | 1/* 2 * f2fs sysfs interface 3 * 4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. 5 * http://www.samsung.com/ 6 * Copyright (c) 2017 Chao Yu <chao@kernel.org> 7 * 8 * This program is free software; you can redistribute it and/or modify --- 4 unchanged lines hidden (view full) --- 13#include <linux/f2fs_fs.h> 14#include <linux/seq_file.h> 15 16#include "f2fs.h" 17#include "segment.h" 18#include "gc.h" 19 20static struct proc_dir_entry *f2fs_proc_root; |
21static struct kset *f2fs_kset; | |
22 23/* Sysfs support for f2fs */ 24enum { 25 GC_THREAD, /* struct f2fs_gc_thread */ 26 SM_INFO, /* struct f2fs_sm_info */ 27 DCC_INFO, /* struct discard_cmd_control */ 28 NM_INFO, /* struct f2fs_nm_info */ 29 F2FS_SBI, /* struct f2fs_sb_info */ --- 6 unchanged lines hidden (view full) --- 36 37struct f2fs_attr { 38 struct attribute attr; 39 ssize_t (*show)(struct f2fs_attr *, struct f2fs_sb_info *, char *); 40 ssize_t (*store)(struct f2fs_attr *, struct f2fs_sb_info *, 41 const char *, size_t); 42 int struct_type; 43 int offset; | 21 22/* Sysfs support for f2fs */ 23enum { 24 GC_THREAD, /* struct f2fs_gc_thread */ 25 SM_INFO, /* struct f2fs_sm_info */ 26 DCC_INFO, /* struct discard_cmd_control */ 27 NM_INFO, /* struct f2fs_nm_info */ 28 F2FS_SBI, /* struct f2fs_sb_info */ --- 6 unchanged lines hidden (view full) --- 35 36struct f2fs_attr { 37 struct attribute attr; 38 ssize_t (*show)(struct f2fs_attr *, struct f2fs_sb_info *, char *); 39 ssize_t (*store)(struct f2fs_attr *, struct f2fs_sb_info *, 40 const char *, size_t); 41 int struct_type; 42 int offset; |
43 int id; |
|
44}; 45 46static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type) 47{ 48 if (struct_type == GC_THREAD) 49 return (unsigned char *)sbi->gc_thread; 50 else if (struct_type == SM_INFO) 51 return (unsigned char *)SM_I(sbi); --- 19 unchanged lines hidden (view full) --- 71 if (!sb->s_bdev->bd_part) 72 return snprintf(buf, PAGE_SIZE, "0\n"); 73 74 return snprintf(buf, PAGE_SIZE, "%llu\n", 75 (unsigned long long)(sbi->kbytes_written + 76 BD_PART_WRITTEN(sbi))); 77} 78 | 44}; 45 46static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type) 47{ 48 if (struct_type == GC_THREAD) 49 return (unsigned char *)sbi->gc_thread; 50 else if (struct_type == SM_INFO) 51 return (unsigned char *)SM_I(sbi); --- 19 unchanged lines hidden (view full) --- 71 if (!sb->s_bdev->bd_part) 72 return snprintf(buf, PAGE_SIZE, "0\n"); 73 74 return snprintf(buf, PAGE_SIZE, "%llu\n", 75 (unsigned long long)(sbi->kbytes_written + 76 BD_PART_WRITTEN(sbi))); 77} 78 |
79static 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 |
|
79static ssize_t f2fs_sbi_show(struct f2fs_attr *a, 80 struct f2fs_sb_info *sbi, char *buf) 81{ 82 unsigned char *ptr = NULL; 83 unsigned int *ui; 84 85 ptr = __struct_ptr(sbi, a->struct_type); 86 if (!ptr) --- 33 unchanged lines hidden (view full) --- 120 spin_unlock(&sbi->stat_lock); 121 return -EINVAL; 122 } 123 *ui = t; 124 spin_unlock(&sbi->stat_lock); 125 return count; 126 } 127 *ui = t; | 107static ssize_t f2fs_sbi_show(struct f2fs_attr *a, 108 struct f2fs_sb_info *sbi, char *buf) 109{ 110 unsigned char *ptr = NULL; 111 unsigned int *ui; 112 113 ptr = __struct_ptr(sbi, a->struct_type); 114 if (!ptr) --- 33 unchanged lines hidden (view full) --- 148 spin_unlock(&sbi->stat_lock); 149 return -EINVAL; 150 } 151 *ui = t; 152 spin_unlock(&sbi->stat_lock); 153 return count; 154 } 155 *ui = t; |
156 157 if (!strcmp(a->attr.name, "iostat_enable") && *ui == 0) 158 f2fs_reset_iostat(sbi); 159 if (!strcmp(a->attr.name, "gc_urgent") && t == 1 && sbi->gc_thread) { 160 sbi->gc_thread->gc_wake = 1; 161 wake_up_interruptible_all(&sbi->gc_thread->gc_wait_queue_head); 162 } 163 |
|
128 return count; 129} 130 131static ssize_t f2fs_attr_show(struct kobject *kobj, 132 struct attribute *attr, char *buf) 133{ 134 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info, 135 s_kobj); --- 14 unchanged lines hidden (view full) --- 150 151static void f2fs_sb_release(struct kobject *kobj) 152{ 153 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info, 154 s_kobj); 155 complete(&sbi->s_kobj_unregister); 156} 157 | 164 return count; 165} 166 167static ssize_t f2fs_attr_show(struct kobject *kobj, 168 struct attribute *attr, char *buf) 169{ 170 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info, 171 s_kobj); --- 14 unchanged lines hidden (view full) --- 186 187static void f2fs_sb_release(struct kobject *kobj) 188{ 189 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info, 190 s_kobj); 191 complete(&sbi->s_kobj_unregister); 192} 193 |
194enum feat_id { 195 FEAT_CRYPTO = 0, 196 FEAT_BLKZONED, 197 FEAT_ATOMIC_WRITE, 198 FEAT_EXTRA_ATTR, 199 FEAT_PROJECT_QUOTA, 200 FEAT_INODE_CHECKSUM, 201}; 202 203static ssize_t f2fs_feature_show(struct f2fs_attr *a, 204 struct f2fs_sb_info *sbi, char *buf) 205{ 206 switch (a->id) { 207 case FEAT_CRYPTO: 208 case FEAT_BLKZONED: 209 case FEAT_ATOMIC_WRITE: 210 case FEAT_EXTRA_ATTR: 211 case FEAT_PROJECT_QUOTA: 212 case FEAT_INODE_CHECKSUM: 213 return snprintf(buf, PAGE_SIZE, "supported\n"); 214 } 215 return 0; 216} 217 |
|
158#define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \ 159static struct f2fs_attr f2fs_attr_##_name = { \ 160 .attr = {.name = __stringify(_name), .mode = _mode }, \ 161 .show = _show, \ 162 .store = _store, \ 163 .struct_type = _struct_type, \ 164 .offset = _offset \ 165} 166 167#define F2FS_RW_ATTR(struct_type, struct_name, name, elname) \ 168 F2FS_ATTR_OFFSET(struct_type, name, 0644, \ 169 f2fs_sbi_show, f2fs_sbi_store, \ 170 offsetof(struct struct_name, elname)) 171 172#define F2FS_GENERAL_RO_ATTR(name) \ 173static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL) 174 | 218#define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \ 219static struct f2fs_attr f2fs_attr_##_name = { \ 220 .attr = {.name = __stringify(_name), .mode = _mode }, \ 221 .show = _show, \ 222 .store = _store, \ 223 .struct_type = _struct_type, \ 224 .offset = _offset \ 225} 226 227#define F2FS_RW_ATTR(struct_type, struct_name, name, elname) \ 228 F2FS_ATTR_OFFSET(struct_type, name, 0644, \ 229 f2fs_sbi_show, f2fs_sbi_store, \ 230 offsetof(struct struct_name, elname)) 231 232#define F2FS_GENERAL_RO_ATTR(name) \ 233static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL) 234 |
235#define F2FS_FEATURE_RO_ATTR(_name, _id) \ 236static struct f2fs_attr f2fs_attr_##_name = { \ 237 .attr = {.name = __stringify(_name), .mode = 0444 }, \ 238 .show = f2fs_feature_show, \ 239 .id = _id, \ 240} 241 242F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent_sleep_time, 243 urgent_sleep_time); |
|
175F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time); 176F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time); 177F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time); 178F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle); | 244F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time); 245F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time); 246F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time); 247F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle); |
248F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent, gc_urgent); |
|
179F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments); 180F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_small_discards, max_discards); 181F2FS_RW_ATTR(RESERVED_BLOCKS, f2fs_sb_info, reserved_blocks, reserved_blocks); 182F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, batched_trim_sections, trim_sections); 183F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy); 184F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util); 185F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks); 186F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_hot_blocks, min_hot_blocks); 187F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh); 188F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages); 189F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, dirty_nats_ratio, dirty_nats_ratio); 190F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search); 191F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level); 192F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]); 193F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]); | 249F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments); 250F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_small_discards, max_discards); 251F2FS_RW_ATTR(RESERVED_BLOCKS, f2fs_sb_info, reserved_blocks, reserved_blocks); 252F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, batched_trim_sections, trim_sections); 253F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy); 254F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util); 255F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks); 256F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_hot_blocks, min_hot_blocks); 257F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh); 258F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages); 259F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, dirty_nats_ratio, dirty_nats_ratio); 260F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search); 261F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level); 262F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]); 263F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]); |
264F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_enable, iostat_enable); |
|
194#ifdef CONFIG_F2FS_FAULT_INJECTION 195F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate); 196F2FS_RW_ATTR(FAULT_INFO_TYPE, f2fs_fault_info, inject_type, inject_type); 197#endif 198F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes); | 265#ifdef CONFIG_F2FS_FAULT_INJECTION 266F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate); 267F2FS_RW_ATTR(FAULT_INFO_TYPE, f2fs_fault_info, inject_type, inject_type); 268#endif 269F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes); |
270F2FS_GENERAL_RO_ATTR(features); |
|
199 | 271 |
272#ifdef CONFIG_F2FS_FS_ENCRYPTION 273F2FS_FEATURE_RO_ATTR(encryption, FEAT_CRYPTO); 274#endif 275#ifdef CONFIG_BLK_DEV_ZONED 276F2FS_FEATURE_RO_ATTR(block_zoned, FEAT_BLKZONED); 277#endif 278F2FS_FEATURE_RO_ATTR(atomic_write, FEAT_ATOMIC_WRITE); 279F2FS_FEATURE_RO_ATTR(extra_attr, FEAT_EXTRA_ATTR); 280F2FS_FEATURE_RO_ATTR(project_quota, FEAT_PROJECT_QUOTA); 281F2FS_FEATURE_RO_ATTR(inode_checksum, FEAT_INODE_CHECKSUM); 282 |
|
200#define ATTR_LIST(name) (&f2fs_attr_##name.attr) 201static struct attribute *f2fs_attrs[] = { | 283#define ATTR_LIST(name) (&f2fs_attr_##name.attr) 284static struct attribute *f2fs_attrs[] = { |
285 ATTR_LIST(gc_urgent_sleep_time), |
|
202 ATTR_LIST(gc_min_sleep_time), 203 ATTR_LIST(gc_max_sleep_time), 204 ATTR_LIST(gc_no_gc_sleep_time), 205 ATTR_LIST(gc_idle), | 286 ATTR_LIST(gc_min_sleep_time), 287 ATTR_LIST(gc_max_sleep_time), 288 ATTR_LIST(gc_no_gc_sleep_time), 289 ATTR_LIST(gc_idle), |
290 ATTR_LIST(gc_urgent), |
|
206 ATTR_LIST(reclaim_segments), 207 ATTR_LIST(max_small_discards), 208 ATTR_LIST(batched_trim_sections), 209 ATTR_LIST(ipu_policy), 210 ATTR_LIST(min_ipu_util), 211 ATTR_LIST(min_fsync_blocks), 212 ATTR_LIST(min_hot_blocks), 213 ATTR_LIST(max_victim_search), 214 ATTR_LIST(dir_level), 215 ATTR_LIST(ram_thresh), 216 ATTR_LIST(ra_nid_pages), 217 ATTR_LIST(dirty_nats_ratio), 218 ATTR_LIST(cp_interval), 219 ATTR_LIST(idle_interval), | 291 ATTR_LIST(reclaim_segments), 292 ATTR_LIST(max_small_discards), 293 ATTR_LIST(batched_trim_sections), 294 ATTR_LIST(ipu_policy), 295 ATTR_LIST(min_ipu_util), 296 ATTR_LIST(min_fsync_blocks), 297 ATTR_LIST(min_hot_blocks), 298 ATTR_LIST(max_victim_search), 299 ATTR_LIST(dir_level), 300 ATTR_LIST(ram_thresh), 301 ATTR_LIST(ra_nid_pages), 302 ATTR_LIST(dirty_nats_ratio), 303 ATTR_LIST(cp_interval), 304 ATTR_LIST(idle_interval), |
305 ATTR_LIST(iostat_enable), |
|
220#ifdef CONFIG_F2FS_FAULT_INJECTION 221 ATTR_LIST(inject_rate), 222 ATTR_LIST(inject_type), 223#endif 224 ATTR_LIST(lifetime_write_kbytes), | 306#ifdef CONFIG_F2FS_FAULT_INJECTION 307 ATTR_LIST(inject_rate), 308 ATTR_LIST(inject_type), 309#endif 310 ATTR_LIST(lifetime_write_kbytes), |
311 ATTR_LIST(features), |
|
225 ATTR_LIST(reserved_blocks), 226 NULL, 227}; 228 | 312 ATTR_LIST(reserved_blocks), 313 NULL, 314}; 315 |
316static struct attribute *f2fs_feat_attrs[] = { 317#ifdef CONFIG_F2FS_FS_ENCRYPTION 318 ATTR_LIST(encryption), 319#endif 320#ifdef CONFIG_BLK_DEV_ZONED 321 ATTR_LIST(block_zoned), 322#endif 323 ATTR_LIST(atomic_write), 324 ATTR_LIST(extra_attr), 325 ATTR_LIST(project_quota), 326 ATTR_LIST(inode_checksum), 327 NULL, 328}; 329 |
|
229static const struct sysfs_ops f2fs_attr_ops = { 230 .show = f2fs_attr_show, 231 .store = f2fs_attr_store, 232}; 233 | 330static const struct sysfs_ops f2fs_attr_ops = { 331 .show = f2fs_attr_show, 332 .store = f2fs_attr_store, 333}; 334 |
234static struct kobj_type f2fs_ktype = { | 335static struct kobj_type f2fs_sb_ktype = { |
235 .default_attrs = f2fs_attrs, 236 .sysfs_ops = &f2fs_attr_ops, 237 .release = f2fs_sb_release, 238}; 239 | 336 .default_attrs = f2fs_attrs, 337 .sysfs_ops = &f2fs_attr_ops, 338 .release = f2fs_sb_release, 339}; 340 |
341static struct kobj_type f2fs_ktype = { 342 .sysfs_ops = &f2fs_attr_ops, 343}; 344 345static struct kset f2fs_kset = { 346 .kobj = {.ktype = &f2fs_ktype}, 347}; 348 349static struct kobj_type f2fs_feat_ktype = { 350 .default_attrs = f2fs_feat_attrs, 351 .sysfs_ops = &f2fs_attr_ops, 352}; 353 354static struct kobject f2fs_feat = { 355 .kset = &f2fs_kset, 356}; 357 |
|
240static int segment_info_seq_show(struct seq_file *seq, void *offset) 241{ 242 struct super_block *sb = seq->private; 243 struct f2fs_sb_info *sbi = F2FS_SB(sb); 244 unsigned int total_segs = 245 le32_to_cpu(sbi->raw_super->segment_count_main); 246 int i; 247 --- 35 unchanged lines hidden (view full) --- 283 get_valid_blocks(sbi, i, false)); 284 for (j = 0; j < SIT_VBLOCK_MAP_SIZE; j++) 285 seq_printf(seq, " %.2x", se->cur_valid_map[j]); 286 seq_putc(seq, '\n'); 287 } 288 return 0; 289} 290 | 358static int segment_info_seq_show(struct seq_file *seq, void *offset) 359{ 360 struct super_block *sb = seq->private; 361 struct f2fs_sb_info *sbi = F2FS_SB(sb); 362 unsigned int total_segs = 363 le32_to_cpu(sbi->raw_super->segment_count_main); 364 int i; 365 --- 35 unchanged lines hidden (view full) --- 401 get_valid_blocks(sbi, i, false)); 402 for (j = 0; j < SIT_VBLOCK_MAP_SIZE; j++) 403 seq_printf(seq, " %.2x", se->cur_valid_map[j]); 404 seq_putc(seq, '\n'); 405 } 406 return 0; 407} 408 |
409static int iostat_info_seq_show(struct seq_file *seq, void *offset) 410{ 411 struct super_block *sb = seq->private; 412 struct f2fs_sb_info *sbi = F2FS_SB(sb); 413 time64_t now = ktime_get_real_seconds(); 414 415 if (!sbi->iostat_enable) 416 return 0; 417 418 seq_printf(seq, "time: %-16llu\n", now); 419 420 /* print app IOs */ 421 seq_printf(seq, "app buffered: %-16llu\n", 422 sbi->write_iostat[APP_BUFFERED_IO]); 423 seq_printf(seq, "app direct: %-16llu\n", 424 sbi->write_iostat[APP_DIRECT_IO]); 425 seq_printf(seq, "app mapped: %-16llu\n", 426 sbi->write_iostat[APP_MAPPED_IO]); 427 428 /* print fs IOs */ 429 seq_printf(seq, "fs data: %-16llu\n", 430 sbi->write_iostat[FS_DATA_IO]); 431 seq_printf(seq, "fs node: %-16llu\n", 432 sbi->write_iostat[FS_NODE_IO]); 433 seq_printf(seq, "fs meta: %-16llu\n", 434 sbi->write_iostat[FS_META_IO]); 435 seq_printf(seq, "fs gc data: %-16llu\n", 436 sbi->write_iostat[FS_GC_DATA_IO]); 437 seq_printf(seq, "fs gc node: %-16llu\n", 438 sbi->write_iostat[FS_GC_NODE_IO]); 439 seq_printf(seq, "fs cp data: %-16llu\n", 440 sbi->write_iostat[FS_CP_DATA_IO]); 441 seq_printf(seq, "fs cp node: %-16llu\n", 442 sbi->write_iostat[FS_CP_NODE_IO]); 443 seq_printf(seq, "fs cp meta: %-16llu\n", 444 sbi->write_iostat[FS_CP_META_IO]); 445 seq_printf(seq, "fs discard: %-16llu\n", 446 sbi->write_iostat[FS_DISCARD]); 447 448 return 0; 449} 450 |
|
291#define F2FS_PROC_FILE_DEF(_name) \ 292static int _name##_open_fs(struct inode *inode, struct file *file) \ 293{ \ 294 return single_open(file, _name##_seq_show, PDE_DATA(inode)); \ 295} \ 296 \ 297static const struct file_operations f2fs_seq_##_name##_fops = { \ 298 .open = _name##_open_fs, \ 299 .read = seq_read, \ 300 .llseek = seq_lseek, \ 301 .release = single_release, \ 302}; 303 304F2FS_PROC_FILE_DEF(segment_info); 305F2FS_PROC_FILE_DEF(segment_bits); | 451#define F2FS_PROC_FILE_DEF(_name) \ 452static int _name##_open_fs(struct inode *inode, struct file *file) \ 453{ \ 454 return single_open(file, _name##_seq_show, PDE_DATA(inode)); \ 455} \ 456 \ 457static const struct file_operations f2fs_seq_##_name##_fops = { \ 458 .open = _name##_open_fs, \ 459 .read = seq_read, \ 460 .llseek = seq_lseek, \ 461 .release = single_release, \ 462}; 463 464F2FS_PROC_FILE_DEF(segment_info); 465F2FS_PROC_FILE_DEF(segment_bits); |
466F2FS_PROC_FILE_DEF(iostat_info); |
|
306 | 467 |
307int __init f2fs_register_sysfs(void) | 468int __init f2fs_init_sysfs(void) |
308{ | 469{ |
309 f2fs_proc_root = proc_mkdir("fs/f2fs", NULL); | 470 int ret; |
310 | 471 |
311 f2fs_kset = kset_create_and_add("f2fs", NULL, fs_kobj); 312 if (!f2fs_kset) 313 return -ENOMEM; 314 return 0; | 472 kobject_set_name(&f2fs_kset.kobj, "f2fs"); 473 f2fs_kset.kobj.parent = fs_kobj; 474 ret = kset_register(&f2fs_kset); 475 if (ret) 476 return ret; 477 478 ret = kobject_init_and_add(&f2fs_feat, &f2fs_feat_ktype, 479 NULL, "features"); 480 if (ret) 481 kset_unregister(&f2fs_kset); 482 else 483 f2fs_proc_root = proc_mkdir("fs/f2fs", NULL); 484 return ret; |
315} 316 | 485} 486 |
317void f2fs_unregister_sysfs(void) | 487void f2fs_exit_sysfs(void) |
318{ | 488{ |
319 kset_unregister(f2fs_kset); | 489 kobject_put(&f2fs_feat); 490 kset_unregister(&f2fs_kset); |
320 remove_proc_entry("fs/f2fs", NULL); | 491 remove_proc_entry("fs/f2fs", NULL); |
492 f2fs_proc_root = NULL; |
|
321} 322 | 493} 494 |
323int f2fs_init_sysfs(struct f2fs_sb_info *sbi) | 495int f2fs_register_sysfs(struct f2fs_sb_info *sbi) |
324{ 325 struct super_block *sb = sbi->sb; 326 int err; 327 | 496{ 497 struct super_block *sb = sbi->sb; 498 int err; 499 |
500 sbi->s_kobj.kset = &f2fs_kset; 501 init_completion(&sbi->s_kobj_unregister); 502 err = kobject_init_and_add(&sbi->s_kobj, &f2fs_sb_ktype, NULL, 503 "%s", sb->s_id); 504 if (err) 505 return err; 506 |
|
328 if (f2fs_proc_root) 329 sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root); 330 331 if (sbi->s_proc) { 332 proc_create_data("segment_info", S_IRUGO, sbi->s_proc, 333 &f2fs_seq_segment_info_fops, sb); 334 proc_create_data("segment_bits", S_IRUGO, sbi->s_proc, 335 &f2fs_seq_segment_bits_fops, sb); | 507 if (f2fs_proc_root) 508 sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root); 509 510 if (sbi->s_proc) { 511 proc_create_data("segment_info", S_IRUGO, sbi->s_proc, 512 &f2fs_seq_segment_info_fops, sb); 513 proc_create_data("segment_bits", S_IRUGO, sbi->s_proc, 514 &f2fs_seq_segment_bits_fops, sb); |
515 proc_create_data("iostat_info", S_IRUGO, sbi->s_proc, 516 &f2fs_seq_iostat_info_fops, sb); |
|
336 } | 517 } |
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 return 0; | 518 return 0; |
345err_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} 353 | 519} 520 |
354void f2fs_exit_sysfs(struct f2fs_sb_info *sbi) | 521void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi) |
355{ | 522{ |
356 kobject_del(&sbi->s_kobj); 357 kobject_put(&sbi->s_kobj); 358 wait_for_completion(&sbi->s_kobj_unregister); 359 | |
360 if (sbi->s_proc) { | 523 if (sbi->s_proc) { |
524 remove_proc_entry("iostat_info", sbi->s_proc); |
|
361 remove_proc_entry("segment_info", sbi->s_proc); 362 remove_proc_entry("segment_bits", sbi->s_proc); 363 remove_proc_entry(sbi->sb->s_id, f2fs_proc_root); 364 } | 525 remove_proc_entry("segment_info", sbi->s_proc); 526 remove_proc_entry("segment_bits", sbi->s_proc); 527 remove_proc_entry(sbi->sb->s_id, f2fs_proc_root); 528 } |
529 kobject_del(&sbi->s_kobj); |
|
365} | 530} |