Commit b0fcf560 authored by Chao Yu's avatar Chao Yu Committed by Yifan Qiao
Browse files

f2fs: reduce stack memory cost by using bitfield in struct f2fs_io_info

mainline inclusion
from mainline-v6.3-rc1
commit 2eae077e
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9L9NO
CVE: CVE-2024-27034

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2eae077e6e46f9046d383631145750e043820dce



--------------------------------

This patch tries to use bitfield in struct f2fs_io_info to improve
memory usage.

struct f2fs_io_info {
...
	unsigned int need_lock:8;	/* indicate we need to lock cp_rwsem */
	unsigned int version:8;		/* version of the node */
	unsigned int submitted:1;	/* indicate IO submission */
	unsigned int in_list:1;		/* indicate fio is in io_list */
	unsigned int is_por:1;		/* indicate IO is from recovery or not */
	unsigned int retry:1;		/* need to reallocate block address */
	unsigned int encrypted:1;	/* indicate file is encrypted */
	unsigned int post_read:1;	/* require post read */
...
};

After this patch, size of struct f2fs_io_info reduces from 136 to 120.

[Nathan: fix a compile warning (single-bit-bitfield-constant-conversion)]
Signed-off-by: default avatarNathan Chancellor <nathan@kernel.org>
Signed-off-by: default avatarChao Yu <chao@kernel.org>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
Conflicts:
	fs/f2fs/data.c
[qyf: fix context conflict only]
Signed-off-by: default avatarYifan Qiao <qiaoyifan4@huawei.com>
parent 30e7a06d
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -63,7 +63,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;

@@ -226,8 +226,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;
+3 −2
Original line number Diff line number Diff line
@@ -1152,10 +1152,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;
+5 −5
Original line number Diff line number Diff line
@@ -972,7 +972,7 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio)
		bio_page = fio->page;

	/* set submitted = true as a return value */
	fio->submitted = true;
	fio->submitted = 1;

	type = WB_DATA_TYPE(bio_page, fio->compressed_page);
	inc_page_count(sbi, type);
@@ -990,7 +990,7 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio)
				fio->new_blkaddr & F2FS_IO_SIZE_MASK(sbi)) {
			dec_page_count(sbi, WB_DATA_TYPE(bio_page,
						fio->compressed_page));
			fio->retry = true;
			fio->retry = 1;
			goto skip;
		}
		io->bio = __bio_alloc(fio, BIO_MAX_PAGES);
@@ -2795,10 +2795,10 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
		.old_blkaddr = NULL_ADDR,
		.page = page,
		.encrypted_page = NULL,
		.submitted = false,
		.submitted = 0,
		.compr_blocks = compr_blocks,
		.need_lock = LOCK_RETRY,
		.post_read = f2fs_post_read_required(inode),
		.post_read = f2fs_post_read_required(inode) ? 1 : 0,
		.io_type = io_type,
		.io_wbc = wbc,
		.bio = bio,
@@ -2926,7 +2926,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
	}

	if (submitted)
		*submitted = fio.submitted ? 1 : 0;
		*submitted = fio.submitted;

	return 0;

+9 −9
Original line number Diff line number Diff line
@@ -1111,19 +1111,19 @@ struct f2fs_io_info {
	struct page *encrypted_page;	/* encrypted page */
	struct page *compressed_page;	/* compressed page */
	struct list_head list;		/* serialize IOs */
	bool submitted;		/* indicate IO submission */
	int need_lock;		/* indicate we need to lock cp_rwsem */
	bool in_list;		/* indicate fio is in io_list */
	bool is_por;		/* indicate IO is from recovery or not */
	bool retry;		/* need to reallocate block address */
	int compr_blocks;	/* # of compressed block addresses */
	bool encrypted;		/* indicate file is encrypted */
	bool post_read;		/* require post read */
	unsigned int compr_blocks;	/* # of compressed block addresses */
	unsigned int need_lock:8;	/* indicate we need to lock cp_rwsem */
	unsigned int version:8;		/* version of the node */
	unsigned int submitted:1;	/* indicate IO submission */
	unsigned int in_list:1;		/* indicate fio is in io_list */
	unsigned int is_por:1;		/* indicate IO is from recovery or not */
	unsigned int retry:1;		/* need to reallocate block address */
	unsigned int encrypted:1;	/* indicate file is encrypted */
	unsigned int post_read:1;	/* require post read */
	enum iostat_type io_type;	/* io type */
	struct writeback_control *io_wbc; /* writeback control */
	struct bio **bio;		/* bio for ipu */
	sector_t *last_block;		/* last block number in bio */
	unsigned char version;		/* version of the node */
};

struct bio_entry {
+4 −4
Original line number Diff line number Diff line
@@ -1056,8 +1056,8 @@ static int ra_data_block(struct inode *inode, pgoff_t index)
		.op = REQ_OP_READ,
		.op_flags = 0,
		.encrypted_page = NULL,
		.in_list = false,
		.retry = false,
		.in_list = 0,
		.retry = 0,
	};
	int err;

@@ -1143,8 +1143,8 @@ static int move_data_block(struct inode *inode, block_t bidx,
		.op = REQ_OP_READ,
		.op_flags = 0,
		.encrypted_page = NULL,
		.in_list = false,
		.retry = false,
		.in_list = 0,
		.retry = 0,
	};
	struct dnode_of_data dn;
	struct f2fs_summary sum;
Loading