mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Joseph Qi <joseph.qi@linux.alibaba.com>
To: Cen Zhang <zzzccc427@gmail.com>,
	Andrew Morton <akpm@linux-foundation.org>
Cc: mark@fasheh.com, jlbec@evilplan.org, heming.zhao@suse.com,
	ocfs2-devel@lists.linux.dev, linux-kernel@vger.kernel.org,
	stable@vger.kernel.org, baijiaju1990@gmail.com,
	jjzuming@gmail.com
Subject: Re: [PATCH] ocfs2/dlmfs: keep the superblock alive during lock work
Date: Wed, 4 Nov 2026 17:18:52 +0800	[thread overview]
Message-ID: <c625feef-9fb4-4a32-b40f-5d118768c587@linux.alibaba.com> (raw)
In-Reply-To: <pm-ocfs2-objects-candidate-0054-v6-c3887cceae3b039e591e@gmail.com>



On 10/29/26 3:00 PM, Cen Zhang wrote:
> Queued dlmfs lock work holds an inode reference, but no active reference
> to its superblock. The workqueue is drained on module exit rather than
> on each dlmfs unmount, and an inode reference does not stop superblock
> shutdown: generic_shutdown_super() reports the busy inode and goes on.
> 
>   DLM callback / worker               Unmount
>   ---------------------               -------
>   queue lock work; igrab(inode)
>   worker delayed
>                                       drop last active superblock ref
>                                       kill_anon_super()
>                                         report the busy inode
>                                         free the superblock
>   finish lock work
>   iput(inode)
>     access the inode's freed superblock
> 
> Flushing the workqueue from a dlmfs kill_sb would not be enough: a
> blocking AST can queue new work for an inode that is still alive after
> the flush and before eviction, and that work again holds only an inode
> reference.
> 
> Take an active superblock reference before acquiring the queued inode
> reference, with the atomic_inc_not_zero() on s_active that grab_super()
> and the NFS and procfs superblock walkers use. Decline to queue if the
> superblock is already shutting down; the inode is then being evicted
> and user_dlm_destroy_lock() tears the lock down. The existing l_lock
> and USER_LOCK_QUEUED flag serialize this with other queue attempts.
> Each execution drops its inode reference before releasing the active
> superblock reference, outside l_lock. If that releases the last active
> reference, the unmount completes on the worker; it only waits for DLM
> replies and never for this workqueue.
> 
> Only the relevant frames of the report are kept:
> 
> Oops: general protection fault, probably for non-canonical address 0xfbd59c0000000026: 0000 [#1] SMP KASAN NOPTI
> KASAN: maybe wild-memory-access in range [0xdead000000000130-0xdead000000000137]
> Workqueue: user_dlm user_dlm_unblock_lock
> RIP: 0010:iput+0x246/0xc10
> Call Trace:
>  <TASK>
>  user_dlm_unblock_lock+0x503/0xa50
>  process_one_work+0x9a8/0x1b40
>  worker_thread+0x65c/0xe40
>  </TASK>
> 
> Fixes: 8df08c89c668 ("[PATCH] OCFS2: The Second Oracle Cluster Filesystem")
> Cc: stable@vger.kernel.org
> Assisted-by: LLM
> Signed-off-by: Cen Zhang <zzzccc427@gmail.com>

Looks fine.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>

> ---
>  fs/ocfs2/dlmfs/userdlm.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/ocfs2/dlmfs/userdlm.c b/fs/ocfs2/dlmfs/userdlm.c
> index 617c92e7b925..516e50a5728d 100644
> --- a/fs/ocfs2/dlmfs/userdlm.c
> +++ b/fs/ocfs2/dlmfs/userdlm.c
> @@ -162,7 +162,13 @@ static void user_dlm_unblock_lock(struct work_struct *work);
>  
>  static void __user_dlm_queue_lockres(struct user_lock_res *lockres)
>  {
> +	struct inode *inode = user_dlm_inode_from_user_lockres(lockres);
> +
>  	if (!(lockres->l_flags & USER_LOCK_QUEUED)) {
> +		/* Pin the superblock through the worker's iput(). */
> +		if (!atomic_inc_not_zero(&inode->i_sb->s_active))
> +			return;
> +
>  		user_dlm_grab_inode_ref(lockres);
>  
>  		INIT_WORK(&lockres->l_work, user_dlm_unblock_lock);
> @@ -275,9 +281,11 @@ static struct ocfs2_locking_protocol user_dlm_lproto = {
>  
>  static inline void user_dlm_drop_inode_ref(struct user_lock_res *lockres)
>  {
> -	struct inode *inode;
> -	inode = user_dlm_inode_from_user_lockres(lockres);
> +	struct inode *inode = user_dlm_inode_from_user_lockres(lockres);
> +	struct super_block *sb = inode->i_sb;
> +
>  	iput(inode);
> +	deactivate_super(sb);
>  }
>  
>  static void user_dlm_unblock_lock(struct work_struct *work)


      reply	other threads:[~2026-11-04  9:19 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-29  7:00 Cen Zhang
2026-11-04  9:18 ` Joseph Qi [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c625feef-9fb4-4a32-b40f-5d118768c587@linux.alibaba.com \
    --to=joseph.qi@linux.alibaba.com \
    --cc=akpm@linux-foundation.org \
    --cc=baijiaju1990@gmail.com \
    --cc=heming.zhao@suse.com \
    --cc=jjzuming@gmail.com \
    --cc=jlbec@evilplan.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark@fasheh.com \
    --cc=ocfs2-devel@lists.linux.dev \
    --cc=stable@vger.kernel.org \
    --cc=zzzccc427@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®