Commit 10383068 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull f2fs updates from Jaegeuk Kim:
 "In this round, we've got a huge number of patches that improve code
  readability along with minor bug fixes, while we've mainly fixed some
  critical issues in recently-added per-block age-based extent_cache,
  atomic write support, and some folio cases.

  Enhancements:

   - add sysfs nodes to set last_age_weight and manage
     discard_io_aware_gran

   - show ipu policy in debugfs

   - reduce stack memory cost by using bitfield in struct f2fs_io_info

   - introduce trace_f2fs_replace_atomic_write_block

   - enhance iostat support and adds flush commands

  Bug fixes:

   - revert "f2fs: truncate blocks in batch in __complete_revoke_list()"

   - fix kernel crash on the atomic write abort flow

   - call clear_page_private_reference in .{release,invalid}_folio

   - support .migrate_folio for compressed inode

   - fix cgroup writeback accounting with fs-layer encryption

   - retry to update the inode page given data corruption

   - fix kernel crash due to NULL io->bio

   - fix some bugs in per-block age-based extent_cache:
       - wrong calculation of block age
       - update age extent in f2fs_do_zero_range()
       - update age extent correctly during truncation"

* tag 'f2fs-for-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (81 commits)
  f2fs: drop unnecessary arg for f2fs_ioc_*()
  f2fs: Revert "f2fs: truncate blocks in batch in __complete_revoke_list()"
  f2fs: synchronize atomic write aborts
  f2fs: fix wrong segment count
  f2fs: replace si->sbi w/ sbi in stat_show()
  f2fs: export ipu policy in debugfs
  f2fs: make kobj_type structures constant
  f2fs: fix to do sanity check on extent cache correctly
  f2fs: add missing description for ipu_policy node
  f2fs: fix to set ipu policy
  f2fs: fix typos in comments
  f2fs: fix kernel crash due to null io->bio
  f2fs: use iostat_lat_type directly as a parameter in the iostat_update_and_unbind_ctx()
  f2fs: add sysfs nodes to set last_age_weight
  f2fs: fix f2fs_show_options to show nogc_merge mount option
  f2fs: fix cgroup writeback accounting with fs-layer encryption
  f2fs: fix wrong calculation of block age
  f2fs: fix to update age extent in f2fs_do_zero_range()
  f2fs: fix to update age extent correctly during truncation
  f2fs: fix to avoid potential memory corruption in __update_iostat_latency()
  ...
parents 46d733d0 ddf1eca4
Loading
Loading
Loading
Loading
+70 −10
Original line number Diff line number Diff line
@@ -49,16 +49,23 @@ Contact: "Jaegeuk Kim" <jaegeuk.kim@samsung.com>
Description:	Controls the in-place-update policy.
		updates in f2fs. User can set:

		====  =================
		0x01  F2FS_IPU_FORCE
		0x02  F2FS_IPU_SSR
		0x04  F2FS_IPU_UTIL
		0x08  F2FS_IPU_SSR_UTIL
		0x10  F2FS_IPU_FSYNC
		0x20  F2FS_IPU_ASYNC
		0x40  F2FS_IPU_NOCACHE
		0x80  F2FS_IPU_HONOR_OPU_WRITE
		====  =================
		===== =============== ===================================================
		value policy          description
		0x00  DISABLE         disable IPU(=default option in LFS mode)
		0x01  FORCE           all the time
		0x02  SSR             if SSR mode is activated
		0x04  UTIL            if FS utilization is over threashold
		0x08  SSR_UTIL        if SSR mode is activated and FS utilization is over
		                      threashold
		0x10  FSYNC           activated in fsync path only for high performance
		                      flash storages. IPU will be triggered only if the
		                      # of dirty pages over min_fsync_blocks.
		                      (=default option)
		0x20  ASYNC           do IPU given by asynchronous write requests
		0x40  NOCACHE         disable IPU bio cache
		0x80  HONOR_OPU_WRITE use OPU write prior to IPU write if inode has
		                      FI_OPU_WRITE flag
		===== =============== ===================================================

		Refer segment.h for details.

@@ -669,3 +676,56 @@ Contact: "Ping Xiong" <xiongping1@xiaomi.com>
Description:	When DATA SEPARATION is on, it controls the age threshold to indicate
		the data blocks as warm. By default it was initialized as 2621440 blocks
		(equals to 10GB).

What:		/sys/fs/f2fs/<disk>/fault_rate
Date:		May 2016
Contact:	"Sheng Yong" <shengyong@oppo.com>
Contact:	"Chao Yu" <chao@kernel.org>
Description:	Enable fault injection in all supported types with
		specified injection rate.

What:		/sys/fs/f2fs/<disk>/fault_type
Date:		May 2016
Contact:	"Sheng Yong" <shengyong@oppo.com>
Contact:	"Chao Yu" <chao@kernel.org>
Description:	Support configuring fault injection type, should be
		enabled with fault_injection option, fault type value
		is shown below, it supports single or combined type.

		===================      ===========
		Type_Name                Type_Value
		===================      ===========
		FAULT_KMALLOC            0x000000001
		FAULT_KVMALLOC           0x000000002
		FAULT_PAGE_ALLOC         0x000000004
		FAULT_PAGE_GET           0x000000008
		FAULT_ALLOC_BIO          0x000000010 (obsolete)
		FAULT_ALLOC_NID          0x000000020
		FAULT_ORPHAN             0x000000040
		FAULT_BLOCK              0x000000080
		FAULT_DIR_DEPTH          0x000000100
		FAULT_EVICT_INODE        0x000000200
		FAULT_TRUNCATE           0x000000400
		FAULT_READ_IO            0x000000800
		FAULT_CHECKPOINT         0x000001000
		FAULT_DISCARD            0x000002000
		FAULT_WRITE_IO           0x000004000
		FAULT_SLAB_ALLOC         0x000008000
		FAULT_DQUOT_INIT         0x000010000
		FAULT_LOCK_OP            0x000020000
		FAULT_BLKADDR            0x000040000
		===================      ===========

What:		/sys/fs/f2fs/<disk>/discard_io_aware_gran
Date:		January 2023
Contact:	"Yangtao Li" <frank.li@vivo.com>
Description:	Controls background discard granularity of inner discard thread
		when is not in idle. Inner thread will not issue discards with size that
		is smaller than granularity. The unit size is one block(4KB), now only
		support configuring in range of [0, 512].
		Default: 512

What:		/sys/fs/f2fs/<disk>/last_age_weight
Date:		January 2023
Contact:	"Ping Xiong" <xiongping1@xiaomi.com>
Description:	When DATA SEPARATION is on, it controls the weight of last data block age.
+1 −0
Original line number Diff line number Diff line
@@ -7795,6 +7795,7 @@ M: Chao Yu <chao@kernel.org>
L:	linux-f2fs-devel@lists.sourceforge.net
S:	Maintained
W:	https://f2fs.wiki.kernel.org/
Q:	https://patchwork.kernel.org/project/f2fs/list/
B:	https://bugzilla.kernel.org/enter_bug.cgi?product=File%20System&component=f2fs
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git
F:	Documentation/ABI/testing/sysfs-fs-f2fs
+16 −21
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index,
		.old_blkaddr = index,
		.new_blkaddr = index,
		.encrypted_page = NULL,
		.is_por = !is_meta,
		.is_por = !is_meta ? 1 : 0,
	};
	int err;

@@ -171,10 +171,8 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr,
bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
					block_t blkaddr, int type)
{
	if (time_to_inject(sbi, FAULT_BLKADDR)) {
		f2fs_show_injection_info(sbi, FAULT_BLKADDR);
	if (time_to_inject(sbi, FAULT_BLKADDR))
		return false;
	}

	switch (type) {
	case META_NAT:
@@ -239,8 +237,8 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
		.op = REQ_OP_READ,
		.op_flags = sync ? (REQ_META | REQ_PRIO) : REQ_RAHEAD,
		.encrypted_page = NULL,
		.in_list = false,
		.is_por = (type == META_POR),
		.in_list = 0,
		.is_por = (type == META_POR) ? 1 : 0,
	};
	struct blk_plug plug;
	int err;
@@ -625,7 +623,6 @@ int f2fs_acquire_orphan_inode(struct f2fs_sb_info *sbi)

	if (time_to_inject(sbi, FAULT_ORPHAN)) {
		spin_unlock(&im->ino_lock);
		f2fs_show_injection_info(sbi, FAULT_ORPHAN);
		return -ENOSPC;
	}

@@ -798,7 +795,7 @@ static void write_orphan_inodes(struct f2fs_sb_info *sbi, block_t start_blk)
	 */
	head = &im->ino_list;

	/* loop for each orphan inode entry and write them in Jornal block */
	/* loop for each orphan inode entry and write them in journal block */
	list_for_each_entry(orphan, head, list) {
		if (!page) {
			page = f2fs_grab_meta_page(sbi, start_blk++);
@@ -1128,7 +1125,7 @@ int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type,
	} else {
		/*
		 * We should submit bio, since it exists several
		 * wribacking dentry pages in the freeing inode.
		 * writebacking dentry pages in the freeing inode.
		 */
		f2fs_submit_merged_write(sbi, DATA);
		cond_resched();
@@ -1476,20 +1473,18 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
	ckpt->elapsed_time = cpu_to_le64(get_mtime(sbi, true));
	ckpt->free_segment_count = cpu_to_le32(free_segments(sbi));
	for (i = 0; i < NR_CURSEG_NODE_TYPE; i++) {
		ckpt->cur_node_segno[i] =
			cpu_to_le32(curseg_segno(sbi, i + CURSEG_HOT_NODE));
		ckpt->cur_node_blkoff[i] =
			cpu_to_le16(curseg_blkoff(sbi, i + CURSEG_HOT_NODE));
		ckpt->alloc_type[i + CURSEG_HOT_NODE] =
				curseg_alloc_type(sbi, i + CURSEG_HOT_NODE);
		struct curseg_info *curseg = CURSEG_I(sbi, i + CURSEG_HOT_NODE);

		ckpt->cur_node_segno[i] = cpu_to_le32(curseg->segno);
		ckpt->cur_node_blkoff[i] = cpu_to_le16(curseg->next_blkoff);
		ckpt->alloc_type[i + CURSEG_HOT_NODE] = curseg->alloc_type;
	}
	for (i = 0; i < NR_CURSEG_DATA_TYPE; i++) {
		ckpt->cur_data_segno[i] =
			cpu_to_le32(curseg_segno(sbi, i + CURSEG_HOT_DATA));
		ckpt->cur_data_blkoff[i] =
			cpu_to_le16(curseg_blkoff(sbi, i + CURSEG_HOT_DATA));
		ckpt->alloc_type[i + CURSEG_HOT_DATA] =
				curseg_alloc_type(sbi, i + CURSEG_HOT_DATA);
		struct curseg_info *curseg = CURSEG_I(sbi, i + CURSEG_HOT_DATA);

		ckpt->cur_data_segno[i] = cpu_to_le32(curseg->segno);
		ckpt->cur_data_blkoff[i] = cpu_to_le16(curseg->next_blkoff);
		ckpt->alloc_type[i + CURSEG_HOT_DATA] = curseg->alloc_type;
	}

	/* 2 cp + n data seg summary + orphan inode blocks */
+11 −13
Original line number Diff line number Diff line
@@ -241,7 +241,7 @@ static int lz4_init_compress_ctx(struct compress_ctx *cc)
	unsigned int size = LZ4_MEM_COMPRESS;

#ifdef CONFIG_F2FS_FS_LZ4HC
	if (F2FS_I(cc->inode)->i_compress_flag >> COMPRESS_LEVEL_OFFSET)
	if (F2FS_I(cc->inode)->i_compress_level)
		size = LZ4HC_MEM_COMPRESS;
#endif

@@ -267,8 +267,7 @@ static void lz4_destroy_compress_ctx(struct compress_ctx *cc)
#ifdef CONFIG_F2FS_FS_LZ4HC
static int lz4hc_compress_pages(struct compress_ctx *cc)
{
	unsigned char level = F2FS_I(cc->inode)->i_compress_flag >>
						COMPRESS_LEVEL_OFFSET;
	unsigned char level = F2FS_I(cc->inode)->i_compress_level;
	int len;

	if (level)
@@ -340,8 +339,7 @@ static int zstd_init_compress_ctx(struct compress_ctx *cc)
	zstd_cstream *stream;
	void *workspace;
	unsigned int workspace_size;
	unsigned char level = F2FS_I(cc->inode)->i_compress_flag >>
						COMPRESS_LEVEL_OFFSET;
	unsigned char level = F2FS_I(cc->inode)->i_compress_level;

	if (!level)
		level = F2FS_ZSTD_DEFAULT_CLEVEL;
@@ -564,7 +562,7 @@ module_param(num_compress_pages, uint, 0444);
MODULE_PARM_DESC(num_compress_pages,
		"Number of intermediate compress pages to preallocate");

int f2fs_init_compress_mempool(void)
int __init f2fs_init_compress_mempool(void)
{
	compress_page_pool = mempool_create_page_pool(num_compress_pages, 0);
	return compress_page_pool ? 0 : -ENOMEM;
@@ -690,9 +688,7 @@ static int f2fs_compress_pages(struct compress_ctx *cc)
	vm_unmap_ram(cc->cbuf, cc->nr_cpages);
	vm_unmap_ram(cc->rbuf, cc->cluster_size);

	for (i = 0; i < cc->nr_cpages; i++) {
		if (i < new_nr_cpages)
			continue;
	for (i = new_nr_cpages; i < cc->nr_cpages; i++) {
		f2fs_compress_free_page(cc->cpages[i]);
		cc->cpages[i] = NULL;
	}
@@ -1070,7 +1066,7 @@ static int prepare_compress_overwrite(struct compress_ctx *cc,
		if (ret)
			goto out;
		if (bio)
			f2fs_submit_bio(sbi, bio, DATA);
			f2fs_submit_read_bio(sbi, bio, DATA);

		ret = f2fs_init_compress_ctx(cc);
		if (ret)
@@ -1215,10 +1211,11 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
		.page = NULL,
		.encrypted_page = NULL,
		.compressed_page = NULL,
		.submitted = false,
		.submitted = 0,
		.io_type = io_type,
		.io_wbc = wbc,
		.encrypted = fscrypt_inode_uses_fs_layer_crypto(cc->inode),
		.encrypted = fscrypt_inode_uses_fs_layer_crypto(cc->inode) ?
									1 : 0,
	};
	struct dnode_of_data dn;
	struct node_info ni;
@@ -1228,7 +1225,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
	loff_t psize;
	int i, err;

	/* we should bypass data pages to proceed the kworkder jobs */
	/* we should bypass data pages to proceed the kworker jobs */
	if (unlikely(f2fs_cp_error(sbi))) {
		mapping_set_error(cc->rpages[0]->mapping, -EIO);
		goto out_free;
@@ -1813,6 +1810,7 @@ unsigned int f2fs_cluster_blocks_are_contiguous(struct dnode_of_data *dn)
const struct address_space_operations f2fs_compress_aops = {
	.release_folio = f2fs_release_folio,
	.invalidate_folio = f2fs_invalidate_folio,
	.migrate_folio	= filemap_migrate_folio,
};

struct address_space *COMPRESS_MAPPING(struct f2fs_sb_info *sbi)
+313 −311

File changed.

Preview size limit exceeded, changes collapsed.

Loading