Commit 834224e8 authored by Harshad Shirwadkar's avatar Harshad Shirwadkar Committed by Theodore Ts'o
Browse files

ext4: convert i_fc_lock to spinlock



Convert ext4_inode_info->i_fc_lock to spinlock to avoid sleeping
in invalid contexts.

Reviewed-by: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatarHarshad Shirwadkar <harshadshirwadkar@gmail.com>
Link: https://patch.msgid.link/20250508175908.1004880-2-harshadshirwadkar@gmail.com


Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
parent b4432656
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -1069,8 +1069,11 @@ struct ext4_inode_info {
	/* Fast commit wait queue for this inode */
	wait_queue_head_t i_fc_wait;

	/* Protect concurrent accesses on i_fc_lblk_start, i_fc_lblk_len */
	struct mutex i_fc_lock;
	/*
	 * Protect concurrent accesses on i_fc_lblk_start, i_fc_lblk_len
	 * and inode's EXT4_FC_STATE_COMMITTING state bit.
	 */
	spinlock_t i_fc_lock;

	/*
	 * i_disksize keeps track of what the inode size is ON DISK, not
+9 −10
Original line number Diff line number Diff line
@@ -385,7 +385,7 @@ static int ext4_fc_track_template(
	int ret;

	tid = handle->h_transaction->t_tid;
	mutex_lock(&ei->i_fc_lock);
	spin_lock(&ei->i_fc_lock);
	if (tid == ei->i_sync_tid) {
		update = true;
	} else {
@@ -393,8 +393,7 @@ static int ext4_fc_track_template(
		ei->i_sync_tid = tid;
	}
	ret = __fc_track_fn(handle, inode, args, update);
	mutex_unlock(&ei->i_fc_lock);

	spin_unlock(&ei->i_fc_lock);
	if (!enqueue)
		return ret;

@@ -428,19 +427,19 @@ static int __track_dentry_update(handle_t *handle, struct inode *inode,
	struct super_block *sb = inode->i_sb;
	struct ext4_sb_info *sbi = EXT4_SB(sb);

	mutex_unlock(&ei->i_fc_lock);
	spin_unlock(&ei->i_fc_lock);

	if (IS_ENCRYPTED(dir)) {
		ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_ENCRYPTED_FILENAME,
					handle);
		mutex_lock(&ei->i_fc_lock);
		spin_lock(&ei->i_fc_lock);
		return -EOPNOTSUPP;
	}

	node = kmem_cache_alloc(ext4_fc_dentry_cachep, GFP_NOFS);
	if (!node) {
		ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM, handle);
		mutex_lock(&ei->i_fc_lock);
		spin_lock(&ei->i_fc_lock);
		return -ENOMEM;
	}

@@ -471,7 +470,7 @@ static int __track_dentry_update(handle_t *handle, struct inode *inode,
		list_add_tail(&node->fcd_dilist, &ei->i_fc_dilist);
	}
	spin_unlock(&sbi->s_fc_lock);
	mutex_lock(&ei->i_fc_lock);
	spin_lock(&ei->i_fc_lock);

	return 0;
}
@@ -893,15 +892,15 @@ static int ext4_fc_write_inode_data(struct inode *inode, u32 *crc)
	struct ext4_extent *ex;
	int ret;

	mutex_lock(&ei->i_fc_lock);
	spin_lock(&ei->i_fc_lock);
	if (ei->i_fc_lblk_len == 0) {
		mutex_unlock(&ei->i_fc_lock);
		spin_unlock(&ei->i_fc_lock);
		return 0;
	}
	old_blk_size = ei->i_fc_lblk_start;
	new_blk_size = ei->i_fc_lblk_start + ei->i_fc_lblk_len - 1;
	ei->i_fc_lblk_len = 0;
	mutex_unlock(&ei->i_fc_lock);
	spin_unlock(&ei->i_fc_lock);

	cur_lblk_off = old_blk_size;
	ext4_debug("will try writing %d to %d for inode %ld\n",
+1 −1
Original line number Diff line number Diff line
@@ -1415,7 +1415,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
	ei->i_datasync_tid = 0;
	INIT_WORK(&ei->i_rsv_conversion_work, ext4_end_io_rsv_work);
	ext4_fc_init_inode(&ei->vfs_inode);
	mutex_init(&ei->i_fc_lock);
	spin_lock_init(&ei->i_fc_lock);
	return &ei->vfs_inode;
}