From nobody Thu Apr 2 23:54:52 2026 Received: from mail-wm1-f53.google.com (mail-wm1-f53.google.com [209.85.128.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 38DC0386C03 for ; Thu, 26 Mar 2026 06:59:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774508345; cv=none; b=PkEObucfxfQQHIuX5S92vDKPLBi3BgsZ5XnI7+5WZUvlexZw9tMGmTBUH4rG9rWjmVtcuF0WLu8qhYPq5JsZ21i+C7ttUasiA1LQfcd9TRtnrSb/tY76ki6XHv+bHjZhHH98XItJZveKjEoSryI8LntnX4nzwtCgnyH7Hv6y2so= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774508345; c=relaxed/simple; bh=x5PShJ88TgzH8FdyVsnskLhfiOBz3n4uaFYvwPHfwa4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TVz27K93ypncXRppHI4r9gUsjSiYn5I+I7SI2JOPBbHIog4mr7ru5/jIvtuzjtcHLqvhsI47Ec29AI8SiJPd3eVMWygHAEYzZn+l2dG06f5gcIay9xxLklvCbb57cRKp6d1vcbBGAdJLxcPpagaJi+rt/5GuH47meat2/vRkopc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=suse.com; spf=pass smtp.mailfrom=suse.com; dkim=pass (2048-bit key) header.d=suse.com header.i=@suse.com header.b=KrY9jmHt; arc=none smtp.client-ip=209.85.128.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=suse.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=suse.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=suse.com header.i=@suse.com header.b="KrY9jmHt" Received: by mail-wm1-f53.google.com with SMTP id 5b1f17b1804b1-485358f43e7so749125e9.2 for ; Wed, 25 Mar 2026 23:59:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=google; t=1774508342; x=1775113142; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0pHlF9RSYomV32eEhsUv5cmZinlB34ZOM7lnu2Ze3CQ=; b=KrY9jmHt2RnjruURt/5f9GxZA52gheMQFofrRx64Uuk3B8ul/EYRM10yWwxvsR2lD2 RUy+XY0NPAv5iFwmhekarS/e+bvwYbqOQ87zd/GqBC0H/ta6yJGRcDNdyIdtF8QzA1L7 dG5O2WTD3ZpqKJ/AIwYIt0BajLgs3AyGhfv76K9vl+F6xEBigYDTfjtG4C0zXK5uyTJa M6hWxCIzS4qNBOPmW70f3gAnI+AwOq/7z8pzLD5neI7vtAfgmAP3iRDaBoOdXhHeUBar bIvQiOpjN0M1BJTlZTuxkoq2Cr5JlHwrg9QcB6ncI4PhwHUwO9eaUXE9K0ZeRf24NTAR wbpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774508342; x=1775113142; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=0pHlF9RSYomV32eEhsUv5cmZinlB34ZOM7lnu2Ze3CQ=; b=TLsFKxslcCxNJF6fx7NAkC7SMTllgwTlcjw+tVF+NW+oVQ3fulGo+c8OtxIGHQZqxz yr/yA8ucZ84p6Fbk2mUnRaqC8cid4fpAfRDVysgsz8M+Hgo/x83VLD2tM1gekoVS0ex0 6oeDpibDmU7h+Ot4diGSL3QCwwLs26IKvBegYgB3X8lHdrQJ7OrHs7Vr+tzU2ifcWoiO rvKc1X8IJ8/ZDWIePIEpsxwD61O0e0KGQNALr9eNs1j3VuUEbblqNXLMHA+8Q3BBDPdk VVBkjQ/F6cAAp4CLYm/TmB8bJLt9fMRANaTnRDFnVkbKzbadK95zdjQbmelUBhW04qAJ hRbw== X-Forwarded-Encrypted: i=1; AJvYcCUBZ0KR1Pqbmm9oAFBuTKHtN+R21FLwjTGwgv6C/IIzAD7HSrG4bItOtzn3y/4Cn0AxIXrOk0YCQpPgn24=@vger.kernel.org X-Gm-Message-State: AOJu0YyUXcg1EJ5CtaPzn1BjcrI7UQ+poMRM2T9dFy7xCN0vf+yy1eES q7kcqeVP0EoZmnbKuY5bnFU9yOb+ZsIdyY0EtPJxkc3H3HjynwsOmy1YAKZtBEVYHwc= X-Gm-Gg: ATEYQzyTdbsYo6bmr3MYK+ZKQ+EuyqtMr6O61vMUQ0ZdlST1E3j9tl5twnxh9NsKwJt uFffkv+sE9qSW0m0eXqr682VO/EWpLJb1peOt45r8Xyq0mcTx7dLfwaqEk05MCf7/FJzx8FHbf3 C6XoTBoAHbdQkITANx8hwgpfknTc0FLFUGL9vlpvb2EZCeaOVL5bksb3pkHAQ4QmhgboFxwTuNv KfZ7BflrfYZqJrDZyzAOjwiTEmPOpTCzCLOOjcEcXeJHCV/Im/dS/Um7DmkkrsEPYEjQ9ad5A89 NdH3KoJdo3kvlxS8Lsh2tcCj8S8EXLySjQ7o5GXo5GrNzOAd0sa9MEhn3rABMJnOolwth4Bx767 pH8Onbi0+2gD6zorQCuIMiSq4NgP24DBZTIEzN5O/gHTybONL2ckUpiPO2H7CTs3rzhWsOwROO5 UTB8sCIOAeZRdXdjupe+NZx9Ze0TRPcp4Yb8Sx X-Received: by 2002:a05:600c:3ba4:b0:485:2af3:3f8b with SMTP id 5b1f17b1804b1-48715fae53dmr58328965e9.1.1774508342496; Wed, 25 Mar 2026 23:59:02 -0700 (PDT) Received: from localhost.localdomain ([202.127.77.110]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2b0bc8c4bd3sm20279875ad.63.2026.03.25.23.58.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Mar 2026 23:59:01 -0700 (PDT) From: Heming Zhao To: joseph.qi@linux.alibaba.com Cc: Heming Zhao , ocfs2-devel@lists.linux.dev, linux-kernel@vger.kernel.org, jack@suse.cz, glass.su@suse.com Subject: [PATCH v3 1/2] ocfs2: split transactions in dio completion to avoid credit exhaustion Date: Thu, 26 Mar 2026 14:58:17 +0800 Message-ID: <20260326065821.15156-2-heming.zhao@suse.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260326065821.15156-1-heming.zhao@suse.com> References: <20260326065821.15156-1-heming.zhao@suse.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" During ocfs2 dio operations, JBD2 may report warnings via following call tr= ace: ocfs2_dio_end_io_write ocfs2_mark_extent_written ocfs2_change_extent_flag ocfs2_split_extent ocfs2_try_to_merge_extent ocfs2_extend_rotate_transaction ocfs2_extend_trans jbd2__journal_restart start_this_handle output: JBD2: kworker/6:2 wants too many credits credits:5450 rsv_= credits:0 max:5449 To prevent exceeding the credits limit, modify ocfs2_dio_end_io_write() to handle extent in a batch of transaction. Additionally, relocate ocfs2_del_inode_from_orphan(). The orphan inode shou= ld only be removed from the orphan list after the extent tree update is comple= te. this ensures that if a crash occurs in the middle of extent tree updates, we won't leave stale blocks beyond EOF. Finally, thanks to Jans and Joseph for providing the bug fix prototype and suggestions. Suggested-by: Jan Kara Suggested-by: Joseph Qi Signed-off-by: Heming Zhao Reviewed-by: Jan Kara --- fs/ocfs2/aops.c | 72 ++++++++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 28 deletions(-) diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 09146b43d1f0..60f1b607022f 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c @@ -37,6 +37,8 @@ #include "namei.h" #include "sysfile.h" =20 +#define OCFS2_DIO_MARK_EXTENT_BATCH 200 + static int ocfs2_symlink_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) { @@ -2277,7 +2279,7 @@ static int ocfs2_dio_end_io_write(struct inode *inode, struct ocfs2_alloc_context *meta_ac =3D NULL; handle_t *handle =3D NULL; loff_t end =3D offset + bytes; - int ret =3D 0, credits =3D 0; + int ret =3D 0, credits =3D 0, batch =3D 0; =20 ocfs2_init_dealloc_ctxt(&dealloc); =20 @@ -2294,18 +2296,6 @@ static int ocfs2_dio_end_io_write(struct inode *inod= e, goto out; } =20 - /* Delete orphan before acquire i_rwsem. */ - if (dwc->dw_orphaned) { - BUG_ON(dwc->dw_writer_pid !=3D task_pid_nr(current)); - - end =3D end > i_size_read(inode) ? end : 0; - - ret =3D ocfs2_del_inode_from_orphan(osb, inode, di_bh, - !!end, end); - if (ret < 0) - mlog_errno(ret); - } - down_write(&oi->ip_alloc_sem); di =3D (struct ocfs2_dinode *)di_bh->b_data; =20 @@ -2326,20 +2316,22 @@ static int ocfs2_dio_end_io_write(struct inode *ino= de, =20 credits =3D ocfs2_calc_extend_credits(inode->i_sb, &di->id2.i_list); =20 - handle =3D ocfs2_start_trans(osb, credits); - if (IS_ERR(handle)) { - ret =3D PTR_ERR(handle); - mlog_errno(ret); - goto unlock; - } - ret =3D ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh, - OCFS2_JOURNAL_ACCESS_WRITE); - if (ret) { - mlog_errno(ret); - goto commit; - } - list_for_each_entry(ue, &dwc->dw_zero_list, ue_node) { + if (!handle) { + handle =3D ocfs2_start_trans(osb, credits); + if (IS_ERR(handle)) { + ret =3D PTR_ERR(handle); + mlog_errno(ret); + handle =3D NULL; + break; + } + ret =3D ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh, + OCFS2_JOURNAL_ACCESS_WRITE); + if (ret) { + mlog_errno(ret); + break; + } + } ret =3D ocfs2_assure_trans_credits(handle, credits); if (ret < 0) { mlog_errno(ret); @@ -2353,17 +2345,41 @@ static int ocfs2_dio_end_io_write(struct inode *ino= de, mlog_errno(ret); break; } + + if (++batch =3D=3D OCFS2_DIO_MARK_EXTENT_BATCH) { + ocfs2_commit_trans(osb, handle); + handle =3D NULL; + batch =3D 0; + } } =20 if (end > i_size_read(inode)) { + if (!handle) { + handle =3D ocfs2_start_trans(osb, credits); + if (IS_ERR(handle)) { + ret =3D PTR_ERR(handle); + mlog_errno(ret); + goto unlock; + } + } ret =3D ocfs2_set_inode_size(handle, inode, di_bh, end); if (ret < 0) mlog_errno(ret); } -commit: - ocfs2_commit_trans(osb, handle); + if (handle) + ocfs2_commit_trans(osb, handle); + unlock: up_write(&oi->ip_alloc_sem); + + /* everything looks good, let's start the cleanup */ + if (dwc->dw_orphaned) { + BUG_ON(dwc->dw_writer_pid !=3D task_pid_nr(current)); + + ret =3D ocfs2_del_inode_from_orphan(osb, inode, di_bh, 0, 0); + if (ret < 0) + mlog_errno(ret); + } ocfs2_inode_unlock(inode, 1); brelse(di_bh); out: --=20 2.43.0