summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVisa Hankala <visa@cvs.openbsd.org>2022-08-12 14:30:54 +0000
committerVisa Hankala <visa@cvs.openbsd.org>2022-08-12 14:30:54 +0000
commitc5809ba8cfd83d3a6df37582a7645dc07eb9240e (patch)
tree7138877aee9c5073e1f77d3506a754eaabdd303e
parentbfa0919b6d8400e745b440c872c27eb4dfabd548 (diff)
Put more struct vnode fields under splbio().
Buffer cache related struct vnode fields can be accessed in interrupt context. Be more consistent with the use of splbio(). OK mpi@
-rw-r--r--sys/kern/vfs_bio.c7
-rw-r--r--sys/kern/vfs_subr.c43
-rw-r--r--sys/msdosfs/msdosfs_vfsops.c12
-rw-r--r--sys/nfs/nfs_vfsops.c12
-rw-r--r--sys/nfs/nfs_vnops.c11
-rw-r--r--sys/sys/vnode.h17
-rw-r--r--sys/ufs/ext2fs/ext2fs_inode.c15
-rw-r--r--sys/ufs/ext2fs/ext2fs_vfsops.c10
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c10
9 files changed, 96 insertions, 41 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 1e29dfcbce0..7ff46e196b9 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_bio.c,v 1.208 2021/12/12 09:14:59 visa Exp $ */
+/* $OpenBSD: vfs_bio.c,v 1.209 2022/08/12 14:30:52 visa Exp $ */
/* $NetBSD: vfs_bio.c,v 1.44 1996/06/11 11:15:36 pk Exp $ */
/*
@@ -1554,7 +1554,10 @@ bufcache_getcleanbuf(int cachenum, int discard)
void
-discard_buffer(struct buf *bp) {
+discard_buffer(struct buf *bp)
+{
+ splassert(IPL_BIO);
+
bufcache_take(bp);
if (bp->b_vp) {
RBT_REMOVE(buf_rb_bufs,
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 13c70890ccc..4ace1adde8d 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_subr.c,v 1.315 2022/03/27 16:19:39 semarie Exp $ */
+/* $OpenBSD: vfs_subr.c,v 1.316 2022/08/12 14:30:52 visa Exp $ */
/* $NetBSD: vfs_subr.c,v 1.53 1996/04/22 01:39:13 christos Exp $ */
/*
@@ -662,16 +662,16 @@ vget(struct vnode *vp, int flags)
}
mtx_leave(&vnode_mtx);
+ s = splbio();
onfreelist = vp->v_bioflag & VBIOONFREELIST;
if (vp->v_usecount == 0 && onfreelist) {
- s = splbio();
if (vp->v_holdcnt > 0)
TAILQ_REMOVE(&vnode_hold_list, vp, v_freelist);
else
TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
vp->v_bioflag &= ~VBIOONFREELIST;
- splx(s);
}
+ splx(s);
vp->v_usecount++;
if (flags & LK_TYPE_MASK) {
@@ -749,6 +749,7 @@ void
vput(struct vnode *vp)
{
struct proc *p = curproc;
+ int s;
#ifdef DIAGNOSTIC
if (vp == NULL)
@@ -777,8 +778,10 @@ vput(struct vnode *vp)
VOP_INACTIVE(vp, p);
+ s = splbio();
if (vp->v_usecount == 0 && !(vp->v_bioflag & VBIOONFREELIST))
vputonfreelist(vp);
+ splx(s);
}
/*
@@ -790,6 +793,7 @@ int
vrele(struct vnode *vp)
{
struct proc *p = curproc;
+ int s;
#ifdef DIAGNOSTIC
if (vp == NULL)
@@ -822,8 +826,10 @@ vrele(struct vnode *vp)
VOP_INACTIVE(vp, p);
+ s = splbio();
if (vp->v_usecount == 0 && !(vp->v_bioflag & VBIOONFREELIST))
vputonfreelist(vp);
+ splx(s);
return (1);
}
@@ -831,6 +837,10 @@ vrele(struct vnode *vp)
void
vhold(struct vnode *vp)
{
+ int s;
+
+ s = splbio();
+
/*
* If it is on the freelist and the hold count is currently
* zero, move it to the hold list.
@@ -841,12 +851,18 @@ vhold(struct vnode *vp)
TAILQ_INSERT_TAIL(&vnode_hold_list, vp, v_freelist);
}
vp->v_holdcnt++;
+
+ splx(s);
}
/* Lose interest in a vnode. */
void
vdrop(struct vnode *vp)
{
+ int s;
+
+ s = splbio();
+
#ifdef DIAGNOSTIC
if (vp->v_holdcnt == 0)
panic("vdrop: zero holdcnt");
@@ -863,6 +879,8 @@ vdrop(struct vnode *vp)
TAILQ_REMOVE(&vnode_hold_list, vp, v_freelist);
TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
}
+
+ splx(s);
}
/*
@@ -909,6 +927,7 @@ vflush_vnode(struct vnode *vp, void *arg)
{
struct vflush_args *va = arg;
struct proc *p = curproc;
+ int empty, s;
if (vp == va->skipvp) {
return (0);
@@ -958,8 +977,11 @@ vflush_vnode(struct vnode *vp, void *arg)
* XXX Might be nice to check per-fs "inode" flags, but
* generally the filesystem is sync'd already, right?
*/
- if ((va->flags & IGNORECLEAN) &&
- LIST_EMPTY(&vp->v_dirtyblkhd))
+ s = splbio();
+ empty = (va->flags & IGNORECLEAN) && LIST_EMPTY(&vp->v_dirtyblkhd);
+ splx(s);
+
+ if (empty)
return (0);
#ifdef DEBUG_SYSCTL
@@ -992,6 +1014,7 @@ void
vclean(struct vnode *vp, int flags, struct proc *p)
{
int active, do_wakeup = 0;
+ int s;
/*
* Check to see if the vnode is in use.
@@ -1066,9 +1089,11 @@ vclean(struct vnode *vp, int flags, struct proc *p)
if (active) {
vp->v_usecount--;
if (vp->v_usecount == 0) {
+ s = splbio();
if (vp->v_holdcnt > 0)
panic("vclean: not clean");
vputonfreelist(vp);
+ splx(s);
}
}
cache_purge(vp);
@@ -1125,6 +1150,7 @@ vgonel(struct vnode *vp, struct proc *p)
{
struct vnode *vq;
struct vnode *vx;
+ int s;
KASSERT(vp->v_uvcount == 0);
@@ -1192,12 +1218,9 @@ vgonel(struct vnode *vp, struct proc *p)
* Move onto the free list, unless we were called from
* getnewvnode and we're not on any free list
*/
+ s = splbio();
if (vp->v_usecount == 0 &&
(vp->v_bioflag & VBIOONFREELIST)) {
- int s;
-
- s = splbio();
-
if (vp->v_holdcnt > 0)
panic("vgonel: not clean");
@@ -1205,8 +1228,8 @@ vgonel(struct vnode *vp, struct proc *p)
TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_freelist);
}
- splx(s);
}
+ splx(s);
}
/*
diff --git a/sys/msdosfs/msdosfs_vfsops.c b/sys/msdosfs/msdosfs_vfsops.c
index 543854c7a7e..0de37665dfd 100644
--- a/sys/msdosfs/msdosfs_vfsops.c
+++ b/sys/msdosfs/msdosfs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: msdosfs_vfsops.c,v 1.95 2021/11/13 18:18:59 kn Exp $ */
+/* $OpenBSD: msdosfs_vfsops.c,v 1.96 2022/08/12 14:30:52 visa Exp $ */
/* $NetBSD: msdosfs_vfsops.c,v 1.48 1997/10/18 02:54:57 briggs Exp $ */
/*-
@@ -640,16 +640,22 @@ int
msdosfs_sync_vnode(struct vnode *vp, void *arg)
{
struct msdosfs_sync_arg *msa = arg;
- int error;
struct denode *dep;
+ int error;
+ int s, skip = 0;
dep = VTODE(vp);
+ s = splbio();
if (vp->v_type == VNON ||
((dep->de_flag & (DE_ACCESS | DE_CREATE | DE_UPDATE | DE_MODIFIED)) == 0
&& LIST_EMPTY(&vp->v_dirtyblkhd)) ||
msa->waitfor == MNT_LAZY) {
- return (0);
+ skip = 1;
}
+ splx(s);
+
+ if (skip)
+ return (0);
if (vget(vp, LK_EXCLUSIVE | LK_NOWAIT))
return (0);
diff --git a/sys/nfs/nfs_vfsops.c b/sys/nfs/nfs_vfsops.c
index d0a7bcf38bc..5b06158752d 100644
--- a/sys/nfs/nfs_vfsops.c
+++ b/sys/nfs/nfs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_vfsops.c,v 1.126 2021/01/02 02:41:42 cheloha Exp $ */
+/* $OpenBSD: nfs_vfsops.c,v 1.127 2022/08/12 14:30:53 visa Exp $ */
/* $NetBSD: nfs_vfsops.c,v 1.46.4.1 1996/05/25 22:40:35 fvdl Exp $ */
/*
@@ -793,7 +793,8 @@ int
nfs_sync(struct mount *mp, int waitfor, int stall, struct ucred *cred, struct proc *p)
{
struct vnode *vp;
- int error, allerror = 0;
+ int allerror = 0;
+ int empty, error, s;
/*
* Don't traverse the vnode list if we want to skip all of them.
@@ -812,7 +813,12 @@ loop:
*/
if (vp->v_mount != mp)
goto loop;
- if (VOP_ISLOCKED(vp) || LIST_EMPTY(&vp->v_dirtyblkhd))
+ if (VOP_ISLOCKED(vp))
+ continue;
+ s = splbio();
+ empty = LIST_EMPTY(&vp->v_dirtyblkhd);
+ splx(s);
+ if (empty)
continue;
if (vget(vp, LK_EXCLUSIVE))
goto loop;
diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c
index 3cc87e3bc52..8e10c520ef8 100644
--- a/sys/nfs/nfs_vnops.c
+++ b/sys/nfs/nfs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_vnops.c,v 1.189 2022/06/26 05:20:42 visa Exp $ */
+/* $OpenBSD: nfs_vnops.c,v 1.190 2022/08/12 14:30:53 visa Exp $ */
/* $NetBSD: nfs_vnops.c,v 1.62.4.1 1996/07/08 20:26:52 jtc Exp $ */
/*
@@ -2849,7 +2849,7 @@ nfs_flush(struct vnode *vp, struct ucred *cred, int waitfor, struct proc *p,
struct nfsmount *nmp = VFSTONFS(vp->v_mount);
uint64_t slptimeo = INFSLP;
int s, error = 0, slpflag = 0, retv, bvecpos;
- int passone = 1;
+ int dirty, passone = 1;
u_quad_t off = (u_quad_t)-1, endoff = 0, toff;
#ifndef NFS_COMMITBVECSIZ
#define NFS_COMMITBVECSIZ 20
@@ -2982,8 +2982,8 @@ loop:
loop2:
s = splbio();
error = vwaitforio(vp, slpflag, "nfs_fsync", slptimeo);
- splx(s);
if (error) {
+ splx(s);
if (nfs_sigintr(nmp, NULL, p))
return (EINTR);
if (slpflag == PCATCH) {
@@ -2992,8 +2992,9 @@ loop:
}
goto loop2;
}
-
- if (!LIST_EMPTY(&vp->v_dirtyblkhd) && commit) {
+ dirty = (!LIST_EMPTY(&vp->v_dirtyblkhd) && commit);
+ splx(s);
+ if (dirty) {
#if 0
vprint("nfs_fsync: dirty", vp);
#endif
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index a5adb99a033..c9bb267e78e 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vnode.h,v 1.166 2022/06/26 05:20:42 visa Exp $ */
+/* $OpenBSD: vnode.h,v 1.167 2022/08/12 14:30:53 visa Exp $ */
/* $NetBSD: vnode.h,v 1.38 1996/02/29 20:59:05 cgd Exp $ */
/*
@@ -104,18 +104,17 @@ struct vnode {
u_int v_writecount; /* reference count of writers */
u_int v_lockcount; /* [V] # threads waiting on lock */
- /* Flags that can be read/written in interrupts */
- u_int v_bioflag;
- u_int v_holdcnt; /* buffer references */
+ u_int v_bioflag; /* [B] flags accessed in interrupts */
+ u_int v_holdcnt; /* [B] buffer references */
u_int v_id; /* capability identifier */
struct mount *v_mount; /* ptr to vfs we are in */
- TAILQ_ENTRY(vnode) v_freelist; /* vnode freelist */
+ TAILQ_ENTRY(vnode) v_freelist; /* [B] vnode freelist */
TAILQ_ENTRY(vnode) v_mntvnodes; /* vnodes for mount point */
- struct buf_rb_bufs v_bufs_tree; /* lookup of all bufs */
- struct buflists v_cleanblkhd; /* clean blocklist head */
- struct buflists v_dirtyblkhd; /* dirty blocklist head */
+ struct buf_rb_bufs v_bufs_tree;/* [B] lookup of all bufs */
+ struct buflists v_cleanblkhd; /* [B] clean blocklist head */
+ struct buflists v_dirtyblkhd; /* [B] dirty blocklist head */
u_int v_numoutput; /* [B] num of writes in progress */
- LIST_ENTRY(vnode) v_synclist; /* vnode with dirty buffers */
+ LIST_ENTRY(vnode) v_synclist; /* [B] vnode with dirty buffers */
union {
struct mount *vu_mountedhere;/* ptr to mounted vfs (VDIR) */
struct socket *vu_socket; /* unix ipc (VSOCK) */
diff --git a/sys/ufs/ext2fs/ext2fs_inode.c b/sys/ufs/ext2fs/ext2fs_inode.c
index 5c76a5956b3..2962628f865 100644
--- a/sys/ufs/ext2fs/ext2fs_inode.c
+++ b/sys/ufs/ext2fs/ext2fs_inode.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ext2fs_inode.c,v 1.65 2021/12/12 09:14:59 visa Exp $ */
+/* $OpenBSD: ext2fs_inode.c,v 1.66 2022/08/12 14:30:53 visa Exp $ */
/* $NetBSD: ext2fs_inode.c,v 1.24 2001/06/19 12:59:18 wiz Exp $ */
/*
@@ -387,10 +387,15 @@ done:
for (i = 0; i < NDADDR; i++)
if (newblks[i] != oip->i_e2fs_blocks[i])
panic("ext2fs_truncate2");
- if (length == 0 &&
- (!LIST_EMPTY(&ovp->v_cleanblkhd) ||
- !LIST_EMPTY(&ovp->v_dirtyblkhd)))
- panic("ext2fs_truncate3");
+ if (length == 0) {
+ int s;
+
+ s = splbio();
+ if (!LIST_EMPTY(&ovp->v_cleanblkhd) ||
+ !LIST_EMPTY(&ovp->v_dirtyblkhd))
+ panic("ext2fs_truncate3");
+ splx(s);
+ }
#endif /* DIAGNOSTIC */
/*
* Put back the real size.
diff --git a/sys/ufs/ext2fs/ext2fs_vfsops.c b/sys/ufs/ext2fs/ext2fs_vfsops.c
index 371ca53f096..af3f0a9ab33 100644
--- a/sys/ufs/ext2fs/ext2fs_vfsops.c
+++ b/sys/ufs/ext2fs/ext2fs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ext2fs_vfsops.c,v 1.116 2021/10/04 08:11:02 claudio Exp $ */
+/* $OpenBSD: ext2fs_vfsops.c,v 1.117 2022/08/12 14:30:53 visa Exp $ */
/* $NetBSD: ext2fs_vfsops.c,v 1.1 1997/06/11 09:34:07 bouyer Exp $ */
/*
@@ -713,6 +713,7 @@ ext2fs_sync_vnode(struct vnode *vp, void *args)
struct ext2fs_sync_args *esa = args;
struct inode *ip;
int error, nlink0 = 0;
+ int s, skip = 0;
if (vp->v_type == VNON)
return (0);
@@ -722,10 +723,15 @@ ext2fs_sync_vnode(struct vnode *vp, void *args)
if (ip->i_e2fs_nlink == 0)
nlink0 = 1;
+ s = splbio();
if ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
LIST_EMPTY(&vp->v_dirtyblkhd)) {
- goto end;
+ skip = 1;
}
+ splx(s);
+
+ if (skip)
+ goto end;
if (vget(vp, LK_EXCLUSIVE | LK_NOWAIT)) {
esa->inflight = MIN(esa->inflight+1, 65536);
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index b513a271877..730a36b0fab 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_vfsops.c,v 1.192 2021/10/20 06:35:39 semarie Exp $ */
+/* $OpenBSD: ffs_vfsops.c,v 1.193 2022/08/12 14:30:53 visa Exp $ */
/* $NetBSD: ffs_vfsops.c,v 1.19 1996/02/09 22:22:26 christos Exp $ */
/*
@@ -1159,6 +1159,7 @@ ffs_sync_vnode(struct vnode *vp, void *arg)
struct ffs_sync_args *fsa = arg;
struct inode *ip;
int error, nlink0 = 0;
+ int s, skip = 0;
if (vp->v_type == VNON)
return (0);
@@ -1177,11 +1178,16 @@ ffs_sync_vnode(struct vnode *vp, void *arg)
if (ip->i_effnlink == 0)
nlink0 = 1;
+ s = splbio();
if ((ip->i_flag &
(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
LIST_EMPTY(&vp->v_dirtyblkhd)) {
- goto end;
+ skip = 1;
}
+ splx(s);
+
+ if (skip)
+ goto end;
if (vget(vp, LK_EXCLUSIVE | LK_NOWAIT)) {
fsa->inflight = MIN(fsa->inflight+1, 65536);