Commit 0a1b2f5e authored by Baokun Li's avatar Baokun Li Committed by Theodore Ts'o
Browse files

ext4: add ext4_emergency_state() helper function



Since both SHUTDOWN and EMERGENCY_RO are emergency states of the ext4 file
system, and they are checked in similar locations, we have added a helper
function, ext4_emergency_state(), to determine whether the current file
system is in one of these two emergency states.

Then, replace calls to ext4_forced_shutdown() with ext4_emergency_state()
in those functions that could potentially trigger write operations.

Signed-off-by: default avatarBaokun Li <libaokun1@huawei.com>
Reviewed-by: default avatarJan Kara <jack@suse.cz>
Reviewed-by: default avatarZhang Yi <yi.zhang@huawei.com>
Link: https://patch.msgid.link/20250122114130.229709-4-libaokun@huaweicloud.com


Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
parent f3054e53
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -2252,6 +2252,15 @@ static inline int ext4_emergency_ro(struct super_block *sb)
	return test_bit(EXT4_FLAGS_EMERGENCY_RO, &EXT4_SB(sb)->s_ext4_flags);
}

static inline int ext4_emergency_state(struct super_block *sb)
{
	if (unlikely(ext4_forced_shutdown(sb)))
		return -EIO;
	if (unlikely(ext4_emergency_ro(sb)))
		return -EROFS;
	return 0;
}

/*
 * Default values for user and/or group using reserved blocks
 */
+4 −2
Original line number Diff line number Diff line
@@ -63,12 +63,14 @@ static void ext4_put_nojournal(handle_t *handle)
 */
static int ext4_journal_check_start(struct super_block *sb)
{
	int ret;
	journal_t *journal;

	might_sleep();

	if (unlikely(ext4_forced_shutdown(sb)))
		return -EIO;
	ret = ext4_emergency_state(sb);
	if (unlikely(ret))
		return ret;

	if (WARN_ON_ONCE(sb_rdonly(sb)))
		return -EROFS;
+17 −7
Original line number Diff line number Diff line
@@ -688,10 +688,12 @@ ext4_dax_write_iter(struct kiocb *iocb, struct iov_iter *from)
static ssize_t
ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
{
	int ret;
	struct inode *inode = file_inode(iocb->ki_filp);

	if (unlikely(ext4_forced_shutdown(inode->i_sb)))
		return -EIO;
	ret = ext4_emergency_state(inode->i_sb);
	if (unlikely(ret))
		return ret;

#ifdef CONFIG_FS_DAX
	if (IS_DAX(inode))
@@ -700,7 +702,6 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)

	if (iocb->ki_flags & IOCB_ATOMIC) {
		size_t len = iov_iter_count(from);
		int ret;

		if (len < EXT4_SB(inode->i_sb)->s_awu_min ||
		    len > EXT4_SB(inode->i_sb)->s_awu_max)
@@ -803,11 +804,16 @@ static const struct vm_operations_struct ext4_file_vm_ops = {

static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma)
{
	int ret;
	struct inode *inode = file->f_mapping->host;
	struct dax_device *dax_dev = EXT4_SB(inode->i_sb)->s_daxdev;

	if (unlikely(ext4_forced_shutdown(inode->i_sb)))
		return -EIO;
	if (file->f_mode & FMODE_WRITE)
		ret = ext4_emergency_state(inode->i_sb);
	else
		ret = ext4_forced_shutdown(inode->i_sb) ? -EIO : 0;
	if (unlikely(ret))
		return ret;

	/*
	 * We don't support synchronous mappings for non-DAX files and
@@ -881,8 +887,12 @@ static int ext4_file_open(struct inode *inode, struct file *filp)
{
	int ret;

	if (unlikely(ext4_forced_shutdown(inode->i_sb)))
		return -EIO;
	if (filp->f_mode & FMODE_WRITE)
		ret = ext4_emergency_state(inode->i_sb);
	else
		ret = ext4_forced_shutdown(inode->i_sb) ? -EIO : 0;
	if (unlikely(ret))
		return ret;

	ret = ext4_sample_last_mounted(inode->i_sb, filp->f_path.mnt);
	if (ret)
+4 −8
Original line number Diff line number Diff line
@@ -132,20 +132,16 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
	bool needs_barrier = false;
	struct inode *inode = file->f_mapping->host;

	if (unlikely(ext4_forced_shutdown(inode->i_sb)))
		return -EIO;
	ret = ext4_emergency_state(inode->i_sb);
	if (unlikely(ret))
		return ret;

	ASSERT(ext4_journal_current_handle() == NULL);

	trace_ext4_sync_file_enter(file, datasync);

	if (sb_rdonly(inode->i_sb)) {
		/* Make sure that we read updated s_ext4_flags value */
		smp_rmb();
		if (ext4_forced_shutdown(inode->i_sb))
			ret = -EROFS;
	if (sb_rdonly(inode->i_sb))
		goto out;
	}

	if (!EXT4_SB(inode->i_sb)->s_journal) {
		ret = ext4_fsync_nojournal(file, start, end, datasync,
+3 −2
Original line number Diff line number Diff line
@@ -951,8 +951,9 @@ struct inode *__ext4_new_inode(struct mnt_idmap *idmap,
	sb = dir->i_sb;
	sbi = EXT4_SB(sb);

	if (unlikely(ext4_forced_shutdown(sb)))
		return ERR_PTR(-EIO);
	ret2 = ext4_emergency_state(sb);
	if (unlikely(ret2))
		return ERR_PTR(ret2);

	ngroups = ext4_get_groups_count(sb);
	trace_ext4_request_inode(dir, mode);
Loading