From: visa Date: Fri, 12 Aug 2022 14:30:52 +0000 (+0000) Subject: Put more struct vnode fields under splbio(). X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=4b515238dee48c80cd9fb2e28481e0de01f4bd43;p=openbsd 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@ --- 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);