linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv2 0/5] ext4/jbd2: inline_data fixes and minor cleanups
@ 2022-01-17 12:11 Ritesh Harjani
  2022-01-17 12:11 ` [PATCHv2 1/5] ext4: Fix error handling in ext4_restore_inline_data() Ritesh Harjani
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Ritesh Harjani @ 2022-01-17 12:11 UTC (permalink / raw)
  To: linux-ext4
  Cc: linux-fsdevel, linux-kernel, Jan Kara, Andreas Dilger, tytso,
	Eric Whitney, Ritesh Harjani

Hello,

Please find v2 of the inline_data fixes and some minor cleanups found during
code review.

I have dropped patch-6 in v2 which was removing use of t_handle_lock (spinlock)
from within jbd2_journal_wait_updates(). Based on Jan comments, I feel we can
push that as killing of t_handle_lock into a separate series (which will be on
top of this).

v1 -> v2
========
1. Added Jan's Reviewed-by tag & addressed one of his comment on no need to make
jbd2_journal_wait_updates() function inline.
2. Dropped patch-6 as described above.

Description
============
Patch[1]: fixes BUG_ON with inline_data which was reported [1] with generic/475.

Patch[2]: is mostly cleanup found during code review of inline_data code.

Patch[3]: is a possible memory corruption fix in case of krealloc failure.

Patch[4-5]: Cleanups.

[v1]: https://lore.kernel.org/linux-ext4/cover.1642044249.git.riteshh@linux.ibm.com/T/

Ritesh Harjani (5):
  ext4: Fix error handling in ext4_restore_inline_data()
  ext4: Remove redundant max inline_size check in ext4_da_write_inline_data_begin()
  ext4: Fix error handling in ext4_fc_record_modified_inode()
  jbd2: Cleanup unused functions declarations from jbd2.h
  jbd2: Refactor wait logic for transaction updates into a common function

 fs/ext4/fast_commit.c | 64 ++++++++++++++++++++-----------------------
 fs/ext4/inline.c      | 23 +++++++++-------
 fs/jbd2/commit.c      | 19 ++-----------
 fs/jbd2/transaction.c | 53 +++++++++++++++++++++--------------
 include/linux/jbd2.h  | 11 ++------
 5 files changed, 80 insertions(+), 90 deletions(-)

--
2.31.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCHv2 1/5] ext4: Fix error handling in ext4_restore_inline_data()
  2022-01-17 12:11 [PATCHv2 0/5] ext4/jbd2: inline_data fixes and minor cleanups Ritesh Harjani
@ 2022-01-17 12:11 ` Ritesh Harjani
  2022-01-17 12:11 ` [PATCHv2 2/5] ext4: Remove redundant max inline_size check in ext4_da_write_inline_data_begin() Ritesh Harjani
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Ritesh Harjani @ 2022-01-17 12:11 UTC (permalink / raw)
  To: linux-ext4
  Cc: linux-fsdevel, linux-kernel, Jan Kara, Andreas Dilger, tytso,
	Eric Whitney, Ritesh Harjani, Jan Kara

While running "./check -I 200 generic/475" it sometimes gives below
kernel BUG(). Ideally we should not call ext4_write_inline_data() if
ext4_create_inline_data() has failed.

<log snip>
[73131.453234] kernel BUG at fs/ext4/inline.c:223!

<code snip>
 212 static void ext4_write_inline_data(struct inode *inode, struct ext4_iloc *iloc,
 213                                    void *buffer, loff_t pos, unsigned int len)
 214 {
<...>
 223         BUG_ON(!EXT4_I(inode)->i_inline_off);
 224         BUG_ON(pos + len > EXT4_I(inode)->i_inline_size);

This patch handles the error and prints out a emergency msg saying potential
data loss for the given inode (since we couldn't restore the original
inline_data due to some previous error).

[ 9571.070313] EXT4-fs (dm-0): error restoring inline_data for inode -- potential data loss! (inode 1703982, error -30)

Reported-by: Eric Whitney <enwlinux@gmail.com>
Signed-off-by: Ritesh Harjani <riteshh@linux.ibm.com>
Reviewed-by: Jan Kara <jack@suse.cz>
---
 fs/ext4/inline.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index 39a1ab129fdc..d091133a4b46 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -1133,7 +1133,15 @@ static void ext4_restore_inline_data(handle_t *handle, struct inode *inode,
 				     struct ext4_iloc *iloc,
 				     void *buf, int inline_size)
 {
-	ext4_create_inline_data(handle, inode, inline_size);
+	int ret;
+
+	ret = ext4_create_inline_data(handle, inode, inline_size);
+	if (ret) {
+		ext4_msg(inode->i_sb, KERN_EMERG,
+			"error restoring inline_data for inode -- potential data loss! (inode %lu, error %d)",
+			inode->i_ino, ret);
+		return;
+	}
 	ext4_write_inline_data(inode, iloc, buf, 0, inline_size);
 	ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
 }
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCHv2 2/5] ext4: Remove redundant max inline_size check in ext4_da_write_inline_data_begin()
  2022-01-17 12:11 [PATCHv2 0/5] ext4/jbd2: inline_data fixes and minor cleanups Ritesh Harjani
  2022-01-17 12:11 ` [PATCHv2 1/5] ext4: Fix error handling in ext4_restore_inline_data() Ritesh Harjani
@ 2022-01-17 12:11 ` Ritesh Harjani
  2022-01-17 12:11 ` [PATCHv2 3/5] ext4: Fix error handling in ext4_fc_record_modified_inode() Ritesh Harjani
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Ritesh Harjani @ 2022-01-17 12:11 UTC (permalink / raw)
  To: linux-ext4
  Cc: linux-fsdevel, linux-kernel, Jan Kara, Andreas Dilger, tytso,
	Eric Whitney, Ritesh Harjani, Jan Kara

ext4_prepare_inline_data() already checks for ext4_get_max_inline_size()
and returns -ENOSPC. So there is no need to check it twice within
ext4_da_write_inline_data_begin(). This patch removes the extra check.

It also makes it more clean.

No functionality change in this patch.

Signed-off-by: Ritesh Harjani <riteshh@linux.ibm.com>
Reviewed-by: Jan Kara <jack@suse.cz>
---
 fs/ext4/inline.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index d091133a4b46..cbdd84e49f2c 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -911,7 +911,7 @@ int ext4_da_write_inline_data_begin(struct address_space *mapping,
 				    struct page **pagep,
 				    void **fsdata)
 {
-	int ret, inline_size;
+	int ret;
 	handle_t *handle;
 	struct page *page;
 	struct ext4_iloc iloc;
@@ -928,14 +928,9 @@ int ext4_da_write_inline_data_begin(struct address_space *mapping,
 		goto out;
 	}
 
-	inline_size = ext4_get_max_inline_size(inode);
-
-	ret = -ENOSPC;
-	if (inline_size >= pos + len) {
-		ret = ext4_prepare_inline_data(handle, inode, pos + len);
-		if (ret && ret != -ENOSPC)
-			goto out_journal;
-	}
+	ret = ext4_prepare_inline_data(handle, inode, pos + len);
+	if (ret && ret != -ENOSPC)
+		goto out_journal;
 
 	/*
 	 * We cannot recurse into the filesystem as the transaction
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCHv2 3/5] ext4: Fix error handling in ext4_fc_record_modified_inode()
  2022-01-17 12:11 [PATCHv2 0/5] ext4/jbd2: inline_data fixes and minor cleanups Ritesh Harjani
  2022-01-17 12:11 ` [PATCHv2 1/5] ext4: Fix error handling in ext4_restore_inline_data() Ritesh Harjani
  2022-01-17 12:11 ` [PATCHv2 2/5] ext4: Remove redundant max inline_size check in ext4_da_write_inline_data_begin() Ritesh Harjani
@ 2022-01-17 12:11 ` Ritesh Harjani
  2022-01-17 12:11 ` [PATCHv2 4/5] jbd2: Cleanup unused functions declarations from jbd2.h Ritesh Harjani
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Ritesh Harjani @ 2022-01-17 12:11 UTC (permalink / raw)
  To: linux-ext4
  Cc: linux-fsdevel, linux-kernel, Jan Kara, Andreas Dilger, tytso,
	Eric Whitney, Ritesh Harjani, luo penghao, Lukas Czerner,
	Jan Kara

Current code does not fully takes care of krealloc() error case,
which could lead to silent memory corruption or a kernel bug.
This patch fixes that.

Also it cleans up some duplicated error handling logic from various functions
in fast_commit.c file.

Reported-by: luo penghao <luo.penghao@zte.com.cn>
Suggested-by: Lukas Czerner <lczerner@redhat.com>
Signed-off-by: Ritesh Harjani <riteshh@linux.ibm.com>
Reviewed-by: Jan Kara <jack@suse.cz>
---
 fs/ext4/fast_commit.c | 64 ++++++++++++++++++++-----------------------
 1 file changed, 29 insertions(+), 35 deletions(-)

diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c
index 5ae8026a0c56..4541c8468c01 100644
--- a/fs/ext4/fast_commit.c
+++ b/fs/ext4/fast_commit.c
@@ -1392,14 +1392,15 @@ static int ext4_fc_record_modified_inode(struct super_block *sb, int ino)
 		if (state->fc_modified_inodes[i] == ino)
 			return 0;
 	if (state->fc_modified_inodes_used == state->fc_modified_inodes_size) {
-		state->fc_modified_inodes_size +=
-			EXT4_FC_REPLAY_REALLOC_INCREMENT;
 		state->fc_modified_inodes = krealloc(
-					state->fc_modified_inodes, sizeof(int) *
-					state->fc_modified_inodes_size,
-					GFP_KERNEL);
+				state->fc_modified_inodes,
+				sizeof(int) * (state->fc_modified_inodes_size +
+				EXT4_FC_REPLAY_REALLOC_INCREMENT),
+				GFP_KERNEL);
 		if (!state->fc_modified_inodes)
 			return -ENOMEM;
+		state->fc_modified_inodes_size +=
+			EXT4_FC_REPLAY_REALLOC_INCREMENT;
 	}
 	state->fc_modified_inodes[state->fc_modified_inodes_used++] = ino;
 	return 0;
@@ -1431,7 +1432,9 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl,
 	}
 	inode = NULL;
 
-	ext4_fc_record_modified_inode(sb, ino);
+	ret = ext4_fc_record_modified_inode(sb, ino);
+	if (ret)
+		goto out;
 
 	raw_fc_inode = (struct ext4_inode *)
 		(val + offsetof(struct ext4_fc_inode, fc_raw_inode));
@@ -1621,6 +1624,8 @@ static int ext4_fc_replay_add_range(struct super_block *sb,
 	}
 
 	ret = ext4_fc_record_modified_inode(sb, inode->i_ino);
+	if (ret)
+		goto out;
 
 	start = le32_to_cpu(ex->ee_block);
 	start_pblk = ext4_ext_pblock(ex);
@@ -1638,18 +1643,14 @@ static int ext4_fc_replay_add_range(struct super_block *sb,
 		map.m_pblk = 0;
 		ret = ext4_map_blocks(NULL, inode, &map, 0);
 
-		if (ret < 0) {
-			iput(inode);
-			return 0;
-		}
+		if (ret < 0)
+			goto out;
 
 		if (ret == 0) {
 			/* Range is not mapped */
 			path = ext4_find_extent(inode, cur, NULL, 0);
-			if (IS_ERR(path)) {
-				iput(inode);
-				return 0;
-			}
+			if (IS_ERR(path))
+				goto out;
 			memset(&newex, 0, sizeof(newex));
 			newex.ee_block = cpu_to_le32(cur);
 			ext4_ext_store_pblock(
@@ -1663,10 +1664,8 @@ static int ext4_fc_replay_add_range(struct super_block *sb,
 			up_write((&EXT4_I(inode)->i_data_sem));
 			ext4_ext_drop_refs(path);
 			kfree(path);
-			if (ret) {
-				iput(inode);
-				return 0;
-			}
+			if (ret)
+				goto out;
 			goto next;
 		}
 
@@ -1679,10 +1678,8 @@ static int ext4_fc_replay_add_range(struct super_block *sb,
 			ret = ext4_ext_replay_update_ex(inode, cur, map.m_len,
 					ext4_ext_is_unwritten(ex),
 					start_pblk + cur - start);
-			if (ret) {
-				iput(inode);
-				return 0;
-			}
+			if (ret)
+				goto out;
 			/*
 			 * Mark the old blocks as free since they aren't used
 			 * anymore. We maintain an array of all the modified
@@ -1702,10 +1699,8 @@ static int ext4_fc_replay_add_range(struct super_block *sb,
 			ext4_ext_is_unwritten(ex), map.m_pblk);
 		ret = ext4_ext_replay_update_ex(inode, cur, map.m_len,
 					ext4_ext_is_unwritten(ex), map.m_pblk);
-		if (ret) {
-			iput(inode);
-			return 0;
-		}
+		if (ret)
+			goto out;
 		/*
 		 * We may have split the extent tree while toggling the state.
 		 * Try to shrink the extent tree now.
@@ -1717,6 +1712,7 @@ static int ext4_fc_replay_add_range(struct super_block *sb,
 	}
 	ext4_ext_replay_shrink_inode(inode, i_size_read(inode) >>
 					sb->s_blocksize_bits);
+out:
 	iput(inode);
 	return 0;
 }
@@ -1746,6 +1742,8 @@ ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl,
 	}
 
 	ret = ext4_fc_record_modified_inode(sb, inode->i_ino);
+	if (ret)
+		goto out;
 
 	jbd_debug(1, "DEL_RANGE, inode %ld, lblk %d, len %d\n",
 			inode->i_ino, le32_to_cpu(lrange.fc_lblk),
@@ -1755,10 +1753,8 @@ ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl,
 		map.m_len = remaining;
 
 		ret = ext4_map_blocks(NULL, inode, &map, 0);
-		if (ret < 0) {
-			iput(inode);
-			return 0;
-		}
+		if (ret < 0)
+			goto out;
 		if (ret > 0) {
 			remaining -= ret;
 			cur += ret;
@@ -1773,15 +1769,13 @@ ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl,
 	ret = ext4_ext_remove_space(inode, lrange.fc_lblk,
 				lrange.fc_lblk + lrange.fc_len - 1);
 	up_write(&EXT4_I(inode)->i_data_sem);
-	if (ret) {
-		iput(inode);
-		return 0;
-	}
+	if (ret)
+		goto out;
 	ext4_ext_replay_shrink_inode(inode,
 		i_size_read(inode) >> sb->s_blocksize_bits);
 	ext4_mark_inode_dirty(NULL, inode);
+out:
 	iput(inode);
-
 	return 0;
 }
 
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCHv2 4/5] jbd2: Cleanup unused functions declarations from jbd2.h
  2022-01-17 12:11 [PATCHv2 0/5] ext4/jbd2: inline_data fixes and minor cleanups Ritesh Harjani
                   ` (2 preceding siblings ...)
  2022-01-17 12:11 ` [PATCHv2 3/5] ext4: Fix error handling in ext4_fc_record_modified_inode() Ritesh Harjani
@ 2022-01-17 12:11 ` Ritesh Harjani
  2022-01-17 12:11 ` [PATCHv2 5/5] jbd2: Refactor wait logic for transaction updates into a common function Ritesh Harjani
  2022-01-20 15:58 ` [PATCHv2 0/5] ext4/jbd2: inline_data fixes and minor cleanups Theodore Ts'o
  5 siblings, 0 replies; 7+ messages in thread
From: Ritesh Harjani @ 2022-01-17 12:11 UTC (permalink / raw)
  To: linux-ext4
  Cc: linux-fsdevel, linux-kernel, Jan Kara, Andreas Dilger, tytso,
	Eric Whitney, Ritesh Harjani, Jan Kara

During code review found no references of few of these below function
declarations. This patch cleans those up from jbd2.h

Signed-off-by: Ritesh Harjani <riteshh@linux.ibm.com>
Reviewed-by: Jan Kara <jack@suse.cz>
---
 include/linux/jbd2.h | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index fd933c45281a..f76598265896 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -1419,9 +1419,7 @@ extern void jbd2_journal_unfile_buffer(journal_t *, struct journal_head *);
 extern bool __jbd2_journal_refile_buffer(struct journal_head *);
 extern void jbd2_journal_refile_buffer(journal_t *, struct journal_head *);
 extern void __jbd2_journal_file_buffer(struct journal_head *, transaction_t *, int);
-extern void __journal_free_buffer(struct journal_head *bh);
 extern void jbd2_journal_file_buffer(struct journal_head *, transaction_t *, int);
-extern void __journal_clean_data_list(transaction_t *transaction);
 static inline void jbd2_file_log_bh(struct list_head *head, struct buffer_head *bh)
 {
 	list_add_tail(&bh->b_assoc_buffers, head);
@@ -1486,9 +1484,6 @@ extern int jbd2_journal_write_metadata_buffer(transaction_t *transaction,
 					      struct buffer_head **bh_out,
 					      sector_t blocknr);
 
-/* Transaction locking */
-extern void		__wait_on_journal (journal_t *);
-
 /* Transaction cache support */
 extern void jbd2_journal_destroy_transaction_cache(void);
 extern int __init jbd2_journal_init_transaction_cache(void);
@@ -1774,8 +1769,6 @@ static inline unsigned long jbd2_log_space_left(journal_t *journal)
 #define BJ_Reserved	4	/* Buffer is reserved for access by journal */
 #define BJ_Types	5
 
-extern int jbd_blocks_per_page(struct inode *inode);
-
 /* JBD uses a CRC32 checksum */
 #define JBD_MAX_CHECKSUM_SIZE 4
 
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCHv2 5/5] jbd2: Refactor wait logic for transaction updates into a common function
  2022-01-17 12:11 [PATCHv2 0/5] ext4/jbd2: inline_data fixes and minor cleanups Ritesh Harjani
                   ` (3 preceding siblings ...)
  2022-01-17 12:11 ` [PATCHv2 4/5] jbd2: Cleanup unused functions declarations from jbd2.h Ritesh Harjani
@ 2022-01-17 12:11 ` Ritesh Harjani
  2022-01-20 15:58 ` [PATCHv2 0/5] ext4/jbd2: inline_data fixes and minor cleanups Theodore Ts'o
  5 siblings, 0 replies; 7+ messages in thread
From: Ritesh Harjani @ 2022-01-17 12:11 UTC (permalink / raw)
  To: linux-ext4
  Cc: linux-fsdevel, linux-kernel, Jan Kara, Andreas Dilger, tytso,
	Eric Whitney, Ritesh Harjani, Jan Kara

No functionality change as such in this patch. This only refactors the
common piece of code which waits for t_updates to finish into a common
function named as jbd2_journal_wait_updates(journal_t *)

Signed-off-by: Ritesh Harjani <riteshh@linux.ibm.com>
Reviewed-by: Jan Kara <jack@suse.cz>
---
 fs/jbd2/commit.c      | 19 +++-------------
 fs/jbd2/transaction.c | 53 ++++++++++++++++++++++++++-----------------
 include/linux/jbd2.h  |  4 +++-
 3 files changed, 38 insertions(+), 38 deletions(-)

diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 3cc4ab2ba7f4..428364f107be 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -484,22 +484,9 @@ void jbd2_journal_commit_transaction(journal_t *journal)
 	stats.run.rs_running = jbd2_time_diff(commit_transaction->t_start,
 					      stats.run.rs_locked);
 
-	spin_lock(&commit_transaction->t_handle_lock);
-	while (atomic_read(&commit_transaction->t_updates)) {
-		DEFINE_WAIT(wait);
+	// waits for any t_updates to finish
+	jbd2_journal_wait_updates(journal);
 
-		prepare_to_wait(&journal->j_wait_updates, &wait,
-					TASK_UNINTERRUPTIBLE);
-		if (atomic_read(&commit_transaction->t_updates)) {
-			spin_unlock(&commit_transaction->t_handle_lock);
-			write_unlock(&journal->j_state_lock);
-			schedule();
-			write_lock(&journal->j_state_lock);
-			spin_lock(&commit_transaction->t_handle_lock);
-		}
-		finish_wait(&journal->j_wait_updates, &wait);
-	}
-	spin_unlock(&commit_transaction->t_handle_lock);
 	commit_transaction->t_state = T_SWITCH;
 	write_unlock(&journal->j_state_lock);
 
@@ -817,7 +804,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
 	commit_transaction->t_state = T_COMMIT_DFLUSH;
 	write_unlock(&journal->j_state_lock);
 
-	/* 
+	/*
 	 * If the journal is not located on the file system device,
 	 * then we must flush the file system device before we issue
 	 * the commit record
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 6a3caedd2285..8e2f8275a253 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -449,7 +449,7 @@ static int start_this_handle(journal_t *journal, handle_t *handle,
 	}
 
 	/* OK, account for the buffers that this operation expects to
-	 * use and add the handle to the running transaction. 
+	 * use and add the handle to the running transaction.
 	 */
 	update_t_max_wait(transaction, ts);
 	handle->h_transaction = transaction;
@@ -836,6 +836,35 @@ int jbd2_journal_restart(handle_t *handle, int nblocks)
 }
 EXPORT_SYMBOL(jbd2_journal_restart);
 
+/*
+ * Waits for any outstanding t_updates to finish.
+ * This is called with write j_state_lock held.
+ */
+void jbd2_journal_wait_updates(journal_t *journal)
+{
+	transaction_t *commit_transaction = journal->j_running_transaction;
+
+	if (!commit_transaction)
+		return;
+
+	spin_lock(&commit_transaction->t_handle_lock);
+	while (atomic_read(&commit_transaction->t_updates)) {
+		DEFINE_WAIT(wait);
+
+		prepare_to_wait(&journal->j_wait_updates, &wait,
+					TASK_UNINTERRUPTIBLE);
+		if (atomic_read(&commit_transaction->t_updates)) {
+			spin_unlock(&commit_transaction->t_handle_lock);
+			write_unlock(&journal->j_state_lock);
+			schedule();
+			write_lock(&journal->j_state_lock);
+			spin_lock(&commit_transaction->t_handle_lock);
+		}
+		finish_wait(&journal->j_wait_updates, &wait);
+	}
+	spin_unlock(&commit_transaction->t_handle_lock);
+}
+
 /**
  * jbd2_journal_lock_updates () - establish a transaction barrier.
  * @journal:  Journal to establish a barrier on.
@@ -863,27 +892,9 @@ void jbd2_journal_lock_updates(journal_t *journal)
 		write_lock(&journal->j_state_lock);
 	}
 
-	/* Wait until there are no running updates */
-	while (1) {
-		transaction_t *transaction = journal->j_running_transaction;
-
-		if (!transaction)
-			break;
+	/* Wait until there are no running t_updates */
+	jbd2_journal_wait_updates(journal);
 
-		spin_lock(&transaction->t_handle_lock);
-		prepare_to_wait(&journal->j_wait_updates, &wait,
-				TASK_UNINTERRUPTIBLE);
-		if (!atomic_read(&transaction->t_updates)) {
-			spin_unlock(&transaction->t_handle_lock);
-			finish_wait(&journal->j_wait_updates, &wait);
-			break;
-		}
-		spin_unlock(&transaction->t_handle_lock);
-		write_unlock(&journal->j_state_lock);
-		schedule();
-		finish_wait(&journal->j_wait_updates, &wait);
-		write_lock(&journal->j_state_lock);
-	}
 	write_unlock(&journal->j_state_lock);
 
 	/*
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index f76598265896..575c3057a98a 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -594,7 +594,7 @@ struct transaction_s
 	 */
 	unsigned long		t_log_start;
 
-	/* 
+	/*
 	 * Number of buffers on the t_buffers list [j_list_lock, no locks
 	 * needed for jbd2 thread]
 	 */
@@ -1538,6 +1538,8 @@ extern int	 jbd2_journal_flush(journal_t *journal, unsigned int flags);
 extern void	 jbd2_journal_lock_updates (journal_t *);
 extern void	 jbd2_journal_unlock_updates (journal_t *);
 
+void jbd2_journal_wait_updates(journal_t *);
+
 extern journal_t * jbd2_journal_init_dev(struct block_device *bdev,
 				struct block_device *fs_dev,
 				unsigned long long start, int len, int bsize);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCHv2 0/5] ext4/jbd2: inline_data fixes and minor cleanups
  2022-01-17 12:11 [PATCHv2 0/5] ext4/jbd2: inline_data fixes and minor cleanups Ritesh Harjani
                   ` (4 preceding siblings ...)
  2022-01-17 12:11 ` [PATCHv2 5/5] jbd2: Refactor wait logic for transaction updates into a common function Ritesh Harjani
@ 2022-01-20 15:58 ` Theodore Ts'o
  5 siblings, 0 replies; 7+ messages in thread
From: Theodore Ts'o @ 2022-01-20 15:58 UTC (permalink / raw)
  To: linux-ext4, Ritesh Harjani
  Cc: Theodore Ts'o, Andreas Dilger, linux-kernel, Eric Whitney,
	Jan Kara, linux-fsdevel

On Mon, 17 Jan 2022 17:41:46 +0530, Ritesh Harjani wrote:
> Please find v2 of the inline_data fixes and some minor cleanups found during
> code review.
> 
> I have dropped patch-6 in v2 which was removing use of t_handle_lock (spinlock)
> from within jbd2_journal_wait_updates(). Based on Jan comments, I feel we can
> push that as killing of t_handle_lock into a separate series (which will be on
> top of this).
> 
> [...]

Applied, thanks!

[1/5] ext4: Fix error handling in ext4_restore_inline_data()
      commit: 2fdd85005f708691a64270ecb67d98191d668c4c
[2/5] ext4: Remove redundant max inline_size check in ext4_da_write_inline_data_begin()
      commit: c7fc77e512a432bba754f969c4eb72b33cda3431
[3/5] ext4: Fix error handling in ext4_fc_record_modified_inode()
      commit: 6dcee78ea266fb736a3357c2e04d81ee7ec7b6e4
[4/5] jbd2: Cleanup unused functions declarations from jbd2.h
      commit: 16263b9820b0d40c778c8ee867f853d3fe638f37
[5/5] jbd2: Refactor wait logic for transaction updates into a common function
      commit: b0544c1f23ddeabd89480d842867ca1c6894e021

Best regards,
-- 
Theodore Ts'o <tytso@mit.edu>

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-01-20 15:58 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-17 12:11 [PATCHv2 0/5] ext4/jbd2: inline_data fixes and minor cleanups Ritesh Harjani
2022-01-17 12:11 ` [PATCHv2 1/5] ext4: Fix error handling in ext4_restore_inline_data() Ritesh Harjani
2022-01-17 12:11 ` [PATCHv2 2/5] ext4: Remove redundant max inline_size check in ext4_da_write_inline_data_begin() Ritesh Harjani
2022-01-17 12:11 ` [PATCHv2 3/5] ext4: Fix error handling in ext4_fc_record_modified_inode() Ritesh Harjani
2022-01-17 12:11 ` [PATCHv2 4/5] jbd2: Cleanup unused functions declarations from jbd2.h Ritesh Harjani
2022-01-17 12:11 ` [PATCHv2 5/5] jbd2: Refactor wait logic for transaction updates into a common function Ritesh Harjani
2022-01-20 15:58 ` [PATCHv2 0/5] ext4/jbd2: inline_data fixes and minor cleanups Theodore Ts'o

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).