From 20eba72f53257b248e358164d2d2befdd5cfa5c2 Mon Sep 17 00:00:00 2001 From: Poul-Henning Kamp Date: Wed, 27 Oct 2004 08:05:02 +0000 Subject: [PATCH] Move the syncer linkage from vnode to bufobj. This is not quite a perfect separation: the syncer still think it knows that everything is a vnode. --- sys/kern/vfs_subr.c | 76 +++++++++++++++++++++++++-------------------- sys/sys/buf.h | 5 +-- sys/sys/bufobj.h | 9 ++++-- sys/sys/vnode.h | 6 ---- 4 files changed, 52 insertions(+), 44 deletions(-) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index a7d3fc8b9ba..aa6cc4b796e 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -193,11 +193,11 @@ int prtactive; */ static int syncer_delayno; static long syncer_mask; -LIST_HEAD(synclist, vnode); +LIST_HEAD(synclist, bufobj); static struct synclist *syncer_workitem_pending; /* * The sync_mtx protects: - * vp->v_synclist + * bo->bo_synclist * sync_vnode_count * syncer_delayno * syncer_state @@ -831,6 +831,7 @@ getnewvnode(tag, mp, vops, vpp) VI_LOCK(vp); vp->v_dd = vp; bo = &vp->v_bufobj; + bo->bo_private = vp; bo->bo_mtx = &vp->v_interlock; vp->v_vnlock = &vp->v_lock; lockinit(vp->v_vnlock, PVFS, tag, VLKTIMEOUT, LK_NOPAUSE); @@ -927,8 +928,8 @@ vinvalbuf(vp, flags, cred, td, slpflag, slptimeo) ASSERT_VOP_LOCKED(vp, "vinvalbuf"); - VI_LOCK(vp); bo = &vp->v_bufobj; + BO_LOCK(bo); if (flags & V_SAVE) { error = bufobj_wwait(bo, slpflag, slptimeo); if (error) { @@ -1397,39 +1398,39 @@ brelvp(struct buf *bp) /* * Delete from old vnode list, if on one. */ - vp = bp->b_vp; - VI_LOCK(vp); + vp = bp->b_vp; /* XXX */ bo = bp->b_bufobj; + BO_LOCK(bo); if (bp->b_xflags & (BX_VNDIRTY | BX_VNCLEAN)) buf_vlist_remove(bp); - if ((vp->v_iflag & VI_ONWORKLST) && bo->bo_dirty.bv_cnt == 0) { - vp->v_iflag &= ~VI_ONWORKLST; + if ((bo->bo_flag & BO_ONWORKLST) && bo->bo_dirty.bv_cnt == 0) { + bo->bo_flag &= ~BO_ONWORKLST; mtx_lock(&sync_mtx); - LIST_REMOVE(vp, v_synclist); + LIST_REMOVE(bo, bo_synclist); syncer_worklist_len--; mtx_unlock(&sync_mtx); } vdropl(vp); bp->b_vp = NULL; bp->b_bufobj = NULL; - VI_UNLOCK(vp); + BO_UNLOCK(bo); } /* * Add an item to the syncer work queue. */ static void -vn_syncer_add_to_worklist(struct vnode *vp, int delay) +vn_syncer_add_to_worklist(struct bufobj *bo, int delay) { int slot; - ASSERT_VI_LOCKED(vp, "vn_syncer_add_to_worklist"); + ASSERT_BO_LOCKED(bo); mtx_lock(&sync_mtx); - if (vp->v_iflag & VI_ONWORKLST) - LIST_REMOVE(vp, v_synclist); + if (bo->bo_flag & BO_ONWORKLST) + LIST_REMOVE(bo, bo_synclist); else { - vp->v_iflag |= VI_ONWORKLST; + bo->bo_flag |= BO_ONWORKLST; syncer_worklist_len++; } @@ -1437,7 +1438,7 @@ vn_syncer_add_to_worklist(struct vnode *vp, int delay) delay = syncer_maxdelay - 2; slot = (syncer_delayno + delay) & syncer_mask; - LIST_INSERT_HEAD(&syncer_workitem_pending[slot], vp, v_synclist); + LIST_INSERT_HEAD(&syncer_workitem_pending[slot], bo, bo_synclist); mtx_unlock(&sync_mtx); } @@ -1474,6 +1475,7 @@ sched_sync(void) struct synclist *next; struct synclist *slp; struct vnode *vp; + struct bufobj *bo; struct mount *mp; long starttime; struct thread *td = FIRST_THREAD_IN_PROC(updateproc); @@ -1549,16 +1551,17 @@ sched_sync(void) last_work_seen = syncer_delayno; if (net_worklist_len > 0 && syncer_state == SYNCER_FINAL_DELAY) syncer_state = SYNCER_SHUTTING_DOWN; - while ((vp = LIST_FIRST(slp)) != NULL) { + while ((bo = LIST_FIRST(slp)) != NULL) { + vp = bo->bo_private; /* XXX */ if (VOP_ISLOCKED(vp, NULL) != 0 || vn_start_write(vp, &mp, V_NOWAIT) != 0) { - LIST_REMOVE(vp, v_synclist); - LIST_INSERT_HEAD(next, vp, v_synclist); + LIST_REMOVE(bo, bo_synclist); + LIST_INSERT_HEAD(next, bo, bo_synclist); continue; } if (VI_TRYLOCK(vp) == 0) { - LIST_REMOVE(vp, v_synclist); - LIST_INSERT_HEAD(next, vp, v_synclist); + LIST_REMOVE(bo, bo_synclist); + LIST_INSERT_HEAD(next, bo, bo_synclist); vn_finished_write(mp); continue; } @@ -1575,14 +1578,14 @@ sched_sync(void) VOP_UNLOCK(vp, 0, td); vn_finished_write(mp); VI_LOCK(vp); - if ((vp->v_iflag & VI_ONWORKLST) != 0) { + if ((bo->bo_flag & BO_ONWORKLST) != 0) { /* * Put us back on the worklist. The worklist * routine will remove us from our current * position and then add us back in at a later * position. */ - vn_syncer_add_to_worklist(vp, syncdelay); + vn_syncer_add_to_worklist(bo, syncdelay); } vdropl(vp); VI_UNLOCK(vp); @@ -1759,7 +1762,7 @@ reassignbuf(struct buf *bp) * of clean buffers. */ if (bp->b_flags & B_DELWRI) { - if ((vp->v_iflag & VI_ONWORKLST) == 0) { + if ((bo->bo_flag & BO_ONWORKLST) == 0) { switch (vp->v_type) { case VDIR: delay = dirdelay; @@ -1770,18 +1773,18 @@ reassignbuf(struct buf *bp) default: delay = filedelay; } - vn_syncer_add_to_worklist(vp, delay); + vn_syncer_add_to_worklist(bo, delay); } buf_vlist_add(bp, bo, BX_VNDIRTY); } else { buf_vlist_add(bp, bo, BX_VNCLEAN); - if ((vp->v_iflag & VI_ONWORKLST) && bo->bo_dirty.bv_cnt == 0) { + if ((bo->bo_flag & BO_ONWORKLST) && bo->bo_dirty.bv_cnt == 0) { mtx_lock(&sync_mtx); - LIST_REMOVE(vp, v_synclist); + LIST_REMOVE(bo, bo_synclist); syncer_worklist_len--; mtx_unlock(&sync_mtx); - vp->v_iflag &= ~VI_ONWORKLST; + bo->bo_flag &= ~BO_ONWORKLST; } } VI_UNLOCK(vp); @@ -3329,7 +3332,8 @@ vfs_allocate_syncvnode(mp) next = start; } VI_LOCK(vp); - vn_syncer_add_to_worklist(vp, syncdelay > 0 ? next % syncdelay : 0); + vn_syncer_add_to_worklist(&vp->v_bufobj, + syncdelay > 0 ? next % syncdelay : 0); /* XXX - vn_syncer_add_to_worklist() also grabs and drops sync_mtx. */ mtx_lock(&sync_mtx); sync_vnode_count++; @@ -3355,6 +3359,7 @@ sync_fsync(ap) struct mount *mp = syncvp->v_mount; struct thread *td = ap->a_td; int error, asyncflag; + struct bufobj *bo; /* * We only need to do something if this is a lazy evaluation. @@ -3365,9 +3370,10 @@ sync_fsync(ap) /* * Move ourselves to the back of the sync list. */ - VI_LOCK(syncvp); - vn_syncer_add_to_worklist(syncvp, syncdelay); - VI_UNLOCK(syncvp); + bo = &syncvp->v_bufobj; + BO_LOCK(bo); + vn_syncer_add_to_worklist(bo, syncdelay); + BO_UNLOCK(bo); /* * Walk the list of vnodes pushing all that are dirty and @@ -3421,16 +3427,18 @@ sync_reclaim(ap) } */ *ap; { struct vnode *vp = ap->a_vp; + struct bufobj *bo; VI_LOCK(vp); + bo = &vp->v_bufobj; vp->v_mount->mnt_syncer = NULL; - if (vp->v_iflag & VI_ONWORKLST) { + if (bo->bo_flag & BO_ONWORKLST) { mtx_lock(&sync_mtx); - LIST_REMOVE(vp, v_synclist); + LIST_REMOVE(bo, bo_synclist); syncer_worklist_len--; sync_vnode_count--; mtx_unlock(&sync_mtx); - vp->v_iflag &= ~VI_ONWORKLST; + bo->bo_flag &= ~BO_ONWORKLST; } VI_UNLOCK(vp); diff --git a/sys/sys/buf.h b/sys/sys/buf.h index 6accac62855..9b1e55d93c5 100644 --- a/sys/sys/buf.h +++ b/sys/sys/buf.h @@ -48,6 +48,7 @@ struct buf; struct bufobj; struct mount; struct vnode; +struct uio; /* * To avoid including @@ -398,6 +399,7 @@ struct cluster_save { static __inline int bwrite(struct buf *bp) { + KASSERT(bp->b_bufobj != NULL, ("bwrite: no bufobj bp=%p", bp)); KASSERT(bp->b_bufobj->bo_ops != NULL, ("bwrite: no bo_ops bp=%p", bp)); KASSERT(bp->b_bufobj->bo_ops->bop_write != NULL, @@ -408,6 +410,7 @@ bwrite(struct buf *bp) static __inline void bstrategy(struct buf *bp) { + KASSERT(bp->b_bufobj != NULL, ("bwrite: no bufobj bp=%p", bp)); KASSERT(bp->b_bufobj->bo_ops != NULL, ("bwrite: no bo_ops bp=%p", bp)); KASSERT(bp->b_bufobj->bo_ops->bop_strategy != NULL, @@ -481,8 +484,6 @@ extern int bufpages; /* Number of memory pages in the buffer pool. */ extern struct buf *swbuf; /* Swap I/O buffer headers. */ extern int nswbuf; /* Number of swap I/O buffer headers. */ -struct uio; - caddr_t kern_vfs_bio_buffer_alloc(caddr_t v, long physmem_est); void bufinit(void); void bwillwrite(void); diff --git a/sys/sys/bufobj.h b/sys/sys/bufobj.h index 337d0cd37b8..0a2f915f7c7 100644 --- a/sys/sys/bufobj.h +++ b/sys/sys/bufobj.h @@ -85,8 +85,15 @@ struct bufobj { struct buf_ops *bo_ops; /* - Buffer operations */ int bo_bsize; /* - Block size for i/o */ struct vm_object *bo_object; /* v Place to store VM object */ + LIST_ENTRY(bufobj) bo_synclist; /* S dirty vnode list */ + void *bo_private; /* private pointer */ }; +/* + * XXX BO_ONWORKLST could be replaced with a check for NULL list elements + * in v_synclist. + */ +#define BO_ONWORKLST (1 << 0) /* On syncer work-list */ #define BO_WWAIT (1 << 1) /* Wait for output to complete */ #define BO_LOCK(bo) \ @@ -111,5 +118,3 @@ int bufobj_wwait(struct bufobj *bo, int slpflag, int timeo); #endif /* defined(_KERNEL) || defined(_KVM_VNODE) */ #endif /* _SYS_BUFOBJ_H_ */ - - diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 07a86d76bbe..d3054c69e98 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -130,7 +130,6 @@ struct vnode { } v_un; TAILQ_ENTRY(vnode) v_freelist; /* f vnode freelist */ TAILQ_ENTRY(vnode) v_nmntvnodes; /* m vnodes for mount point */ - LIST_ENTRY(vnode) v_synclist; /* S dirty vnode list */ enum vtype v_type; /* u vnode type */ const char *v_tag; /* u type of underlying data */ void *v_data; /* u private data for fs */ @@ -224,11 +223,6 @@ struct xvnode { #define VI_FREE 0x0100 /* This vnode is on the freelist */ #define VI_OBJDIRTY 0x0400 /* object might be dirty */ #define VI_DOINGINACT 0x0800 /* VOP_INACTIVE is in progress */ -/* - * XXX VI_ONWORKLST could be replaced with a check for NULL list elements - * in v_synclist. - */ -#define VI_ONWORKLST 0x0200 /* On syncer work-list */ #define VV_ROOT 0x0001 /* root of its filesystem */ #define VV_ISTTY 0x0002 /* vnode represents a tty */