Skip to content

Commit 4c45ede

Browse files
perseantperseant
authored andcommitted
Avoid a deadlock between vnode reclamation and lfs_writevnodes(). A vnode
being reclaimed will be in state VS_RECLAIMING, while it attemmpts to get the segment lock. lfs_writevnodes() holds the segment lock while traversing the list of vnodes; so it must skip vnodes in the process of reclamation in order to avoid a deadlock.
1 parent d92f4a9 commit 4c45ede

1 file changed

Lines changed: 14 additions & 2 deletions

File tree

sys/ufs/lfs/lfs_segment.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $NetBSD: lfs_segment.c,v 1.306 2025/12/11 01:27:24 perseant Exp $ */
1+
/* $NetBSD: lfs_segment.c,v 1.307 2026/01/20 15:30:15 perseant Exp $ */
22

33
/*-
44
* Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
@@ -60,7 +60,7 @@
6060
*/
6161

6262
#include <sys/cdefs.h>
63-
__KERNEL_RCSID(0, "$NetBSD: lfs_segment.c,v 1.306 2025/12/11 01:27:24 perseant Exp $");
63+
__KERNEL_RCSID(0, "$NetBSD: lfs_segment.c,v 1.307 2026/01/20 15:30:15 perseant Exp $");
6464

6565
#ifdef DEBUG
6666
# define vndebug(vp, str) do { \
@@ -91,6 +91,7 @@ __KERNEL_RCSID(0, "$NetBSD: lfs_segment.c,v 1.306 2025/12/11 01:27:24 perseant E
9191
#include <sys/mount.h>
9292
#include <sys/kauth.h>
9393
#include <sys/syslog.h>
94+
#include <sys/vnode_impl.h>
9495
#include <sys/workqueue.h>
9596

9697
#include <miscfs/specfs/specdev.h>
@@ -416,9 +417,20 @@ lfs_writevnodes_selector(void *cl, struct vnode *vp)
416417
struct lfs_writevnodes_ctx *c = cl;
417418
struct inode *ip;
418419
int op = c->op;
420+
vnode_impl_t *vip = VNODE_TO_VIMPL(vp);
419421

420422
KASSERT(mutex_owned(vp->v_interlock));
421423

424+
/*
425+
* A vnode being reclaimed will be in state VS_RECLAIMING
426+
* while it attemmpts to get the segment lock. We hold the
427+
* segment lock, so we must skip these vnodes in order to
428+
* avoid a deadlock.
429+
*/
430+
if (vip->vi_state != VS_LOADED && vip->vi_state != VS_RECLAIMED
431+
&& !IS_FLUSHING(c->fs, vp))
432+
return false;
433+
422434
ip = VTOI(vp);
423435
if (ip == NULL || vp->v_type == VNON || ip->i_nlink <= 0)
424436
return false;

0 commit comments

Comments
 (0)