From: Ojaswin Mujoo Date: Thu, 21 Nov 2024 12:38:55 +0000 (+0530) Subject: ext4: protect ext4_release_dquot against freezing X-Git-Tag: v5.4.293~156 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=446d7281bfcc07a6407d611e32750c5f529f814a;p=thirdparty%2Fkernel%2Fstable.git ext4: protect ext4_release_dquot against freezing [ Upstream commit 530fea29ef82e169cd7fe048c2b7baaeb85a0028 ] Protect ext4_release_dquot against freezing so that we don't try to start a transaction when FS is frozen, leading to warnings. Further, avoid taking the freeze protection if a transaction is already running so that we don't need end up in a deadlock as described in 46e294efc355 ext4: fix deadlock with fs freezing and EA inodes Suggested-by: Jan Kara Signed-off-by: Ojaswin Mujoo Reviewed-by: Baokun Li Reviewed-by: Jan Kara Link: https://patch.msgid.link/20241121123855.645335-3-ojaswin@linux.ibm.com Signed-off-by: Theodore Ts'o Signed-off-by: Sasha Levin --- diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 6307adb16621a..0d4d50c8038fd 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -5809,18 +5809,35 @@ static int ext4_release_dquot(struct dquot *dquot) { int ret, err; handle_t *handle; + bool freeze_protected = false; + + /* + * Trying to sb_start_intwrite() in a running transaction + * can result in a deadlock. Further, running transactions + * are already protected from freezing. + */ + if (!ext4_journal_current_handle()) { + sb_start_intwrite(dquot->dq_sb); + freeze_protected = true; + } handle = ext4_journal_start(dquot_to_inode(dquot), EXT4_HT_QUOTA, EXT4_QUOTA_DEL_BLOCKS(dquot->dq_sb)); if (IS_ERR(handle)) { /* Release dquot anyway to avoid endless cycle in dqput() */ dquot_release(dquot); + if (freeze_protected) + sb_end_intwrite(dquot->dq_sb); return PTR_ERR(handle); } ret = dquot_release(dquot); err = ext4_journal_stop(handle); if (!ret) ret = err; + + if (freeze_protected) + sb_end_intwrite(dquot->dq_sb); + return ret; }