Unverified Commit 82a1d540 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!7042 CVE-2024-27034

Merge Pull Request from: @ci-robot 
 
PR sync from: Yifan Qiao <qiaoyifan4@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/4KM5I6I6OUB2L6CN5SAXEYGALG226PEU/ 
Chao Yu (3):
  f2fs: fix to stop filesystem update once CP failed
  f2fs: reduce stack memory cost by using bitfield in struct
    f2fs_io_info
  f2fs: compress: fix to cover normal cluster write with cp_rwsem

NeilBrown (1):
  f2fs: replace congestion_wait() calls with io_schedule_timeout()


-- 
2.39.2
 
https://gitee.com/src-openeuler/kernel/issues/I9L9NO 
 
Link:https://gitee.com/openeuler/kernel/pulls/7042

 

Reviewed-by: default avatarzhangyi (F) <yi.zhang@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parents 717ca4fe f8ef2736
Loading
Loading
Loading
Loading
+12 −6
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;
@@ -1645,8 +1645,11 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)

	/* write cached NAT/SIT entries to NAT/SIT area */
	err = f2fs_flush_nat_entries(sbi, cpc);
	if (err)
	if (err) {
		f2fs_err(sbi, "f2fs_flush_nat_entries failed err:%d, stop checkpoint", err);
		f2fs_bug_on(sbi, !f2fs_cp_error(sbi));
		goto stop;
	}

	f2fs_flush_sit_entries(sbi, cpc);

@@ -1654,10 +1657,13 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
	f2fs_save_inmem_curseg(sbi);

	err = do_checkpoint(sbi, cpc);
	if (err)
	if (err) {
		f2fs_err(sbi, "do_checkpoint failed err:%d, stop checkpoint", err);
		f2fs_bug_on(sbi, !f2fs_cp_error(sbi));
		f2fs_release_discard_addrs(sbi);
	else
	} else {
		f2fs_clear_prefree_segments(sbi, cpc);
	}

	f2fs_restore_inmem_curseg(sbi);
stop:
+22 −14
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;
@@ -1358,12 +1359,14 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page)
}

static int f2fs_write_raw_pages(struct compress_ctx *cc,
					int *submitted,
					int *submitted_p,
					struct writeback_control *wbc,
					enum iostat_type io_type)
{
	struct address_space *mapping = cc->inode->i_mapping;
	int _submitted, compr_blocks, ret, i;
	struct f2fs_sb_info *sbi = F2FS_M_SB(mapping);
	int submitted, compr_blocks, i;
	int ret = 0;

	compr_blocks = f2fs_compressed_blocks(cc);

@@ -1378,6 +1381,10 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc,
	if (compr_blocks < 0)
		return compr_blocks;

	/* overwrite compressed cluster w/ normal cluster */
	if (compr_blocks > 0)
		f2fs_lock_op(sbi);

	for (i = 0; i < cc->cluster_size; i++) {
		if (!cc->rpages[i])
			continue;
@@ -1402,7 +1409,7 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc,
		if (!clear_page_dirty_for_io(cc->rpages[i]))
			goto continue_unlock;

		ret = f2fs_write_single_data_page(cc->rpages[i], &_submitted,
		ret = f2fs_write_single_data_page(cc->rpages[i], &submitted,
						NULL, NULL, wbc, io_type,
						compr_blocks, false);
		if (ret) {
@@ -1410,28 +1417,29 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc,
				unlock_page(cc->rpages[i]);
				ret = 0;
			} else if (ret == -EAGAIN) {
				ret = 0;
				/*
				 * for quota file, just redirty left pages to
				 * avoid deadlock caused by cluster update race
				 * from foreground operation.
				 */
				if (IS_NOQUOTA(cc->inode))
					return 0;
				ret = 0;
				cond_resched();
				congestion_wait(BLK_RW_ASYNC,
						DEFAULT_IO_TIMEOUT);
					goto out;
				f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT);
				goto retry_write;
			}
			return ret;
			goto out;
		}

		*submitted += _submitted;
		*submitted_p += submitted;
	}

	f2fs_balance_fs(F2FS_M_SB(mapping), true);
out:
	if (compr_blocks > 0)
		f2fs_unlock_op(sbi);

	return 0;
	f2fs_balance_fs(sbi, true);
	return ret;
}

int f2fs_write_multi_pages(struct compress_ctx *cc,
+8 −8
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),
		.need_lock = compr_blocks ? LOCK_DONE : LOCK_RETRY,
		.post_read = f2fs_post_read_required(inode) ? 1 : 0,
		.io_type = io_type,
		.io_wbc = wbc,
		.bio = bio,
@@ -2882,6 +2882,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
	if (err == -EAGAIN) {
		err = f2fs_do_write_data_page(&fio);
		if (err == -EAGAIN) {
			f2fs_bug_on(sbi, compr_blocks);
			fio.need_lock = LOCK_REQ;
			err = f2fs_do_write_data_page(&fio);
		}
@@ -2926,7 +2927,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
	}

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

	return 0;

@@ -3152,8 +3153,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
				} else if (ret == -EAGAIN) {
					ret = 0;
					if (wbc->sync_mode == WB_SYNC_ALL) {
						cond_resched();
						congestion_wait(BLK_RW_ASYNC,
						f2fs_io_schedule_timeout(
							DEFAULT_IO_TIMEOUT);
						goto retry_write;
					}
+16 −10
Original line number Diff line number Diff line
@@ -518,7 +518,7 @@ enum {
					 */
};

#define DEFAULT_RETRY_IO_COUNT	8	/* maximum retry read IO count */
#define DEFAULT_RETRY_IO_COUNT	8	/* maximum retry read IO or flush count */

/* congestion wait timeout value, default: 20ms */
#define	DEFAULT_IO_TIMEOUT	(msecs_to_jiffies(20))
@@ -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 {
@@ -4155,6 +4155,12 @@ static inline void f2fs_truncate_meta_inode_pages(struct f2fs_sb_info *sbi,
			F2FS_BLK_END_BYTES((loff_t)(blkaddr + cnt - 1)));
}

static inline void f2fs_io_schedule_timeout(long timeout)
{
	set_current_state(TASK_UNINTERRUPTIBLE);
	io_schedule_timeout(timeout);
}

#define EFSBADCRC	EBADMSG		/* Bad CRC detected */
#define EFSCORRUPTED	EUCLEAN		/* Filesystem is corrupted */

+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