brintos

brintos / linux-shallow public Read only

0
0
Text · 46.1 KiB · c56e8c8 Raw
1692 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * f2fs sysfs interface4 *5 * Copyright (c) 2012 Samsung Electronics Co., Ltd.6 *             http://www.samsung.com/7 * Copyright (c) 2017 Chao Yu <chao@kernel.org>8 */9#include <linux/compiler.h>10#include <linux/proc_fs.h>11#include <linux/f2fs_fs.h>12#include <linux/seq_file.h>13#include <linux/unicode.h>14#include <linux/ioprio.h>15#include <linux/sysfs.h>16 17#include "f2fs.h"18#include "segment.h"19#include "gc.h"20#include "iostat.h"21#include <trace/events/f2fs.h>22 23static struct proc_dir_entry *f2fs_proc_root;24 25/* Sysfs support for f2fs */26enum {27	GC_THREAD,	/* struct f2fs_gc_thread */28	SM_INFO,	/* struct f2fs_sm_info */29	DCC_INFO,	/* struct discard_cmd_control */30	NM_INFO,	/* struct f2fs_nm_info */31	F2FS_SBI,	/* struct f2fs_sb_info */32#ifdef CONFIG_F2FS_STAT_FS33	STAT_INFO,	/* struct f2fs_stat_info */34#endif35#ifdef CONFIG_F2FS_FAULT_INJECTION36	FAULT_INFO_RATE,	/* struct f2fs_fault_info */37	FAULT_INFO_TYPE,	/* struct f2fs_fault_info */38#endif39	RESERVED_BLOCKS,	/* struct f2fs_sb_info */40	CPRC_INFO,	/* struct ckpt_req_control */41	ATGC_INFO,	/* struct atgc_management */42};43 44static const char *gc_mode_names[MAX_GC_MODE] = {45	"GC_NORMAL",46	"GC_IDLE_CB",47	"GC_IDLE_GREEDY",48	"GC_IDLE_AT",49	"GC_URGENT_HIGH",50	"GC_URGENT_LOW",51	"GC_URGENT_MID"52};53 54struct f2fs_attr {55	struct attribute attr;56	ssize_t (*show)(struct f2fs_attr *a, struct f2fs_sb_info *sbi, char *buf);57	ssize_t (*store)(struct f2fs_attr *a, struct f2fs_sb_info *sbi,58			 const char *buf, size_t len);59	int struct_type;60	int offset;61	int id;62};63 64static ssize_t f2fs_sbi_show(struct f2fs_attr *a,65			     struct f2fs_sb_info *sbi, char *buf);66 67static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type)68{69	if (struct_type == GC_THREAD)70		return (unsigned char *)sbi->gc_thread;71	else if (struct_type == SM_INFO)72		return (unsigned char *)SM_I(sbi);73	else if (struct_type == DCC_INFO)74		return (unsigned char *)SM_I(sbi)->dcc_info;75	else if (struct_type == NM_INFO)76		return (unsigned char *)NM_I(sbi);77	else if (struct_type == F2FS_SBI || struct_type == RESERVED_BLOCKS)78		return (unsigned char *)sbi;79#ifdef CONFIG_F2FS_FAULT_INJECTION80	else if (struct_type == FAULT_INFO_RATE ||81					struct_type == FAULT_INFO_TYPE)82		return (unsigned char *)&F2FS_OPTION(sbi).fault_info;83#endif84#ifdef CONFIG_F2FS_STAT_FS85	else if (struct_type == STAT_INFO)86		return (unsigned char *)F2FS_STAT(sbi);87#endif88	else if (struct_type == CPRC_INFO)89		return (unsigned char *)&sbi->cprc_info;90	else if (struct_type == ATGC_INFO)91		return (unsigned char *)&sbi->am;92	return NULL;93}94 95static ssize_t dirty_segments_show(struct f2fs_attr *a,96		struct f2fs_sb_info *sbi, char *buf)97{98	return sysfs_emit(buf, "%llu\n",99			(unsigned long long)(dirty_segments(sbi)));100}101 102static ssize_t free_segments_show(struct f2fs_attr *a,103		struct f2fs_sb_info *sbi, char *buf)104{105	return sysfs_emit(buf, "%llu\n",106			(unsigned long long)(free_segments(sbi)));107}108 109static ssize_t ovp_segments_show(struct f2fs_attr *a,110		struct f2fs_sb_info *sbi, char *buf)111{112	return sysfs_emit(buf, "%llu\n",113			(unsigned long long)(overprovision_segments(sbi)));114}115 116static ssize_t lifetime_write_kbytes_show(struct f2fs_attr *a,117		struct f2fs_sb_info *sbi, char *buf)118{119	return sysfs_emit(buf, "%llu\n",120			(unsigned long long)(sbi->kbytes_written +121			((f2fs_get_sectors_written(sbi) -122				sbi->sectors_written_start) >> 1)));123}124 125static ssize_t sb_status_show(struct f2fs_attr *a,126		struct f2fs_sb_info *sbi, char *buf)127{128	return sysfs_emit(buf, "%lx\n", sbi->s_flag);129}130 131static ssize_t cp_status_show(struct f2fs_attr *a,132		struct f2fs_sb_info *sbi, char *buf)133{134	return sysfs_emit(buf, "%x\n", le32_to_cpu(F2FS_CKPT(sbi)->ckpt_flags));135}136 137static ssize_t pending_discard_show(struct f2fs_attr *a,138		struct f2fs_sb_info *sbi, char *buf)139{140	if (!SM_I(sbi)->dcc_info)141		return -EINVAL;142	return sysfs_emit(buf, "%llu\n", (unsigned long long)atomic_read(143				&SM_I(sbi)->dcc_info->discard_cmd_cnt));144}145 146static ssize_t issued_discard_show(struct f2fs_attr *a,147		struct f2fs_sb_info *sbi, char *buf)148{149	if (!SM_I(sbi)->dcc_info)150		return -EINVAL;151	return sysfs_emit(buf, "%llu\n", (unsigned long long)atomic_read(152				&SM_I(sbi)->dcc_info->issued_discard));153}154 155static ssize_t queued_discard_show(struct f2fs_attr *a,156		struct f2fs_sb_info *sbi, char *buf)157{158	if (!SM_I(sbi)->dcc_info)159		return -EINVAL;160	return sysfs_emit(buf, "%llu\n", (unsigned long long)atomic_read(161				&SM_I(sbi)->dcc_info->queued_discard));162}163 164static ssize_t undiscard_blks_show(struct f2fs_attr *a,165		struct f2fs_sb_info *sbi, char *buf)166{167	if (!SM_I(sbi)->dcc_info)168		return -EINVAL;169	return sysfs_emit(buf, "%u\n",170				SM_I(sbi)->dcc_info->undiscard_blks);171}172 173static ssize_t atgc_enabled_show(struct f2fs_attr *a,174		struct f2fs_sb_info *sbi, char *buf)175{176	return sysfs_emit(buf, "%d\n", sbi->am.atgc_enabled ? 1 : 0);177}178 179static ssize_t gc_mode_show(struct f2fs_attr *a,180		struct f2fs_sb_info *sbi, char *buf)181{182	return sysfs_emit(buf, "%s\n", gc_mode_names[sbi->gc_mode]);183}184 185static ssize_t features_show(struct f2fs_attr *a,186		struct f2fs_sb_info *sbi, char *buf)187{188	int len = 0;189 190	if (f2fs_sb_has_encrypt(sbi))191		len += sysfs_emit_at(buf, len, "%s",192						"encryption");193	if (f2fs_sb_has_blkzoned(sbi))194		len += sysfs_emit_at(buf, len, "%s%s",195				len ? ", " : "", "blkzoned");196	if (f2fs_sb_has_extra_attr(sbi))197		len += sysfs_emit_at(buf, len, "%s%s",198				len ? ", " : "", "extra_attr");199	if (f2fs_sb_has_project_quota(sbi))200		len += sysfs_emit_at(buf, len, "%s%s",201				len ? ", " : "", "projquota");202	if (f2fs_sb_has_inode_chksum(sbi))203		len += sysfs_emit_at(buf, len, "%s%s",204				len ? ", " : "", "inode_checksum");205	if (f2fs_sb_has_flexible_inline_xattr(sbi))206		len += sysfs_emit_at(buf, len, "%s%s",207				len ? ", " : "", "flexible_inline_xattr");208	if (f2fs_sb_has_quota_ino(sbi))209		len += sysfs_emit_at(buf, len, "%s%s",210				len ? ", " : "", "quota_ino");211	if (f2fs_sb_has_inode_crtime(sbi))212		len += sysfs_emit_at(buf, len, "%s%s",213				len ? ", " : "", "inode_crtime");214	if (f2fs_sb_has_lost_found(sbi))215		len += sysfs_emit_at(buf, len, "%s%s",216				len ? ", " : "", "lost_found");217	if (f2fs_sb_has_verity(sbi))218		len += sysfs_emit_at(buf, len, "%s%s",219				len ? ", " : "", "verity");220	if (f2fs_sb_has_sb_chksum(sbi))221		len += sysfs_emit_at(buf, len, "%s%s",222				len ? ", " : "", "sb_checksum");223	if (f2fs_sb_has_casefold(sbi))224		len += sysfs_emit_at(buf, len, "%s%s",225				len ? ", " : "", "casefold");226	if (f2fs_sb_has_readonly(sbi))227		len += sysfs_emit_at(buf, len, "%s%s",228				len ? ", " : "", "readonly");229	if (f2fs_sb_has_compression(sbi))230		len += sysfs_emit_at(buf, len, "%s%s",231				len ? ", " : "", "compression");232	len += sysfs_emit_at(buf, len, "%s%s",233				len ? ", " : "", "pin_file");234	len += sysfs_emit_at(buf, len, "\n");235	return len;236}237 238static ssize_t current_reserved_blocks_show(struct f2fs_attr *a,239					struct f2fs_sb_info *sbi, char *buf)240{241	return sysfs_emit(buf, "%u\n", sbi->current_reserved_blocks);242}243 244static ssize_t unusable_show(struct f2fs_attr *a,245		struct f2fs_sb_info *sbi, char *buf)246{247	block_t unusable;248 249	if (test_opt(sbi, DISABLE_CHECKPOINT))250		unusable = sbi->unusable_block_count;251	else252		unusable = f2fs_get_unusable_blocks(sbi);253	return sysfs_emit(buf, "%llu\n", (unsigned long long)unusable);254}255 256static ssize_t encoding_show(struct f2fs_attr *a,257		struct f2fs_sb_info *sbi, char *buf)258{259#if IS_ENABLED(CONFIG_UNICODE)260	struct super_block *sb = sbi->sb;261 262	if (f2fs_sb_has_casefold(sbi))263		return sysfs_emit(buf, "UTF-8 (%d.%d.%d)\n",264			(sb->s_encoding->version >> 16) & 0xff,265			(sb->s_encoding->version >> 8) & 0xff,266			sb->s_encoding->version & 0xff);267#endif268	return sysfs_emit(buf, "(none)\n");269}270 271static ssize_t mounted_time_sec_show(struct f2fs_attr *a,272		struct f2fs_sb_info *sbi, char *buf)273{274	return sysfs_emit(buf, "%llu\n", SIT_I(sbi)->mounted_time);275}276 277#ifdef CONFIG_F2FS_STAT_FS278static ssize_t moved_blocks_foreground_show(struct f2fs_attr *a,279				struct f2fs_sb_info *sbi, char *buf)280{281	struct f2fs_stat_info *si = F2FS_STAT(sbi);282 283	return sysfs_emit(buf, "%llu\n",284		(unsigned long long)(si->tot_blks -285			(si->bg_data_blks + si->bg_node_blks)));286}287 288static ssize_t moved_blocks_background_show(struct f2fs_attr *a,289				struct f2fs_sb_info *sbi, char *buf)290{291	struct f2fs_stat_info *si = F2FS_STAT(sbi);292 293	return sysfs_emit(buf, "%llu\n",294		(unsigned long long)(si->bg_data_blks + si->bg_node_blks));295}296 297static ssize_t avg_vblocks_show(struct f2fs_attr *a,298		struct f2fs_sb_info *sbi, char *buf)299{300	struct f2fs_stat_info *si = F2FS_STAT(sbi);301 302	si->dirty_count = dirty_segments(sbi);303	f2fs_update_sit_info(sbi);304	return sysfs_emit(buf, "%llu\n", (unsigned long long)(si->avg_vblocks));305}306#endif307 308static ssize_t main_blkaddr_show(struct f2fs_attr *a,309				struct f2fs_sb_info *sbi, char *buf)310{311	return sysfs_emit(buf, "%llu\n",312			(unsigned long long)MAIN_BLKADDR(sbi));313}314 315static ssize_t f2fs_sbi_show(struct f2fs_attr *a,316			struct f2fs_sb_info *sbi, char *buf)317{318	unsigned char *ptr = NULL;319	unsigned int *ui;320 321	ptr = __struct_ptr(sbi, a->struct_type);322	if (!ptr)323		return -EINVAL;324 325	if (!strcmp(a->attr.name, "extension_list")) {326		__u8 (*extlist)[F2FS_EXTENSION_LEN] =327					sbi->raw_super->extension_list;328		int cold_count = le32_to_cpu(sbi->raw_super->extension_count);329		int hot_count = sbi->raw_super->hot_ext_count;330		int len = 0, i;331 332		len += sysfs_emit_at(buf, len, "cold file extension:\n");333		for (i = 0; i < cold_count; i++)334			len += sysfs_emit_at(buf, len, "%s\n", extlist[i]);335 336		len += sysfs_emit_at(buf, len, "hot file extension:\n");337		for (i = cold_count; i < cold_count + hot_count; i++)338			len += sysfs_emit_at(buf, len, "%s\n", extlist[i]);339 340		return len;341	}342 343	if (!strcmp(a->attr.name, "ckpt_thread_ioprio")) {344		struct ckpt_req_control *cprc = &sbi->cprc_info;345		int class = IOPRIO_PRIO_CLASS(cprc->ckpt_thread_ioprio);346		int level = IOPRIO_PRIO_LEVEL(cprc->ckpt_thread_ioprio);347 348		if (class != IOPRIO_CLASS_RT && class != IOPRIO_CLASS_BE)349			return -EINVAL;350 351		return sysfs_emit(buf, "%s,%d\n",352			class == IOPRIO_CLASS_RT ? "rt" : "be", level);353	}354 355#ifdef CONFIG_F2FS_FS_COMPRESSION356	if (!strcmp(a->attr.name, "compr_written_block"))357		return sysfs_emit(buf, "%llu\n", sbi->compr_written_block);358 359	if (!strcmp(a->attr.name, "compr_saved_block"))360		return sysfs_emit(buf, "%llu\n", sbi->compr_saved_block);361 362	if (!strcmp(a->attr.name, "compr_new_inode"))363		return sysfs_emit(buf, "%u\n", sbi->compr_new_inode);364#endif365 366	if (!strcmp(a->attr.name, "gc_segment_mode"))367		return sysfs_emit(buf, "%u\n", sbi->gc_segment_mode);368 369	if (!strcmp(a->attr.name, "gc_reclaimed_segments")) {370		return sysfs_emit(buf, "%u\n",371			sbi->gc_reclaimed_segs[sbi->gc_segment_mode]);372	}373 374	if (!strcmp(a->attr.name, "current_atomic_write")) {375		s64 current_write = atomic64_read(&sbi->current_atomic_write);376 377		return sysfs_emit(buf, "%lld\n", current_write);378	}379 380	if (!strcmp(a->attr.name, "peak_atomic_write"))381		return sysfs_emit(buf, "%lld\n", sbi->peak_atomic_write);382 383	if (!strcmp(a->attr.name, "committed_atomic_block"))384		return sysfs_emit(buf, "%llu\n", sbi->committed_atomic_block);385 386	if (!strcmp(a->attr.name, "revoked_atomic_block"))387		return sysfs_emit(buf, "%llu\n", sbi->revoked_atomic_block);388 389#ifdef CONFIG_F2FS_STAT_FS390	if (!strcmp(a->attr.name, "cp_foreground_calls"))391		return sysfs_emit(buf, "%d\n",392				atomic_read(&sbi->cp_call_count[TOTAL_CALL]) -393				atomic_read(&sbi->cp_call_count[BACKGROUND]));394	if (!strcmp(a->attr.name, "cp_background_calls"))395		return sysfs_emit(buf, "%d\n",396				atomic_read(&sbi->cp_call_count[BACKGROUND]));397#endif398 399	ui = (unsigned int *)(ptr + a->offset);400 401	return sysfs_emit(buf, "%u\n", *ui);402}403 404static ssize_t __sbi_store(struct f2fs_attr *a,405			struct f2fs_sb_info *sbi,406			const char *buf, size_t count)407{408	unsigned char *ptr;409	unsigned long t;410	unsigned int *ui;411	ssize_t ret;412 413	ptr = __struct_ptr(sbi, a->struct_type);414	if (!ptr)415		return -EINVAL;416 417	if (!strcmp(a->attr.name, "extension_list")) {418		const char *name = strim((char *)buf);419		bool set = true, hot;420 421		if (!strncmp(name, "[h]", 3))422			hot = true;423		else if (!strncmp(name, "[c]", 3))424			hot = false;425		else426			return -EINVAL;427 428		name += 3;429 430		if (*name == '!') {431			name++;432			set = false;433		}434 435		if (!strlen(name) || strlen(name) >= F2FS_EXTENSION_LEN)436			return -EINVAL;437 438		f2fs_down_write(&sbi->sb_lock);439 440		ret = f2fs_update_extension_list(sbi, name, hot, set);441		if (ret)442			goto out;443 444		ret = f2fs_commit_super(sbi, false);445		if (ret)446			f2fs_update_extension_list(sbi, name, hot, !set);447out:448		f2fs_up_write(&sbi->sb_lock);449		return ret ? ret : count;450	}451 452	if (!strcmp(a->attr.name, "ckpt_thread_ioprio")) {453		const char *name = strim((char *)buf);454		struct ckpt_req_control *cprc = &sbi->cprc_info;455		int class;456		long level;457		int ret;458 459		if (!strncmp(name, "rt,", 3))460			class = IOPRIO_CLASS_RT;461		else if (!strncmp(name, "be,", 3))462			class = IOPRIO_CLASS_BE;463		else464			return -EINVAL;465 466		name += 3;467		ret = kstrtol(name, 10, &level);468		if (ret)469			return ret;470		if (level >= IOPRIO_NR_LEVELS || level < 0)471			return -EINVAL;472 473		cprc->ckpt_thread_ioprio = IOPRIO_PRIO_VALUE(class, level);474		if (test_opt(sbi, MERGE_CHECKPOINT)) {475			ret = set_task_ioprio(cprc->f2fs_issue_ckpt,476					cprc->ckpt_thread_ioprio);477			if (ret)478				return ret;479		}480 481		return count;482	}483 484	ui = (unsigned int *)(ptr + a->offset);485 486	ret = kstrtoul(skip_spaces(buf), 0, &t);487	if (ret < 0)488		return ret;489#ifdef CONFIG_F2FS_FAULT_INJECTION490	if (a->struct_type == FAULT_INFO_TYPE) {491		if (f2fs_build_fault_attr(sbi, 0, t))492			return -EINVAL;493		return count;494	}495	if (a->struct_type == FAULT_INFO_RATE) {496		if (f2fs_build_fault_attr(sbi, t, 0))497			return -EINVAL;498		return count;499	}500#endif501	if (a->struct_type == RESERVED_BLOCKS) {502		spin_lock(&sbi->stat_lock);503		if (t > (unsigned long)(sbi->user_block_count -504				F2FS_OPTION(sbi).root_reserved_blocks -505				SEGS_TO_BLKS(sbi,506				SM_I(sbi)->additional_reserved_segments))) {507			spin_unlock(&sbi->stat_lock);508			return -EINVAL;509		}510		*ui = t;511		sbi->current_reserved_blocks = min(sbi->reserved_blocks,512				sbi->user_block_count - valid_user_blocks(sbi));513		spin_unlock(&sbi->stat_lock);514		return count;515	}516 517	if (!strcmp(a->attr.name, "discard_io_aware_gran")) {518		if (t > MAX_PLIST_NUM)519			return -EINVAL;520		if (!f2fs_block_unit_discard(sbi))521			return -EINVAL;522		if (t == *ui)523			return count;524		*ui = t;525		return count;526	}527 528	if (!strcmp(a->attr.name, "discard_granularity")) {529		if (t == 0 || t > MAX_PLIST_NUM)530			return -EINVAL;531		if (!f2fs_block_unit_discard(sbi))532			return -EINVAL;533		if (t == *ui)534			return count;535		*ui = t;536		return count;537	}538 539	if (!strcmp(a->attr.name, "max_ordered_discard")) {540		if (t == 0 || t > MAX_PLIST_NUM)541			return -EINVAL;542		if (!f2fs_block_unit_discard(sbi))543			return -EINVAL;544		*ui = t;545		return count;546	}547 548	if (!strcmp(a->attr.name, "discard_urgent_util")) {549		if (t > 100)550			return -EINVAL;551		*ui = t;552		return count;553	}554 555	if (!strcmp(a->attr.name, "discard_io_aware")) {556		if (t >= DPOLICY_IO_AWARE_MAX)557			return -EINVAL;558		*ui = t;559		return count;560	}561 562	if (!strcmp(a->attr.name, "migration_granularity")) {563		if (t == 0 || t > SEGS_PER_SEC(sbi))564			return -EINVAL;565	}566 567	if (!strcmp(a->attr.name, "migration_window_granularity")) {568		if (t == 0 || t > SEGS_PER_SEC(sbi))569			return -EINVAL;570	}571 572	if (!strcmp(a->attr.name, "gc_urgent")) {573		if (t == 0) {574			sbi->gc_mode = GC_NORMAL;575		} else if (t == 1) {576			sbi->gc_mode = GC_URGENT_HIGH;577			if (sbi->gc_thread) {578				sbi->gc_thread->gc_wake = true;579				wake_up_interruptible_all(580					&sbi->gc_thread->gc_wait_queue_head);581				wake_up_discard_thread(sbi, true);582			}583		} else if (t == 2) {584			sbi->gc_mode = GC_URGENT_LOW;585		} else if (t == 3) {586			sbi->gc_mode = GC_URGENT_MID;587			if (sbi->gc_thread) {588				sbi->gc_thread->gc_wake = true;589				wake_up_interruptible_all(590					&sbi->gc_thread->gc_wait_queue_head);591			}592		} else {593			return -EINVAL;594		}595		return count;596	}597	if (!strcmp(a->attr.name, "gc_idle")) {598		if (t == GC_IDLE_CB) {599			sbi->gc_mode = GC_IDLE_CB;600		} else if (t == GC_IDLE_GREEDY) {601			sbi->gc_mode = GC_IDLE_GREEDY;602		} else if (t == GC_IDLE_AT) {603			if (!sbi->am.atgc_enabled)604				return -EINVAL;605			sbi->gc_mode = GC_IDLE_AT;606		} else {607			sbi->gc_mode = GC_NORMAL;608		}609		return count;610	}611 612	if (!strcmp(a->attr.name, "gc_remaining_trials")) {613		spin_lock(&sbi->gc_remaining_trials_lock);614		sbi->gc_remaining_trials = t;615		spin_unlock(&sbi->gc_remaining_trials_lock);616 617		return count;618	}619 620#ifdef CONFIG_F2FS_IOSTAT621	if (!strcmp(a->attr.name, "iostat_enable")) {622		sbi->iostat_enable = !!t;623		if (!sbi->iostat_enable)624			f2fs_reset_iostat(sbi);625		return count;626	}627 628	if (!strcmp(a->attr.name, "iostat_period_ms")) {629		if (t < MIN_IOSTAT_PERIOD_MS || t > MAX_IOSTAT_PERIOD_MS)630			return -EINVAL;631		spin_lock_irq(&sbi->iostat_lock);632		sbi->iostat_period_ms = (unsigned int)t;633		spin_unlock_irq(&sbi->iostat_lock);634		return count;635	}636#endif637 638#ifdef CONFIG_BLK_DEV_ZONED639	if (!strcmp(a->attr.name, "blkzone_alloc_policy")) {640		if (t < BLKZONE_ALLOC_PRIOR_SEQ || t > BLKZONE_ALLOC_PRIOR_CONV)641			return -EINVAL;642		sbi->blkzone_alloc_policy = t;643		return count;644	}645#endif646 647#ifdef CONFIG_F2FS_FS_COMPRESSION648	if (!strcmp(a->attr.name, "compr_written_block") ||649		!strcmp(a->attr.name, "compr_saved_block")) {650		if (t != 0)651			return -EINVAL;652		sbi->compr_written_block = 0;653		sbi->compr_saved_block = 0;654		return count;655	}656 657	if (!strcmp(a->attr.name, "compr_new_inode")) {658		if (t != 0)659			return -EINVAL;660		sbi->compr_new_inode = 0;661		return count;662	}663 664	if (!strcmp(a->attr.name, "compress_percent")) {665		if (t == 0 || t > 100)666			return -EINVAL;667		*ui = t;668		return count;669	}670 671	if (!strcmp(a->attr.name, "compress_watermark")) {672		if (t == 0 || t > 100)673			return -EINVAL;674		*ui = t;675		return count;676	}677#endif678 679	if (!strcmp(a->attr.name, "atgc_candidate_ratio")) {680		if (t > 100)681			return -EINVAL;682		sbi->am.candidate_ratio = t;683		return count;684	}685 686	if (!strcmp(a->attr.name, "atgc_age_weight")) {687		if (t > 100)688			return -EINVAL;689		sbi->am.age_weight = t;690		return count;691	}692 693	if (!strcmp(a->attr.name, "gc_segment_mode")) {694		if (t < MAX_GC_MODE)695			sbi->gc_segment_mode = t;696		else697			return -EINVAL;698		return count;699	}700 701	if (!strcmp(a->attr.name, "gc_pin_file_threshold")) {702		if (t > MAX_GC_FAILED_PINNED_FILES)703			return -EINVAL;704		sbi->gc_pin_file_threshold = t;705		return count;706	}707 708	if (!strcmp(a->attr.name, "gc_reclaimed_segments")) {709		if (t != 0)710			return -EINVAL;711		sbi->gc_reclaimed_segs[sbi->gc_segment_mode] = 0;712		return count;713	}714 715	if (!strcmp(a->attr.name, "seq_file_ra_mul")) {716		if (t >= MIN_RA_MUL && t <= MAX_RA_MUL)717			sbi->seq_file_ra_mul = t;718		else719			return -EINVAL;720		return count;721	}722 723	if (!strcmp(a->attr.name, "max_fragment_chunk")) {724		if (t >= MIN_FRAGMENT_SIZE && t <= MAX_FRAGMENT_SIZE)725			sbi->max_fragment_chunk = t;726		else727			return -EINVAL;728		return count;729	}730 731	if (!strcmp(a->attr.name, "max_fragment_hole")) {732		if (t >= MIN_FRAGMENT_SIZE && t <= MAX_FRAGMENT_SIZE)733			sbi->max_fragment_hole = t;734		else735			return -EINVAL;736		return count;737	}738 739	if (!strcmp(a->attr.name, "peak_atomic_write")) {740		if (t != 0)741			return -EINVAL;742		sbi->peak_atomic_write = 0;743		return count;744	}745 746	if (!strcmp(a->attr.name, "committed_atomic_block")) {747		if (t != 0)748			return -EINVAL;749		sbi->committed_atomic_block = 0;750		return count;751	}752 753	if (!strcmp(a->attr.name, "revoked_atomic_block")) {754		if (t != 0)755			return -EINVAL;756		sbi->revoked_atomic_block = 0;757		return count;758	}759 760	if (!strcmp(a->attr.name, "readdir_ra")) {761		sbi->readdir_ra = !!t;762		return count;763	}764 765	if (!strcmp(a->attr.name, "hot_data_age_threshold")) {766		if (t == 0 || t >= sbi->warm_data_age_threshold)767			return -EINVAL;768		if (t == *ui)769			return count;770		*ui = (unsigned int)t;771		return count;772	}773 774	if (!strcmp(a->attr.name, "warm_data_age_threshold")) {775		if (t <= sbi->hot_data_age_threshold)776			return -EINVAL;777		if (t == *ui)778			return count;779		*ui = (unsigned int)t;780		return count;781	}782 783	if (!strcmp(a->attr.name, "last_age_weight")) {784		if (t > 100)785			return -EINVAL;786		if (t == *ui)787			return count;788		*ui = (unsigned int)t;789		return count;790	}791 792	if (!strcmp(a->attr.name, "ipu_policy")) {793		if (t >= BIT(F2FS_IPU_MAX))794			return -EINVAL;795		/* allow F2FS_IPU_NOCACHE only for IPU in the pinned file */796		if (f2fs_lfs_mode(sbi) && (t & ~BIT(F2FS_IPU_NOCACHE)))797			return -EINVAL;798		SM_I(sbi)->ipu_policy = (unsigned int)t;799		return count;800	}801 802	if (!strcmp(a->attr.name, "dir_level")) {803		if (t > MAX_DIR_HASH_DEPTH)804			return -EINVAL;805		sbi->dir_level = t;806		return count;807	}808 809	*ui = (unsigned int)t;810 811	return count;812}813 814static ssize_t f2fs_sbi_store(struct f2fs_attr *a,815			struct f2fs_sb_info *sbi,816			const char *buf, size_t count)817{818	ssize_t ret;819	bool gc_entry = (!strcmp(a->attr.name, "gc_urgent") ||820					a->struct_type == GC_THREAD);821 822	if (gc_entry) {823		if (!down_read_trylock(&sbi->sb->s_umount))824			return -EAGAIN;825	}826	ret = __sbi_store(a, sbi, buf, count);827	if (gc_entry)828		up_read(&sbi->sb->s_umount);829 830	return ret;831}832 833static ssize_t f2fs_attr_show(struct kobject *kobj,834				struct attribute *attr, char *buf)835{836	struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,837								s_kobj);838	struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);839 840	return a->show ? a->show(a, sbi, buf) : 0;841}842 843static ssize_t f2fs_attr_store(struct kobject *kobj, struct attribute *attr,844						const char *buf, size_t len)845{846	struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,847									s_kobj);848	struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);849 850	return a->store ? a->store(a, sbi, buf, len) : 0;851}852 853static void f2fs_sb_release(struct kobject *kobj)854{855	struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,856								s_kobj);857	complete(&sbi->s_kobj_unregister);858}859 860/*861 * Note that there are three feature list entries:862 * 1) /sys/fs/f2fs/features863 *   : shows runtime features supported by in-kernel f2fs along with Kconfig.864 *     - ref. F2FS_FEATURE_RO_ATTR()865 *866 * 2) /sys/fs/f2fs/$s_id/features <deprecated>867 *   : shows on-disk features enabled by mkfs.f2fs, used for old kernels. This868 *     won't add new feature anymore, and thus, users should check entries in 3)869 *     instead of this 2).870 *871 * 3) /sys/fs/f2fs/$s_id/feature_list872 *   : shows on-disk features enabled by mkfs.f2fs per instance, which follows873 *     sysfs entry rule where each entry should expose single value.874 *     This list covers old feature list provided by 2) and beyond. Therefore,875 *     please add new on-disk feature in this list only.876 *     - ref. F2FS_SB_FEATURE_RO_ATTR()877 */878static ssize_t f2fs_feature_show(struct f2fs_attr *a,879		struct f2fs_sb_info *sbi, char *buf)880{881	return sysfs_emit(buf, "supported\n");882}883 884#define F2FS_FEATURE_RO_ATTR(_name)				\885static struct f2fs_attr f2fs_attr_##_name = {			\886	.attr = {.name = __stringify(_name), .mode = 0444 },	\887	.show	= f2fs_feature_show,				\888}889 890static ssize_t f2fs_sb_feature_show(struct f2fs_attr *a,891		struct f2fs_sb_info *sbi, char *buf)892{893	if (F2FS_HAS_FEATURE(sbi, a->id))894		return sysfs_emit(buf, "supported\n");895	return sysfs_emit(buf, "unsupported\n");896}897 898#define F2FS_SB_FEATURE_RO_ATTR(_name, _feat)			\899static struct f2fs_attr f2fs_attr_sb_##_name = {		\900	.attr = {.name = __stringify(_name), .mode = 0444 },	\901	.show	= f2fs_sb_feature_show,				\902	.id	= F2FS_FEATURE_##_feat,				\903}904 905#define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \906static struct f2fs_attr f2fs_attr_##_name = {			\907	.attr = {.name = __stringify(_name), .mode = _mode },	\908	.show	= _show,					\909	.store	= _store,					\910	.struct_type = _struct_type,				\911	.offset = _offset					\912}913 914#define F2FS_RO_ATTR(struct_type, struct_name, name, elname)	\915	F2FS_ATTR_OFFSET(struct_type, name, 0444,		\916		f2fs_sbi_show, NULL,				\917		offsetof(struct struct_name, elname))918 919#define F2FS_RW_ATTR(struct_type, struct_name, name, elname)	\920	F2FS_ATTR_OFFSET(struct_type, name, 0644,		\921		f2fs_sbi_show, f2fs_sbi_store,			\922		offsetof(struct struct_name, elname))923 924#define F2FS_GENERAL_RO_ATTR(name) \925static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL)926 927#ifdef CONFIG_F2FS_STAT_FS928#define STAT_INFO_RO_ATTR(name, elname)				\929	F2FS_RO_ATTR(STAT_INFO, f2fs_stat_info, name, elname)930#endif931 932#define GC_THREAD_RW_ATTR(name, elname)				\933	F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, name, elname)934 935#define SM_INFO_RW_ATTR(name, elname)				\936	F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, name, elname)937 938#define SM_INFO_GENERAL_RW_ATTR(elname)				\939	SM_INFO_RW_ATTR(elname, elname)940 941#define DCC_INFO_RW_ATTR(name, elname)				\942	F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, name, elname)943 944#define DCC_INFO_GENERAL_RW_ATTR(elname)			\945	DCC_INFO_RW_ATTR(elname, elname)946 947#define NM_INFO_RW_ATTR(name, elname)				\948	F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, name, elname)949 950#define NM_INFO_GENERAL_RW_ATTR(elname)				\951	NM_INFO_RW_ATTR(elname, elname)952 953#define F2FS_SBI_RW_ATTR(name, elname)				\954	F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, name, elname)955 956#define F2FS_SBI_GENERAL_RW_ATTR(elname)			\957	F2FS_SBI_RW_ATTR(elname, elname)958 959#define F2FS_SBI_GENERAL_RO_ATTR(elname)			\960	F2FS_RO_ATTR(F2FS_SBI, f2fs_sb_info, elname, elname)961 962#ifdef CONFIG_F2FS_FAULT_INJECTION963#define FAULT_INFO_GENERAL_RW_ATTR(type, elname)		\964	F2FS_RW_ATTR(type, f2fs_fault_info, elname, elname)965#endif966 967#define RESERVED_BLOCKS_GENERAL_RW_ATTR(elname)			\968	F2FS_RW_ATTR(RESERVED_BLOCKS, f2fs_sb_info, elname, elname)969 970#define CPRC_INFO_GENERAL_RW_ATTR(elname)			\971	F2FS_RW_ATTR(CPRC_INFO, ckpt_req_control, elname, elname)972 973#define ATGC_INFO_RW_ATTR(name, elname)				\974	F2FS_RW_ATTR(ATGC_INFO, atgc_management, name, elname)975 976/* GC_THREAD ATTR */977GC_THREAD_RW_ATTR(gc_urgent_sleep_time, urgent_sleep_time);978GC_THREAD_RW_ATTR(gc_min_sleep_time, min_sleep_time);979GC_THREAD_RW_ATTR(gc_max_sleep_time, max_sleep_time);980GC_THREAD_RW_ATTR(gc_no_gc_sleep_time, no_gc_sleep_time);981GC_THREAD_RW_ATTR(gc_no_zoned_gc_percent, no_zoned_gc_percent);982GC_THREAD_RW_ATTR(gc_boost_zoned_gc_percent, boost_zoned_gc_percent);983GC_THREAD_RW_ATTR(gc_valid_thresh_ratio, valid_thresh_ratio);984 985/* SM_INFO ATTR */986SM_INFO_RW_ATTR(reclaim_segments, rec_prefree_segments);987SM_INFO_GENERAL_RW_ATTR(ipu_policy);988SM_INFO_GENERAL_RW_ATTR(min_ipu_util);989SM_INFO_GENERAL_RW_ATTR(min_fsync_blocks);990SM_INFO_GENERAL_RW_ATTR(min_seq_blocks);991SM_INFO_GENERAL_RW_ATTR(min_hot_blocks);992SM_INFO_GENERAL_RW_ATTR(min_ssr_sections);993SM_INFO_GENERAL_RW_ATTR(reserved_segments);994 995/* DCC_INFO ATTR */996DCC_INFO_RW_ATTR(max_small_discards, max_discards);997DCC_INFO_GENERAL_RW_ATTR(max_discard_request);998DCC_INFO_GENERAL_RW_ATTR(min_discard_issue_time);999DCC_INFO_GENERAL_RW_ATTR(mid_discard_issue_time);1000DCC_INFO_GENERAL_RW_ATTR(max_discard_issue_time);1001DCC_INFO_GENERAL_RW_ATTR(discard_io_aware_gran);1002DCC_INFO_GENERAL_RW_ATTR(discard_urgent_util);1003DCC_INFO_GENERAL_RW_ATTR(discard_granularity);1004DCC_INFO_GENERAL_RW_ATTR(max_ordered_discard);1005DCC_INFO_GENERAL_RW_ATTR(discard_io_aware);1006 1007/* NM_INFO ATTR */1008NM_INFO_RW_ATTR(max_roll_forward_node_blocks, max_rf_node_blocks);1009NM_INFO_GENERAL_RW_ATTR(ram_thresh);1010NM_INFO_GENERAL_RW_ATTR(ra_nid_pages);1011NM_INFO_GENERAL_RW_ATTR(dirty_nats_ratio);1012 1013/* F2FS_SBI ATTR */1014F2FS_RW_ATTR(F2FS_SBI, f2fs_super_block, extension_list, extension_list);1015F2FS_SBI_RW_ATTR(gc_idle, gc_mode);1016F2FS_SBI_RW_ATTR(gc_urgent, gc_mode);1017F2FS_SBI_RW_ATTR(cp_interval, interval_time[CP_TIME]);1018F2FS_SBI_RW_ATTR(idle_interval, interval_time[REQ_TIME]);1019F2FS_SBI_RW_ATTR(discard_idle_interval, interval_time[DISCARD_TIME]);1020F2FS_SBI_RW_ATTR(gc_idle_interval, interval_time[GC_TIME]);1021F2FS_SBI_RW_ATTR(umount_discard_timeout, interval_time[UMOUNT_DISCARD_TIMEOUT]);1022F2FS_SBI_RW_ATTR(gc_pin_file_thresh, gc_pin_file_threshold);1023F2FS_SBI_RW_ATTR(gc_reclaimed_segments, gc_reclaimed_segs);1024F2FS_SBI_GENERAL_RW_ATTR(max_victim_search);1025F2FS_SBI_GENERAL_RW_ATTR(migration_granularity);1026F2FS_SBI_GENERAL_RW_ATTR(migration_window_granularity);1027F2FS_SBI_GENERAL_RW_ATTR(dir_level);1028#ifdef CONFIG_F2FS_IOSTAT1029F2FS_SBI_GENERAL_RW_ATTR(iostat_enable);1030F2FS_SBI_GENERAL_RW_ATTR(iostat_period_ms);1031#endif1032F2FS_SBI_GENERAL_RW_ATTR(readdir_ra);1033F2FS_SBI_GENERAL_RW_ATTR(max_io_bytes);1034F2FS_SBI_GENERAL_RW_ATTR(data_io_flag);1035F2FS_SBI_GENERAL_RW_ATTR(node_io_flag);1036F2FS_SBI_GENERAL_RW_ATTR(gc_remaining_trials);1037F2FS_SBI_GENERAL_RW_ATTR(seq_file_ra_mul);1038F2FS_SBI_GENERAL_RW_ATTR(gc_segment_mode);1039F2FS_SBI_GENERAL_RW_ATTR(max_fragment_chunk);1040F2FS_SBI_GENERAL_RW_ATTR(max_fragment_hole);1041#ifdef CONFIG_F2FS_FS_COMPRESSION1042F2FS_SBI_GENERAL_RW_ATTR(compr_written_block);1043F2FS_SBI_GENERAL_RW_ATTR(compr_saved_block);1044F2FS_SBI_GENERAL_RW_ATTR(compr_new_inode);1045F2FS_SBI_GENERAL_RW_ATTR(compress_percent);1046F2FS_SBI_GENERAL_RW_ATTR(compress_watermark);1047#endif1048/* atomic write */1049F2FS_SBI_GENERAL_RO_ATTR(current_atomic_write);1050F2FS_SBI_GENERAL_RW_ATTR(peak_atomic_write);1051F2FS_SBI_GENERAL_RW_ATTR(committed_atomic_block);1052F2FS_SBI_GENERAL_RW_ATTR(revoked_atomic_block);1053/* block age extent cache */1054F2FS_SBI_GENERAL_RW_ATTR(hot_data_age_threshold);1055F2FS_SBI_GENERAL_RW_ATTR(warm_data_age_threshold);1056F2FS_SBI_GENERAL_RW_ATTR(last_age_weight);1057#ifdef CONFIG_BLK_DEV_ZONED1058F2FS_SBI_GENERAL_RO_ATTR(unusable_blocks_per_sec);1059F2FS_SBI_GENERAL_RW_ATTR(blkzone_alloc_policy);1060#endif1061 1062/* STAT_INFO ATTR */1063#ifdef CONFIG_F2FS_STAT_FS1064STAT_INFO_RO_ATTR(cp_foreground_calls, cp_call_count[FOREGROUND]);1065STAT_INFO_RO_ATTR(cp_background_calls, cp_call_count[BACKGROUND]);1066STAT_INFO_RO_ATTR(gc_foreground_calls, gc_call_count[FOREGROUND]);1067STAT_INFO_RO_ATTR(gc_background_calls, gc_call_count[BACKGROUND]);1068#endif1069 1070/* FAULT_INFO ATTR */1071#ifdef CONFIG_F2FS_FAULT_INJECTION1072FAULT_INFO_GENERAL_RW_ATTR(FAULT_INFO_RATE, inject_rate);1073FAULT_INFO_GENERAL_RW_ATTR(FAULT_INFO_TYPE, inject_type);1074#endif1075 1076/* RESERVED_BLOCKS ATTR */1077RESERVED_BLOCKS_GENERAL_RW_ATTR(reserved_blocks);1078 1079/* CPRC_INFO ATTR */1080CPRC_INFO_GENERAL_RW_ATTR(ckpt_thread_ioprio);1081 1082/* ATGC_INFO ATTR */1083ATGC_INFO_RW_ATTR(atgc_candidate_ratio, candidate_ratio);1084ATGC_INFO_RW_ATTR(atgc_candidate_count, max_candidate_count);1085ATGC_INFO_RW_ATTR(atgc_age_weight, age_weight);1086ATGC_INFO_RW_ATTR(atgc_age_threshold, age_threshold);1087 1088F2FS_GENERAL_RO_ATTR(dirty_segments);1089F2FS_GENERAL_RO_ATTR(free_segments);1090F2FS_GENERAL_RO_ATTR(ovp_segments);1091F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes);1092F2FS_GENERAL_RO_ATTR(features);1093F2FS_GENERAL_RO_ATTR(current_reserved_blocks);1094F2FS_GENERAL_RO_ATTR(unusable);1095F2FS_GENERAL_RO_ATTR(encoding);1096F2FS_GENERAL_RO_ATTR(mounted_time_sec);1097F2FS_GENERAL_RO_ATTR(main_blkaddr);1098F2FS_GENERAL_RO_ATTR(pending_discard);1099F2FS_GENERAL_RO_ATTR(atgc_enabled);1100F2FS_GENERAL_RO_ATTR(gc_mode);1101#ifdef CONFIG_F2FS_STAT_FS1102F2FS_GENERAL_RO_ATTR(moved_blocks_background);1103F2FS_GENERAL_RO_ATTR(moved_blocks_foreground);1104F2FS_GENERAL_RO_ATTR(avg_vblocks);1105#endif1106 1107#ifdef CONFIG_FS_ENCRYPTION1108F2FS_FEATURE_RO_ATTR(encryption);1109F2FS_FEATURE_RO_ATTR(test_dummy_encryption_v2);1110#if IS_ENABLED(CONFIG_UNICODE)1111F2FS_FEATURE_RO_ATTR(encrypted_casefold);1112#endif1113#endif /* CONFIG_FS_ENCRYPTION */1114#ifdef CONFIG_BLK_DEV_ZONED1115F2FS_FEATURE_RO_ATTR(block_zoned);1116#endif1117F2FS_FEATURE_RO_ATTR(atomic_write);1118F2FS_FEATURE_RO_ATTR(extra_attr);1119F2FS_FEATURE_RO_ATTR(project_quota);1120F2FS_FEATURE_RO_ATTR(inode_checksum);1121F2FS_FEATURE_RO_ATTR(flexible_inline_xattr);1122F2FS_FEATURE_RO_ATTR(quota_ino);1123F2FS_FEATURE_RO_ATTR(inode_crtime);1124F2FS_FEATURE_RO_ATTR(lost_found);1125#ifdef CONFIG_FS_VERITY1126F2FS_FEATURE_RO_ATTR(verity);1127#endif1128F2FS_FEATURE_RO_ATTR(sb_checksum);1129#if IS_ENABLED(CONFIG_UNICODE)1130F2FS_FEATURE_RO_ATTR(casefold);1131#endif1132F2FS_FEATURE_RO_ATTR(readonly);1133#ifdef CONFIG_F2FS_FS_COMPRESSION1134F2FS_FEATURE_RO_ATTR(compression);1135#endif1136F2FS_FEATURE_RO_ATTR(pin_file);1137 1138#define ATTR_LIST(name) (&f2fs_attr_##name.attr)1139static struct attribute *f2fs_attrs[] = {1140	ATTR_LIST(gc_urgent_sleep_time),1141	ATTR_LIST(gc_min_sleep_time),1142	ATTR_LIST(gc_max_sleep_time),1143	ATTR_LIST(gc_no_gc_sleep_time),1144	ATTR_LIST(gc_no_zoned_gc_percent),1145	ATTR_LIST(gc_boost_zoned_gc_percent),1146	ATTR_LIST(gc_valid_thresh_ratio),1147	ATTR_LIST(gc_idle),1148	ATTR_LIST(gc_urgent),1149	ATTR_LIST(reclaim_segments),1150	ATTR_LIST(main_blkaddr),1151	ATTR_LIST(max_small_discards),1152	ATTR_LIST(max_discard_request),1153	ATTR_LIST(min_discard_issue_time),1154	ATTR_LIST(mid_discard_issue_time),1155	ATTR_LIST(max_discard_issue_time),1156	ATTR_LIST(discard_io_aware_gran),1157	ATTR_LIST(discard_urgent_util),1158	ATTR_LIST(discard_granularity),1159	ATTR_LIST(max_ordered_discard),1160	ATTR_LIST(discard_io_aware),1161	ATTR_LIST(pending_discard),1162	ATTR_LIST(gc_mode),1163	ATTR_LIST(ipu_policy),1164	ATTR_LIST(min_ipu_util),1165	ATTR_LIST(min_fsync_blocks),1166	ATTR_LIST(min_seq_blocks),1167	ATTR_LIST(min_hot_blocks),1168	ATTR_LIST(min_ssr_sections),1169	ATTR_LIST(reserved_segments),1170	ATTR_LIST(max_victim_search),1171	ATTR_LIST(migration_granularity),1172	ATTR_LIST(migration_window_granularity),1173	ATTR_LIST(dir_level),1174	ATTR_LIST(ram_thresh),1175	ATTR_LIST(ra_nid_pages),1176	ATTR_LIST(dirty_nats_ratio),1177	ATTR_LIST(max_roll_forward_node_blocks),1178	ATTR_LIST(cp_interval),1179	ATTR_LIST(idle_interval),1180	ATTR_LIST(discard_idle_interval),1181	ATTR_LIST(gc_idle_interval),1182	ATTR_LIST(umount_discard_timeout),1183#ifdef CONFIG_F2FS_IOSTAT1184	ATTR_LIST(iostat_enable),1185	ATTR_LIST(iostat_period_ms),1186#endif1187	ATTR_LIST(readdir_ra),1188	ATTR_LIST(max_io_bytes),1189	ATTR_LIST(gc_pin_file_thresh),1190	ATTR_LIST(extension_list),1191#ifdef CONFIG_F2FS_FAULT_INJECTION1192	ATTR_LIST(inject_rate),1193	ATTR_LIST(inject_type),1194#endif1195	ATTR_LIST(data_io_flag),1196	ATTR_LIST(node_io_flag),1197	ATTR_LIST(gc_remaining_trials),1198	ATTR_LIST(ckpt_thread_ioprio),1199	ATTR_LIST(dirty_segments),1200	ATTR_LIST(free_segments),1201	ATTR_LIST(ovp_segments),1202	ATTR_LIST(unusable),1203	ATTR_LIST(lifetime_write_kbytes),1204	ATTR_LIST(features),1205	ATTR_LIST(reserved_blocks),1206	ATTR_LIST(current_reserved_blocks),1207	ATTR_LIST(encoding),1208	ATTR_LIST(mounted_time_sec),1209#ifdef CONFIG_F2FS_STAT_FS1210	ATTR_LIST(cp_foreground_calls),1211	ATTR_LIST(cp_background_calls),1212	ATTR_LIST(gc_foreground_calls),1213	ATTR_LIST(gc_background_calls),1214	ATTR_LIST(moved_blocks_foreground),1215	ATTR_LIST(moved_blocks_background),1216	ATTR_LIST(avg_vblocks),1217#endif1218#ifdef CONFIG_BLK_DEV_ZONED1219	ATTR_LIST(unusable_blocks_per_sec),1220	ATTR_LIST(blkzone_alloc_policy),1221#endif1222#ifdef CONFIG_F2FS_FS_COMPRESSION1223	ATTR_LIST(compr_written_block),1224	ATTR_LIST(compr_saved_block),1225	ATTR_LIST(compr_new_inode),1226	ATTR_LIST(compress_percent),1227	ATTR_LIST(compress_watermark),1228#endif1229	/* For ATGC */1230	ATTR_LIST(atgc_candidate_ratio),1231	ATTR_LIST(atgc_candidate_count),1232	ATTR_LIST(atgc_age_weight),1233	ATTR_LIST(atgc_age_threshold),1234	ATTR_LIST(atgc_enabled),1235	ATTR_LIST(seq_file_ra_mul),1236	ATTR_LIST(gc_segment_mode),1237	ATTR_LIST(gc_reclaimed_segments),1238	ATTR_LIST(max_fragment_chunk),1239	ATTR_LIST(max_fragment_hole),1240	ATTR_LIST(current_atomic_write),1241	ATTR_LIST(peak_atomic_write),1242	ATTR_LIST(committed_atomic_block),1243	ATTR_LIST(revoked_atomic_block),1244	ATTR_LIST(hot_data_age_threshold),1245	ATTR_LIST(warm_data_age_threshold),1246	ATTR_LIST(last_age_weight),1247	NULL,1248};1249ATTRIBUTE_GROUPS(f2fs);1250 1251static struct attribute *f2fs_feat_attrs[] = {1252#ifdef CONFIG_FS_ENCRYPTION1253	ATTR_LIST(encryption),1254	ATTR_LIST(test_dummy_encryption_v2),1255#if IS_ENABLED(CONFIG_UNICODE)1256	ATTR_LIST(encrypted_casefold),1257#endif1258#endif /* CONFIG_FS_ENCRYPTION */1259#ifdef CONFIG_BLK_DEV_ZONED1260	ATTR_LIST(block_zoned),1261#endif1262	ATTR_LIST(atomic_write),1263	ATTR_LIST(extra_attr),1264	ATTR_LIST(project_quota),1265	ATTR_LIST(inode_checksum),1266	ATTR_LIST(flexible_inline_xattr),1267	ATTR_LIST(quota_ino),1268	ATTR_LIST(inode_crtime),1269	ATTR_LIST(lost_found),1270#ifdef CONFIG_FS_VERITY1271	ATTR_LIST(verity),1272#endif1273	ATTR_LIST(sb_checksum),1274#if IS_ENABLED(CONFIG_UNICODE)1275	ATTR_LIST(casefold),1276#endif1277	ATTR_LIST(readonly),1278#ifdef CONFIG_F2FS_FS_COMPRESSION1279	ATTR_LIST(compression),1280#endif1281	ATTR_LIST(pin_file),1282	NULL,1283};1284ATTRIBUTE_GROUPS(f2fs_feat);1285 1286F2FS_GENERAL_RO_ATTR(sb_status);1287F2FS_GENERAL_RO_ATTR(cp_status);1288F2FS_GENERAL_RO_ATTR(issued_discard);1289F2FS_GENERAL_RO_ATTR(queued_discard);1290F2FS_GENERAL_RO_ATTR(undiscard_blks);1291 1292static struct attribute *f2fs_stat_attrs[] = {1293	ATTR_LIST(sb_status),1294	ATTR_LIST(cp_status),1295	ATTR_LIST(issued_discard),1296	ATTR_LIST(queued_discard),1297	ATTR_LIST(undiscard_blks),1298	NULL,1299};1300ATTRIBUTE_GROUPS(f2fs_stat);1301 1302F2FS_SB_FEATURE_RO_ATTR(encryption, ENCRYPT);1303F2FS_SB_FEATURE_RO_ATTR(block_zoned, BLKZONED);1304F2FS_SB_FEATURE_RO_ATTR(extra_attr, EXTRA_ATTR);1305F2FS_SB_FEATURE_RO_ATTR(project_quota, PRJQUOTA);1306F2FS_SB_FEATURE_RO_ATTR(inode_checksum, INODE_CHKSUM);1307F2FS_SB_FEATURE_RO_ATTR(flexible_inline_xattr, FLEXIBLE_INLINE_XATTR);1308F2FS_SB_FEATURE_RO_ATTR(quota_ino, QUOTA_INO);1309F2FS_SB_FEATURE_RO_ATTR(inode_crtime, INODE_CRTIME);1310F2FS_SB_FEATURE_RO_ATTR(lost_found, LOST_FOUND);1311F2FS_SB_FEATURE_RO_ATTR(verity, VERITY);1312F2FS_SB_FEATURE_RO_ATTR(sb_checksum, SB_CHKSUM);1313F2FS_SB_FEATURE_RO_ATTR(casefold, CASEFOLD);1314F2FS_SB_FEATURE_RO_ATTR(compression, COMPRESSION);1315F2FS_SB_FEATURE_RO_ATTR(readonly, RO);1316 1317static struct attribute *f2fs_sb_feat_attrs[] = {1318	ATTR_LIST(sb_encryption),1319	ATTR_LIST(sb_block_zoned),1320	ATTR_LIST(sb_extra_attr),1321	ATTR_LIST(sb_project_quota),1322	ATTR_LIST(sb_inode_checksum),1323	ATTR_LIST(sb_flexible_inline_xattr),1324	ATTR_LIST(sb_quota_ino),1325	ATTR_LIST(sb_inode_crtime),1326	ATTR_LIST(sb_lost_found),1327	ATTR_LIST(sb_verity),1328	ATTR_LIST(sb_sb_checksum),1329	ATTR_LIST(sb_casefold),1330	ATTR_LIST(sb_compression),1331	ATTR_LIST(sb_readonly),1332	NULL,1333};1334ATTRIBUTE_GROUPS(f2fs_sb_feat);1335 1336static const struct sysfs_ops f2fs_attr_ops = {1337	.show	= f2fs_attr_show,1338	.store	= f2fs_attr_store,1339};1340 1341static const struct kobj_type f2fs_sb_ktype = {1342	.default_groups = f2fs_groups,1343	.sysfs_ops	= &f2fs_attr_ops,1344	.release	= f2fs_sb_release,1345};1346 1347static const struct kobj_type f2fs_ktype = {1348	.sysfs_ops	= &f2fs_attr_ops,1349};1350 1351static struct kset f2fs_kset = {1352	.kobj	= {.ktype = &f2fs_ktype},1353};1354 1355static const struct kobj_type f2fs_feat_ktype = {1356	.default_groups = f2fs_feat_groups,1357	.sysfs_ops	= &f2fs_attr_ops,1358};1359 1360static struct kobject f2fs_feat = {1361	.kset	= &f2fs_kset,1362};1363 1364static ssize_t f2fs_stat_attr_show(struct kobject *kobj,1365				struct attribute *attr, char *buf)1366{1367	struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,1368								s_stat_kobj);1369	struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);1370 1371	return a->show ? a->show(a, sbi, buf) : 0;1372}1373 1374static ssize_t f2fs_stat_attr_store(struct kobject *kobj, struct attribute *attr,1375						const char *buf, size_t len)1376{1377	struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,1378								s_stat_kobj);1379	struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);1380 1381	return a->store ? a->store(a, sbi, buf, len) : 0;1382}1383 1384static void f2fs_stat_kobj_release(struct kobject *kobj)1385{1386	struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,1387								s_stat_kobj);1388	complete(&sbi->s_stat_kobj_unregister);1389}1390 1391static const struct sysfs_ops f2fs_stat_attr_ops = {1392	.show	= f2fs_stat_attr_show,1393	.store	= f2fs_stat_attr_store,1394};1395 1396static const struct kobj_type f2fs_stat_ktype = {1397	.default_groups = f2fs_stat_groups,1398	.sysfs_ops	= &f2fs_stat_attr_ops,1399	.release	= f2fs_stat_kobj_release,1400};1401 1402static ssize_t f2fs_sb_feat_attr_show(struct kobject *kobj,1403				struct attribute *attr, char *buf)1404{1405	struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,1406							s_feature_list_kobj);1407	struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);1408 1409	return a->show ? a->show(a, sbi, buf) : 0;1410}1411 1412static void f2fs_feature_list_kobj_release(struct kobject *kobj)1413{1414	struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,1415							s_feature_list_kobj);1416	complete(&sbi->s_feature_list_kobj_unregister);1417}1418 1419static const struct sysfs_ops f2fs_feature_list_attr_ops = {1420	.show	= f2fs_sb_feat_attr_show,1421};1422 1423static const struct kobj_type f2fs_feature_list_ktype = {1424	.default_groups = f2fs_sb_feat_groups,1425	.sysfs_ops	= &f2fs_feature_list_attr_ops,1426	.release	= f2fs_feature_list_kobj_release,1427};1428 1429static int __maybe_unused segment_info_seq_show(struct seq_file *seq,1430						void *offset)1431{1432	struct super_block *sb = seq->private;1433	struct f2fs_sb_info *sbi = F2FS_SB(sb);1434	unsigned int total_segs =1435			le32_to_cpu(sbi->raw_super->segment_count_main);1436	int i;1437 1438	seq_puts(seq, "format: segment_type|valid_blocks\n"1439		"segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)\n");1440 1441	for (i = 0; i < total_segs; i++) {1442		struct seg_entry *se = get_seg_entry(sbi, i);1443 1444		if ((i % 10) == 0)1445			seq_printf(seq, "%-10d", i);1446		seq_printf(seq, "%d|%-3u", se->type, se->valid_blocks);1447		if ((i % 10) == 9 || i == (total_segs - 1))1448			seq_putc(seq, '\n');1449		else1450			seq_putc(seq, ' ');1451	}1452 1453	return 0;1454}1455 1456static int __maybe_unused segment_bits_seq_show(struct seq_file *seq,1457						void *offset)1458{1459	struct super_block *sb = seq->private;1460	struct f2fs_sb_info *sbi = F2FS_SB(sb);1461	unsigned int total_segs =1462			le32_to_cpu(sbi->raw_super->segment_count_main);1463	int i, j;1464 1465	seq_puts(seq, "format: segment_type|valid_blocks|bitmaps\n"1466		"segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)\n");1467 1468	for (i = 0; i < total_segs; i++) {1469		struct seg_entry *se = get_seg_entry(sbi, i);1470 1471		seq_printf(seq, "%-10d", i);1472		seq_printf(seq, "%d|%-3u|", se->type, se->valid_blocks);1473		for (j = 0; j < SIT_VBLOCK_MAP_SIZE; j++)1474			seq_printf(seq, " %.2x", se->cur_valid_map[j]);1475		seq_putc(seq, '\n');1476	}1477	return 0;1478}1479 1480static int __maybe_unused victim_bits_seq_show(struct seq_file *seq,1481						void *offset)1482{1483	struct super_block *sb = seq->private;1484	struct f2fs_sb_info *sbi = F2FS_SB(sb);1485	struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);1486	int i;1487 1488	seq_puts(seq, "format: victim_secmap bitmaps\n");1489 1490	for (i = 0; i < MAIN_SECS(sbi); i++) {1491		if ((i % 10) == 0)1492			seq_printf(seq, "%-10d", i);1493		seq_printf(seq, "%d", test_bit(i, dirty_i->victim_secmap) ? 1 : 0);1494		if ((i % 10) == 9 || i == (MAIN_SECS(sbi) - 1))1495			seq_putc(seq, '\n');1496		else1497			seq_putc(seq, ' ');1498	}1499	return 0;1500}1501 1502static int __maybe_unused discard_plist_seq_show(struct seq_file *seq,1503						void *offset)1504{1505	struct super_block *sb = seq->private;1506	struct f2fs_sb_info *sbi = F2FS_SB(sb);1507	struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;1508	int i, count;1509 1510	seq_puts(seq, "Discard pend list(Show diacrd_cmd count on each entry, .:not exist):\n");1511	if (!f2fs_realtime_discard_enable(sbi))1512		return 0;1513 1514	if (dcc) {1515		mutex_lock(&dcc->cmd_lock);1516		for (i = 0; i < MAX_PLIST_NUM; i++) {1517			struct list_head *pend_list;1518			struct discard_cmd *dc, *tmp;1519 1520			if (i % 8 == 0)1521				seq_printf(seq, "  %-3d", i);1522			count = 0;1523			pend_list = &dcc->pend_list[i];1524			list_for_each_entry_safe(dc, tmp, pend_list, list)1525				count++;1526			if (count)1527				seq_printf(seq, " %7d", count);1528			else1529				seq_puts(seq, "       .");1530			if (i % 8 == 7)1531				seq_putc(seq, '\n');1532		}1533		seq_putc(seq, '\n');1534		mutex_unlock(&dcc->cmd_lock);1535	}1536 1537	return 0;1538}1539 1540static int __maybe_unused disk_map_seq_show(struct seq_file *seq,1541						void *offset)1542{1543	struct super_block *sb = seq->private;1544	struct f2fs_sb_info *sbi = F2FS_SB(sb);1545	int i;1546 1547	seq_printf(seq, "Address Layout   : %5luB Block address (# of Segments)\n",1548					F2FS_BLKSIZE);1549	seq_printf(seq, " SB            : %12s\n", "0/1024B");1550	seq_printf(seq, " seg0_blkaddr  : 0x%010x\n", SEG0_BLKADDR(sbi));1551	seq_printf(seq, " Checkpoint    : 0x%010x (%10d)\n",1552			le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_blkaddr), 2);1553	seq_printf(seq, " SIT           : 0x%010x (%10d)\n",1554			SIT_I(sbi)->sit_base_addr,1555			le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment_count_sit));1556	seq_printf(seq, " NAT           : 0x%010x (%10d)\n",1557			NM_I(sbi)->nat_blkaddr,1558			le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment_count_nat));1559	seq_printf(seq, " SSA           : 0x%010x (%10d)\n",1560			SM_I(sbi)->ssa_blkaddr,1561			le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment_count_ssa));1562	seq_printf(seq, " Main          : 0x%010x (%10d)\n",1563			SM_I(sbi)->main_blkaddr,1564			le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment_count_main));1565	seq_printf(seq, " # of Sections : %12d\n",1566			le32_to_cpu(F2FS_RAW_SUPER(sbi)->section_count));1567	seq_printf(seq, " Segs/Sections : %12d\n",1568			SEGS_PER_SEC(sbi));1569	seq_printf(seq, " Section size  : %12d MB\n",1570			SEGS_PER_SEC(sbi) << 1);1571 1572	if (!f2fs_is_multi_device(sbi))1573		return 0;1574 1575	seq_puts(seq, "\nDisk Map for multi devices:\n");1576	for (i = 0; i < sbi->s_ndevs; i++)1577		seq_printf(seq, "Disk:%2d (zoned=%d): 0x%010x - 0x%010x on %s\n",1578			i, bdev_is_zoned(FDEV(i).bdev),1579			FDEV(i).start_blk, FDEV(i).end_blk,1580			FDEV(i).path);1581	return 0;1582}1583 1584int __init f2fs_init_sysfs(void)1585{1586	int ret;1587 1588	kobject_set_name(&f2fs_kset.kobj, "f2fs");1589	f2fs_kset.kobj.parent = fs_kobj;1590	ret = kset_register(&f2fs_kset);1591	if (ret)1592		return ret;1593 1594	ret = kobject_init_and_add(&f2fs_feat, &f2fs_feat_ktype,1595				   NULL, "features");1596	if (ret)1597		goto put_kobject;1598 1599	f2fs_proc_root = proc_mkdir("fs/f2fs", NULL);1600	if (!f2fs_proc_root) {1601		ret = -ENOMEM;1602		goto put_kobject;1603	}1604 1605	return 0;1606put_kobject:1607	kobject_put(&f2fs_feat);1608	kset_unregister(&f2fs_kset);1609	return ret;1610}1611 1612void f2fs_exit_sysfs(void)1613{1614	kobject_put(&f2fs_feat);1615	kset_unregister(&f2fs_kset);1616	remove_proc_entry("fs/f2fs", NULL);1617	f2fs_proc_root = NULL;1618}1619 1620int f2fs_register_sysfs(struct f2fs_sb_info *sbi)1621{1622	struct super_block *sb = sbi->sb;1623	int err;1624 1625	sbi->s_kobj.kset = &f2fs_kset;1626	init_completion(&sbi->s_kobj_unregister);1627	err = kobject_init_and_add(&sbi->s_kobj, &f2fs_sb_ktype, NULL,1628				"%s", sb->s_id);1629	if (err)1630		goto put_sb_kobj;1631 1632	sbi->s_stat_kobj.kset = &f2fs_kset;1633	init_completion(&sbi->s_stat_kobj_unregister);1634	err = kobject_init_and_add(&sbi->s_stat_kobj, &f2fs_stat_ktype,1635						&sbi->s_kobj, "stat");1636	if (err)1637		goto put_stat_kobj;1638 1639	sbi->s_feature_list_kobj.kset = &f2fs_kset;1640	init_completion(&sbi->s_feature_list_kobj_unregister);1641	err = kobject_init_and_add(&sbi->s_feature_list_kobj,1642					&f2fs_feature_list_ktype,1643					&sbi->s_kobj, "feature_list");1644	if (err)1645		goto put_feature_list_kobj;1646 1647	sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root);1648	if (!sbi->s_proc) {1649		err = -ENOMEM;1650		goto put_feature_list_kobj;1651	}1652 1653	proc_create_single_data("segment_info", 0444, sbi->s_proc,1654				segment_info_seq_show, sb);1655	proc_create_single_data("segment_bits", 0444, sbi->s_proc,1656				segment_bits_seq_show, sb);1657#ifdef CONFIG_F2FS_IOSTAT1658	proc_create_single_data("iostat_info", 0444, sbi->s_proc,1659				iostat_info_seq_show, sb);1660#endif1661	proc_create_single_data("victim_bits", 0444, sbi->s_proc,1662				victim_bits_seq_show, sb);1663	proc_create_single_data("discard_plist_info", 0444, sbi->s_proc,1664				discard_plist_seq_show, sb);1665	proc_create_single_data("disk_map", 0444, sbi->s_proc,1666				disk_map_seq_show, sb);1667	return 0;1668put_feature_list_kobj:1669	kobject_put(&sbi->s_feature_list_kobj);1670	wait_for_completion(&sbi->s_feature_list_kobj_unregister);1671put_stat_kobj:1672	kobject_put(&sbi->s_stat_kobj);1673	wait_for_completion(&sbi->s_stat_kobj_unregister);1674put_sb_kobj:1675	kobject_put(&sbi->s_kobj);1676	wait_for_completion(&sbi->s_kobj_unregister);1677	return err;1678}1679 1680void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi)1681{1682	remove_proc_subtree(sbi->sb->s_id, f2fs_proc_root);1683 1684	kobject_put(&sbi->s_stat_kobj);1685	wait_for_completion(&sbi->s_stat_kobj_unregister);1686	kobject_put(&sbi->s_feature_list_kobj);1687	wait_for_completion(&sbi->s_feature_list_kobj_unregister);1688 1689	kobject_put(&sbi->s_kobj);1690	wait_for_completion(&sbi->s_kobj_unregister);1691}1692