From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794532342; b=PICuiWTOrn1y1NrNnm+g/3vSuOuOjw8XGEq1/Uje/huadvyrjsQayRGDJoAX9znJ4MuJ mKyDpbxOP6sCnN84sNl0YVmQDPbaaMjpTK/1lRDFjXwNA8MRZmpgj9+wvri0fKAI/2STZ av/YBCiBuiWwN70miYCNofsAztRKDawcucGhtzW5hh1o/GJTr4xnF5fXTvzXYb7mPp/Im wdiOcSRTyiLY/W/SAPFMhhXOKMArPtdK8BYkbjJFLLU4o6IQx9gKpZwLoUth151LLjNHu VF9aGjPrdEqxBp2ENF5Jl0u2X09nRk1ejPQtJQixSZXXq4H2jHIRGhhjpXkHuONxe9w== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794532342; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:MIME-Version:Content-Transfer-Encoding; bh=b/VX43gWEi/O70UuMifK1uuZWMGBnjeoYlWDJz1FR4Y=; b=uRGDn59N8ulSZxROp+czoGWBOKRR4baQR1hsq01lZ75ksdPL0i7Fr8YhGr1pftnvIl+8 oSrYvVF1SIzNtJphxP9AfhMtjrm1zscpFw5pQrWbOP/bKpRU6uyrNTfpAYDNi4rIbol6L 4IZlXeES9qDappW0bT7HfpI9nsGBnTcF+NFr2KilPUihNbj5gnjTZpJmiWMIj1z6stjz3 uz3lABYXtL/VOZ7RatMjMoxH5vmf8pwQWV4svvzAxKnqinieL/xm2ou3I1EG7/CJudfSv ihlZAXbnu3ohB3ES0d2DhFOv2wEsoKAU0d77yizyIKksak3EW30o+wF+FYFYI5ra6Zg== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=cj+O3hOW; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 72662606A32A for ; Fri, 13 Nov 2026 01:12:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=cj+O3hOW Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5698B1F000C6; Fri, 13 Nov 2026 01:12:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1794532342; bh=b/VX43gWEi/O70UuMifK1uuZWMGBnjeoYlWDJz1FR4Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=cj+O3hOWqmCv1tD2rDbTIUmZSfWuSOc1uEBTParLGumxM4JuRHpOSOPrWoNC8cQ5Q bStcepprG/uoMUixjMYkeN4+x0/8s9A86cGDG4fG3/gaJUTlx5y0BqJZklLFlmYax6 YbfTVqkaaTvu3zjcY22w3AncudGISKBNcdd4ztjCeRdLY9K8OuG1OKtgS1V4G8vhYJ 52lhCHzOgJhiQAZdf2WVLDzABU2JwMLzFpixeChY8a4w0eoTUQHq1KmRGcF7dY3Nb9 vsnGDlHWMdKq11CG2jhlDafLAEa+sqpXKQYpzn2tVldkHLo1Ef+ZKvH5oM3duJzrQ+ /sBpzQPQ4gXxQ== From: Sasha Levin To: stable@vger.kernel.org Cc: Cen Zhang , Andrew Morton , Joseph Qi , Mark Fasheh , Joel Becker , Heming Zhao , Jia-Ju Bai , jjzuming@gmail.com, Sasha Levin Subject: [PATCH 5.10.y 2/2] ocfs2: cache the mount context for dentry lock callbacks Date: Thu, 12 Nov 2026 20:12:18 -0500 Message-ID: <20261113011204.583671-2-sashal@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20261113011204.583671-1-sashal@kernel.org> References: <20261109202711-failed-5.10-5b4696e0bfc3@kernel.org> <20261113011204.583671-1-sashal@kernel.org> X-Mailing-List: stable@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Cen Zhang [ Upstream commit 5b4696e0bfc358619adaeab25ad35b4979af8331 ] ocfs2_drop_dentry_lock() drops the inode reference before releasing the DENTRY lock. This lets inode eviction release the local inode and open locks before a remote unlink can proceed past the DENTRY lock. A DLM callback can still arrive before the DENTRY lock has been dropped. ocfs2_get_dentry_osb() obtains the mount context through dl_inode->i_sb, which can access a freed inode when the downconvert thread drops the last inode reference in its post-unlock callback: Downconvert thread DLM callback thread ------------------ ------------------- ocfs2_process_blocked_lock() ocfs2_dentry_post_unlock() ocfs2_dentry_lock_put() ocfs2_drop_dentry_lock() iput(dl->dl_inode) [inode reclaimed after RCU] ocfs2_blocking_ast() ocfs2_get_dentry_osb() dl->dl_inode->i_sb ocfs2_simple_drop_lockres() Store the mount context in the DENTRY lock resource's l_priv field and use the default mount-context lookup. Recover the containing dentry lock with container_of(), as already done for refcount locks, and remove ocfs2_get_dentry_osb(). ocfs2_dismount_volume() shuts down the DLM before freeing the mount context, so callbacks can use it without accessing the inode. Preserve the existing iput-before-unlock order to avoid delaying local inode and open lock release until after the DENTRY lock is released. Link: https://lore.kernel.org/pm-ocfs2-objects-candidate-0012-v9-eeb9084fb29577971229@gmail.com Fixes: 8ed6b23709b3 ("ocfs2: revert iput deferring code in ocfs2_drop_dentry_lock") Signed-off-by: Cen Zhang Signed-off-by: Andrew Morton Suggested-by: Joseph Qi Reviewed-by: Joseph Qi Assisted-by: LLM Cc: Mark Fasheh Cc: Joel Becker Cc: Heming Zhao Cc: Jia-Ju Bai Cc: Cc: Signed-off-by: Sasha Levin --- fs/ocfs2/dcache.h | 5 ++--- fs/ocfs2/dlmglue.c | 16 ++++------------ 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/fs/ocfs2/dcache.h b/fs/ocfs2/dcache.h index 3686a52ba1435..2e7fa014942d5 100644 --- a/fs/ocfs2/dcache.h +++ b/fs/ocfs2/dcache.h @@ -19,9 +19,8 @@ struct ocfs2_dentry_lock { u64 dl_parent_blkno; /* - * The ocfs2_dentry_lock keeps an inode reference until - * dl_lockres has been destroyed. This is usually done in - * ->d_iput() anyway, so there should be minimal impact. + * The inode reference is dropped before dl_lockres is unlocked. + * Callbacks must not use it to find the mount context during teardown. */ struct inode *dl_inode; struct ocfs2_lock_res dl_lockres; diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 6338ee9fc5a47..8d51575c348d2 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c @@ -57,7 +57,6 @@ struct ocfs2_mask_waiter { #endif }; -static struct ocfs2_super *ocfs2_get_dentry_osb(struct ocfs2_lock_res *lockres); static struct ocfs2_super *ocfs2_get_inode_osb(struct ocfs2_lock_res *lockres); static struct ocfs2_super *ocfs2_get_file_osb(struct ocfs2_lock_res *lockres); static struct ocfs2_super *ocfs2_get_qinfo_osb(struct ocfs2_lock_res *lockres); @@ -257,7 +256,6 @@ static const struct ocfs2_lock_res_ops ocfs2_orphan_scan_lops = { }; static const struct ocfs2_lock_res_ops ocfs2_dentry_lops = { - .get_osb = ocfs2_get_dentry_osb, .post_unlock = ocfs2_dentry_post_unlock, .downconvert_worker = ocfs2_dentry_convert_worker, .flags = 0, @@ -308,7 +306,7 @@ static inline struct ocfs2_dentry_lock *ocfs2_lock_res_dl(struct ocfs2_lock_res { BUG_ON(lockres->l_type != OCFS2_LOCK_TYPE_DENTRY); - return (struct ocfs2_dentry_lock *)lockres->l_priv; + return container_of(lockres, struct ocfs2_dentry_lock, dl_lockres); } static inline struct ocfs2_mem_dqinfo *ocfs2_lock_res_qinfo(struct ocfs2_lock_res *lockres) @@ -609,13 +607,6 @@ static __u64 ocfs2_get_dentry_lock_ino(struct ocfs2_lock_res *lockres) return be64_to_cpu(inode_blkno_be); } -static struct ocfs2_super *ocfs2_get_dentry_osb(struct ocfs2_lock_res *lockres) -{ - struct ocfs2_dentry_lock *dl = lockres->l_priv; - - return OCFS2_SB(dl->dl_inode->i_sb); -} - void ocfs2_dentry_lock_res_init(struct ocfs2_dentry_lock *dl, u64 parent, struct inode *inode) { @@ -623,6 +614,7 @@ void ocfs2_dentry_lock_res_init(struct ocfs2_dentry_lock *dl, u64 inode_blkno = OCFS2_I(inode)->ip_blkno; __be64 inode_blkno_be = cpu_to_be64(inode_blkno); struct ocfs2_lock_res *lockres = &dl->dl_lockres; + struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); ocfs2_lock_res_init_once(lockres); @@ -651,9 +643,9 @@ void ocfs2_dentry_lock_res_init(struct ocfs2_dentry_lock *dl, memcpy(&lockres->l_name[OCFS2_DENTRY_LOCK_INO_START], &inode_blkno_be, sizeof(__be64)); - ocfs2_lock_res_init_common(OCFS2_SB(inode->i_sb), lockres, + ocfs2_lock_res_init_common(osb, lockres, OCFS2_LOCK_TYPE_DENTRY, &ocfs2_dentry_lops, - dl); + osb); } static void ocfs2_super_lock_res_init(struct ocfs2_lock_res *res, -- 2.53.0