debug.c 15.4 KB
Newer Older
J
Jaegeuk Kim 已提交
1
/*
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 * f2fs debugging statistics
 *
 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
 *             http://www.samsung.com/
 * Copyright (c) 2012 Linux Foundation
 * Copyright (c) 2012 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/fs.h>
#include <linux/backing-dev.h>
#include <linux/f2fs_fs.h>
#include <linux/blkdev.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>

#include "f2fs.h"
#include "node.h"
#include "segment.h"
#include "gc.h"

static LIST_HEAD(f2fs_stat_list);
27
static struct dentry *f2fs_debugfs_root;
28
static DEFINE_MUTEX(f2fs_stat_mutex);
29

30
static void update_general_status(struct f2fs_sb_info *sbi)
31
{
32
	struct f2fs_stat_info *si = F2FS_STAT(sbi);
33 34
	int i;

A
arter97 已提交
35
	/* validation check of the segment numbers */
36 37 38
	si->hit_largest = atomic64_read(&sbi->read_hit_largest);
	si->hit_cached = atomic64_read(&sbi->read_hit_cached);
	si->hit_rbtree = atomic64_read(&sbi->read_hit_rbtree);
39
	si->hit_total = si->hit_largest + si->hit_cached + si->hit_rbtree;
40
	si->total_ext = atomic64_read(&sbi->total_hit_ext);
41
	si->ext_tree = atomic_read(&sbi->total_ext_tree);
J
Jaegeuk Kim 已提交
42
	si->zombie_tree = atomic_read(&sbi->total_zombie_tree);
43
	si->ext_node = atomic_read(&sbi->total_ext_node);
44 45 46
	si->ndirty_node = get_pages(sbi, F2FS_DIRTY_NODES);
	si->ndirty_dent = get_pages(sbi, F2FS_DIRTY_DENTS);
	si->ndirty_meta = get_pages(sbi, F2FS_DIRTY_META);
C
Chao Yu 已提交
47
	si->ndirty_data = get_pages(sbi, F2FS_DIRTY_DATA);
C
Chao Yu 已提交
48
	si->ndirty_imeta = get_pages(sbi, F2FS_DIRTY_IMETA);
C
Chao Yu 已提交
49 50
	si->ndirty_dirs = sbi->ndirty_inode[DIR_INODE];
	si->ndirty_files = sbi->ndirty_inode[FILE_INODE];
51
	si->ndirty_all = sbi->ndirty_inode[DIRTY_META];
52
	si->inmem_pages = get_pages(sbi, F2FS_INMEM_PAGES);
53 54
	si->aw_cnt = atomic_read(&sbi->aw_cnt);
	si->max_aw_cnt = atomic_read(&sbi->max_aw_cnt);
55 56
	si->nr_wb_cp_data = get_pages(sbi, F2FS_WB_CP_DATA);
	si->nr_wb_data = get_pages(sbi, F2FS_WB_DATA);
57 58 59 60
	si->total_count = (int)sbi->user_block_count / sbi->blocks_per_seg;
	si->rsvd_segs = reserved_segments(sbi);
	si->overp_segs = overprovision_segments(sbi);
	si->valid_count = valid_user_blocks(sbi);
61
	si->discard_blks = discard_blocks(sbi);
62 63
	si->valid_node_count = valid_node_count(sbi);
	si->valid_inode_count = valid_inode_count(sbi);
C
Chao Yu 已提交
64
	si->inline_xattr = atomic_read(&sbi->inline_xattr);
65 66
	si->inline_inode = atomic_read(&sbi->inline_inode);
	si->inline_dir = atomic_read(&sbi->inline_dir);
J
Jaegeuk Kim 已提交
67
	si->orphans = sbi->im[ORPHAN_INO].ino_num;
68 69 70 71 72 73
	si->utilization = utilization(sbi);

	si->free_segs = free_segments(sbi);
	si->free_secs = free_sections(sbi);
	si->prefree_count = prefree_segments(sbi);
	si->dirty_count = dirty_segments(sbi);
74
	si->node_pages = NODE_MAPPING(sbi)->nrpages;
G
Gu Zheng 已提交
75
	si->meta_pages = META_MAPPING(sbi)->nrpages;
76
	si->nats = NM_I(sbi)->nat_cnt;
77 78 79
	si->dirty_nats = NM_I(sbi)->dirty_nat_cnt;
	si->sits = MAIN_SEGS(sbi);
	si->dirty_sits = SIT_I(sbi)->dirty_sentries;
C
Chao Yu 已提交
80 81
	si->free_nids = NM_I(sbi)->nid_cnt[FREE_NID_LIST];
	si->alloc_nids = NM_I(sbi)->nid_cnt[ALLOC_NID_LIST];
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
	si->bg_gc = sbi->bg_gc;
	si->util_free = (int)(free_user_blocks(sbi) >> sbi->log_blocks_per_seg)
		* 100 / (int)(sbi->user_block_count >> sbi->log_blocks_per_seg)
		/ 2;
	si->util_valid = (int)(written_block_count(sbi) >>
						sbi->log_blocks_per_seg)
		* 100 / (int)(sbi->user_block_count >> sbi->log_blocks_per_seg)
		/ 2;
	si->util_invalid = 50 - si->util_free - si->util_valid;
	for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_NODE; i++) {
		struct curseg_info *curseg = CURSEG_I(sbi, i);
		si->curseg[i] = curseg->segno;
		si->cursec[i] = curseg->segno / sbi->segs_per_sec;
		si->curzone[i] = si->cursec[i] / sbi->secs_per_zone;
	}

	for (i = 0; i < 2; i++) {
		si->segment_count[i] = sbi->segment_count[i];
		si->block_count[i] = sbi->block_count[i];
	}
102 103

	si->inplace_count = atomic_read(&sbi->inplace_count);
104 105
}

J
Jaegeuk Kim 已提交
106
/*
107 108 109 110
 * This function calculates BDF of every segments
 */
static void update_sit_info(struct f2fs_sb_info *sbi)
{
111
	struct f2fs_stat_info *si = F2FS_STAT(sbi);
112 113
	unsigned long long blks_per_sec, hblks_per_sec, total_vblocks;
	unsigned long long bimodal, dist;
114 115 116 117 118
	unsigned int segno, vblocks;
	int ndirty = 0;

	bimodal = 0;
	total_vblocks = 0;
119
	blks_per_sec = sbi->segs_per_sec * sbi->blocks_per_seg;
120
	hblks_per_sec = blks_per_sec / 2;
121
	for (segno = 0; segno < MAIN_SEGS(sbi); segno += sbi->segs_per_sec) {
122 123 124 125 126 127 128 129 130
		vblocks = get_valid_blocks(sbi, segno, sbi->segs_per_sec);
		dist = abs(vblocks - hblks_per_sec);
		bimodal += dist * dist;

		if (vblocks > 0 && vblocks < blks_per_sec) {
			total_vblocks += vblocks;
			ndirty++;
		}
	}
131
	dist = div_u64(MAIN_SECS(sbi) * hblks_per_sec * hblks_per_sec, 100);
C
Chao Yu 已提交
132
	si->bimodal = div64_u64(bimodal, dist);
133
	if (si->dirty_count)
134
		si->avg_vblocks = div_u64(total_vblocks, ndirty);
135 136 137 138
	else
		si->avg_vblocks = 0;
}

J
Jaegeuk Kim 已提交
139
/*
140 141 142 143
 * This function calculates memory footprint.
 */
static void update_mem_info(struct f2fs_sb_info *sbi)
{
144
	struct f2fs_stat_info *si = F2FS_STAT(sbi);
145
	unsigned npages;
146
	int i;
147 148 149 150 151 152 153

	if (si->base_mem)
		goto get_cache;

	si->base_mem = sizeof(struct f2fs_sb_info) + sbi->sb->s_blocksize;
	si->base_mem += 2 * sizeof(struct f2fs_inode_info);
	si->base_mem += sizeof(*sbi->ckpt);
154
	si->base_mem += sizeof(struct percpu_counter) * NR_COUNT_TYPE;
155 156 157 158 159 160

	/* build sm */
	si->base_mem += sizeof(struct f2fs_sm_info);

	/* build sit */
	si->base_mem += sizeof(struct sit_info);
161 162
	si->base_mem += MAIN_SEGS(sbi) * sizeof(struct seg_entry);
	si->base_mem += f2fs_bitmap_size(MAIN_SEGS(sbi));
163 164 165
	si->base_mem += 2 * SIT_VBLOCK_MAP_SIZE * MAIN_SEGS(sbi);
	if (f2fs_discard_en(sbi))
		si->base_mem += SIT_VBLOCK_MAP_SIZE * MAIN_SEGS(sbi);
J
Jaegeuk Kim 已提交
166
	si->base_mem += SIT_VBLOCK_MAP_SIZE;
167
	if (sbi->segs_per_sec > 1)
168
		si->base_mem += MAIN_SECS(sbi) * sizeof(struct sec_entry);
169 170 171 172
	si->base_mem += __bitmap_size(sbi, SIT_BITMAP);

	/* build free segmap */
	si->base_mem += sizeof(struct free_segmap_info);
173 174
	si->base_mem += f2fs_bitmap_size(MAIN_SEGS(sbi));
	si->base_mem += f2fs_bitmap_size(MAIN_SECS(sbi));
175 176 177

	/* build curseg */
	si->base_mem += sizeof(struct curseg_info) * NR_CURSEG_TYPE;
178
	si->base_mem += PAGE_SIZE * NR_CURSEG_TYPE;
179 180 181

	/* build dirty segmap */
	si->base_mem += sizeof(struct dirty_seglist_info);
182 183
	si->base_mem += NR_DIRTY_TYPE * f2fs_bitmap_size(MAIN_SEGS(sbi));
	si->base_mem += f2fs_bitmap_size(MAIN_SECS(sbi));
184

A
arter97 已提交
185
	/* build nm */
186 187 188
	si->base_mem += sizeof(struct f2fs_nm_info);
	si->base_mem += __bitmap_size(sbi, NAT_BITMAP);

189 190 191
get_cache:
	si->cache_mem = 0;

192
	/* build gc */
193 194 195 196
	if (sbi->gc_thread)
		si->cache_mem += sizeof(struct f2fs_gc_kthread);

	/* build merge flush thread */
197
	if (SM_I(sbi)->fcc_info)
198
		si->cache_mem += sizeof(struct flush_cmd_control);
199 200

	/* free nids */
C
Chao Yu 已提交
201 202 203
	si->cache_mem += (NM_I(sbi)->nid_cnt[FREE_NID_LIST] +
				NM_I(sbi)->nid_cnt[ALLOC_NID_LIST]) *
				sizeof(struct free_nid);
204
	si->cache_mem += NM_I(sbi)->nat_cnt * sizeof(struct nat_entry);
205 206 207
	si->cache_mem += NM_I(sbi)->dirty_nat_cnt *
					sizeof(struct nat_entry_set);
	si->cache_mem += si->inmem_pages * sizeof(struct inmem_pages);
J
Jaegeuk Kim 已提交
208
	for (i = 0; i <= ORPHAN_INO; i++)
209
		si->cache_mem += sbi->im[i].ino_num * sizeof(struct ino_entry);
210 211
	si->cache_mem += atomic_read(&sbi->total_ext_tree) *
						sizeof(struct extent_tree);
212 213
	si->cache_mem += atomic_read(&sbi->total_ext_node) *
						sizeof(struct extent_node);
214 215 216

	si->page_mem = 0;
	npages = NODE_MAPPING(sbi)->nrpages;
217
	si->page_mem += (unsigned long long)npages << PAGE_SHIFT;
218
	npages = META_MAPPING(sbi)->nrpages;
219
	si->page_mem += (unsigned long long)npages << PAGE_SHIFT;
220 221 222 223
}

static int stat_show(struct seq_file *s, void *v)
{
224
	struct f2fs_stat_info *si;
225 226 227
	int i = 0;
	int j;

228
	mutex_lock(&f2fs_stat_mutex);
229
	list_for_each_entry(si, &f2fs_stat_list, stat_list) {
230 231
		update_general_status(si->sbi);

J
Jaegeuk Kim 已提交
232 233 234
		seq_printf(s, "\n=====[ partition info(%pg). #%d, %s]=====\n",
			si->sbi->sb->s_bdev, i++,
			f2fs_readonly(si->sbi->sb) ? "RO": "RW");
235 236
		seq_printf(s, "[SB: 1] [CP: 2] [SIT: %d] [NAT: %d] ",
			   si->sit_area_segs, si->nat_area_segs);
237 238 239 240
		seq_printf(s, "[SSA: %d] [MAIN: %d",
			   si->ssa_area_segs, si->main_area_segs);
		seq_printf(s, "(OverProv:%d Resv:%d)]\n\n",
			   si->overp_segs, si->rsvd_segs);
241 242 243 244 245 246 247
		if (test_opt(si->sbi, DISCARD))
			seq_printf(s, "Utilization: %u%% (%u valid blocks, %u discard blocks)\n",
				si->utilization, si->valid_count, si->discard_blks);
		else
			seq_printf(s, "Utilization: %u%% (%u valid blocks)\n",
				si->utilization, si->valid_count);

248 249 250 251 252
		seq_printf(s, "  - Node: %u (Inode: %u, ",
			   si->valid_node_count, si->valid_inode_count);
		seq_printf(s, "Other: %u)\n  - Data: %u\n",
			   si->valid_node_count - si->valid_inode_count,
			   si->valid_count - si->valid_node_count);
C
Chao Yu 已提交
253 254
		seq_printf(s, "  - Inline_xattr Inode: %u\n",
			   si->inline_xattr);
255 256
		seq_printf(s, "  - Inline_data Inode: %u\n",
			   si->inline_inode);
257 258
		seq_printf(s, "  - Inline_dentry Inode: %u\n",
			   si->inline_dir);
J
Jaegeuk Kim 已提交
259 260
		seq_printf(s, "  - Orphan Inode: %u\n",
			   si->orphans);
261 262
		seq_printf(s, "  - Atomic write count: %4d (Max. %4d)\n",
			   si->aw_cnt, si->max_aw_cnt);
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
		seq_printf(s, "\nMain area: %d segs, %d secs %d zones\n",
			   si->main_area_segs, si->main_area_sections,
			   si->main_area_zones);
		seq_printf(s, "  - COLD  data: %d, %d, %d\n",
			   si->curseg[CURSEG_COLD_DATA],
			   si->cursec[CURSEG_COLD_DATA],
			   si->curzone[CURSEG_COLD_DATA]);
		seq_printf(s, "  - WARM  data: %d, %d, %d\n",
			   si->curseg[CURSEG_WARM_DATA],
			   si->cursec[CURSEG_WARM_DATA],
			   si->curzone[CURSEG_WARM_DATA]);
		seq_printf(s, "  - HOT   data: %d, %d, %d\n",
			   si->curseg[CURSEG_HOT_DATA],
			   si->cursec[CURSEG_HOT_DATA],
			   si->curzone[CURSEG_HOT_DATA]);
		seq_printf(s, "  - Dir   dnode: %d, %d, %d\n",
			   si->curseg[CURSEG_HOT_NODE],
			   si->cursec[CURSEG_HOT_NODE],
			   si->curzone[CURSEG_HOT_NODE]);
		seq_printf(s, "  - File   dnode: %d, %d, %d\n",
			   si->curseg[CURSEG_WARM_NODE],
			   si->cursec[CURSEG_WARM_NODE],
			   si->curzone[CURSEG_WARM_NODE]);
		seq_printf(s, "  - Indir nodes: %d, %d, %d\n",
			   si->curseg[CURSEG_COLD_NODE],
			   si->cursec[CURSEG_COLD_NODE],
			   si->curzone[CURSEG_COLD_NODE]);
		seq_printf(s, "\n  - Valid: %d\n  - Dirty: %d\n",
			   si->main_area_segs - si->dirty_count -
			   si->prefree_count - si->free_segs,
			   si->dirty_count);
		seq_printf(s, "  - Prefree: %d\n  - Free: %d (%d)\n\n",
			   si->prefree_count, si->free_segs, si->free_secs);
296 297
		seq_printf(s, "CP calls: %d (BG: %d)\n",
				si->cp_count, si->bg_cp_count);
298 299
		seq_printf(s, "GC calls: %d (BG: %d)\n",
			   si->call_count, si->bg_gc);
300 301 302 303 304 305 306 307 308 309
		seq_printf(s, "  - data segments : %d (%d)\n",
				si->data_segs, si->bg_data_segs);
		seq_printf(s, "  - node segments : %d (%d)\n",
				si->node_segs, si->bg_node_segs);
		seq_printf(s, "Try to move %d blocks (BG: %d)\n", si->tot_blks,
				si->bg_data_blks + si->bg_node_blks);
		seq_printf(s, "  - data blocks : %d (%d)\n", si->data_blks,
				si->bg_data_blks);
		seq_printf(s, "  - node blocks : %d (%d)\n", si->node_blks,
				si->bg_node_blks);
310
		seq_puts(s, "\nExtent Cache:\n");
311
		seq_printf(s, "  - Hit Count: L1-1:%llu L1-2:%llu L2:%llu\n",
312
				si->hit_largest, si->hit_cached,
313
				si->hit_rbtree);
314
		seq_printf(s, "  - Hit Ratio: %llu%% (%llu / %llu)\n",
315
				!si->total_ext ? 0 :
316
				div64_u64(si->hit_total * 100, si->total_ext),
317
				si->hit_total, si->total_ext);
J
Jaegeuk Kim 已提交
318 319
		seq_printf(s, "  - Inner Struct Count: tree: %d(%d), node: %d\n",
				si->ext_tree, si->zombie_tree, si->ext_node);
C
Chris Fries 已提交
320
		seq_puts(s, "\nBalancing F2FS Async:\n");
321 322
		seq_printf(s, "  - inmem: %4d, wb_cp_data: %4d, wb_data: %4d\n",
			   si->inmem_pages, si->nr_wb_cp_data, si->nr_wb_data);
323
		seq_printf(s, "  - nodes: %4d in %4d\n",
324
			   si->ndirty_node, si->node_pages);
325
		seq_printf(s, "  - dents: %4d in dirs:%4d (%4d)\n",
326
			   si->ndirty_dent, si->ndirty_dirs, si->ndirty_all);
327
		seq_printf(s, "  - datas: %4d in files:%4d\n",
C
Chao Yu 已提交
328
			   si->ndirty_data, si->ndirty_files);
329
		seq_printf(s, "  - meta: %4d in %4d\n",
330
			   si->ndirty_meta, si->meta_pages);
331
		seq_printf(s, "  - imeta: %4d\n",
C
Chao Yu 已提交
332
			   si->ndirty_imeta);
333 334
		seq_printf(s, "  - NATs: %9d/%9d\n  - SITs: %9d/%9d\n",
			   si->dirty_nats, si->nats, si->dirty_sits, si->sits);
C
Chao Yu 已提交
335 336
		seq_printf(s, "  - free_nids: %9d, alloc_nids: %9d\n",
			   si->free_nids, si->alloc_nids);
337 338 339
		seq_puts(s, "\nDistribution of User Blocks:");
		seq_puts(s, " [ valid | invalid | free ]\n");
		seq_puts(s, "  [");
340 341

		for (j = 0; j < si->util_valid; j++)
342 343
			seq_putc(s, '-');
		seq_putc(s, '|');
344 345

		for (j = 0; j < si->util_invalid; j++)
346 347
			seq_putc(s, '-');
		seq_putc(s, '|');
348 349

		for (j = 0; j < si->util_free; j++)
350 351
			seq_putc(s, '-');
		seq_puts(s, "]\n\n");
352
		seq_printf(s, "IPU: %u blocks\n", si->inplace_count);
353 354 355 356 357 358 359 360 361 362 363 364
		seq_printf(s, "SSR: %u blocks in %u segments\n",
			   si->block_count[SSR], si->segment_count[SSR]);
		seq_printf(s, "LFS: %u blocks in %u segments\n",
			   si->block_count[LFS], si->segment_count[LFS]);

		/* segment usage info */
		update_sit_info(si->sbi);
		seq_printf(s, "\nBDF: %u, avg. vblocks: %u\n",
			   si->bimodal, si->avg_vblocks);

		/* memory footprint */
		update_mem_info(si->sbi);
C
Chao Yu 已提交
365
		seq_printf(s, "\nMemory: %llu KB\n",
366
			(si->base_mem + si->cache_mem + si->page_mem) >> 10);
C
Chao Yu 已提交
367
		seq_printf(s, "  - static: %llu KB\n",
368
				si->base_mem >> 10);
C
Chao Yu 已提交
369
		seq_printf(s, "  - cached: %llu KB\n",
370
				si->cache_mem >> 10);
C
Chao Yu 已提交
371
		seq_printf(s, "  - paged : %llu KB\n",
372
				si->page_mem >> 10);
373
	}
374
	mutex_unlock(&f2fs_stat_mutex);
375 376 377 378 379 380 381 382 383
	return 0;
}

static int stat_open(struct inode *inode, struct file *file)
{
	return single_open(file, stat_show, inode->i_private);
}

static const struct file_operations stat_fops = {
384
	.owner = THIS_MODULE,
385 386 387 388 389 390
	.open = stat_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
};

391
int f2fs_build_stats(struct f2fs_sb_info *sbi)
392 393 394 395
{
	struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
	struct f2fs_stat_info *si;

396 397
	si = kzalloc(sizeof(struct f2fs_stat_info), GFP_KERNEL);
	if (!si)
398 399 400 401 402 403 404 405 406 407 408
		return -ENOMEM;

	si->all_area_segs = le32_to_cpu(raw_super->segment_count);
	si->sit_area_segs = le32_to_cpu(raw_super->segment_count_sit);
	si->nat_area_segs = le32_to_cpu(raw_super->segment_count_nat);
	si->ssa_area_segs = le32_to_cpu(raw_super->segment_count_ssa);
	si->main_area_segs = le32_to_cpu(raw_super->segment_count_main);
	si->main_area_sections = le32_to_cpu(raw_super->section_count);
	si->main_area_zones = si->main_area_sections /
				le32_to_cpu(raw_super->secs_per_zone);
	si->sbi = sbi;
409
	sbi->stat_info = si;
410

411 412 413 414
	atomic64_set(&sbi->total_hit_ext, 0);
	atomic64_set(&sbi->read_hit_rbtree, 0);
	atomic64_set(&sbi->read_hit_largest, 0);
	atomic64_set(&sbi->read_hit_cached, 0);
415

C
Chao Yu 已提交
416
	atomic_set(&sbi->inline_xattr, 0);
417 418
	atomic_set(&sbi->inline_inode, 0);
	atomic_set(&sbi->inline_dir, 0);
419
	atomic_set(&sbi->inplace_count, 0);
420

421 422 423
	atomic_set(&sbi->aw_cnt, 0);
	atomic_set(&sbi->max_aw_cnt, 0);

424 425 426 427
	mutex_lock(&f2fs_stat_mutex);
	list_add_tail(&si->stat_list, &f2fs_stat_list);
	mutex_unlock(&f2fs_stat_mutex);

428 429 430 431 432
	return 0;
}

void f2fs_destroy_stats(struct f2fs_sb_info *sbi)
{
433
	struct f2fs_stat_info *si = F2FS_STAT(sbi);
434

435
	mutex_lock(&f2fs_stat_mutex);
436
	list_del(&si->stat_list);
437 438
	mutex_unlock(&f2fs_stat_mutex);

439
	kfree(si);
440 441
}

442
int __init f2fs_create_root_stats(void)
443
{
444 445
	struct dentry *file;

446 447
	f2fs_debugfs_root = debugfs_create_dir("f2fs", NULL);
	if (!f2fs_debugfs_root)
448
		return -ENOMEM;
449

450
	file = debugfs_create_file("status", S_IRUGO, f2fs_debugfs_root,
451
			NULL, &stat_fops);
452 453 454
	if (!file) {
		debugfs_remove(f2fs_debugfs_root);
		f2fs_debugfs_root = NULL;
455
		return -ENOMEM;
456
	}
457 458

	return 0;
459 460 461
}

void f2fs_destroy_root_stats(void)
462
{
463
	if (!f2fs_debugfs_root)
464 465
		return;

466 467
	debugfs_remove_recursive(f2fs_debugfs_root);
	f2fs_debugfs_root = NULL;
468
}