diff options
author | jeff <jeff@FreeBSD.org> | 2002-07-06 08:59:52 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2002-07-06 08:59:52 +0000 |
commit | 0dd7645264ca202a719af56ac11adbf83a664a12 (patch) | |
tree | 5783b378b0b909b42f518f718b5804f02cf06503 /sys | |
parent | 4037477f94b23f8b1d083009977249d2ac2c773d (diff) | |
download | FreeBSD-src-0dd7645264ca202a719af56ac11adbf83a664a12.zip FreeBSD-src-0dd7645264ca202a719af56ac11adbf83a664a12.tar.gz |
Fixup uses of GETVOBJECT.
- Cache a pointer to the vnode's object in the buf.
- Hold a reference to that object in addition to the vnode's reference just
to be consistent.
- Cleanup code that got the object indirectly through the vp and VOP calls.
This fixes at least one case where we were calling GETVOBJECT without a lock.
It also avoids an expensive layered call at the cost of another pointer in
struct buf.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/vfs_bio.c | 25 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 4 | ||||
-rw-r--r-- | sys/sys/buf.h | 3 |
3 files changed, 17 insertions, 15 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 30dc753..02b13cf 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -1206,6 +1206,7 @@ brelse(struct buf * bp) struct vnode *vp; vp = bp->b_vp; + obj = bp->b_object; /* * Get the base offset and length of the buffer. Note that @@ -1233,7 +1234,6 @@ brelse(struct buf * bp) * now. */ if (m == bogus_page) { - VOP_GETVOBJECT(vp, &obj); poff = OFF_TO_IDX(bp->b_offset); had_bogus = 1; @@ -1803,6 +1803,7 @@ restart: bp->b_dirtyoff = bp->b_dirtyend = 0; bp->b_magic = B_MAGIC_BIO; bp->b_op = &buf_ops_bio; + bp->b_object = NULL; LIST_INIT(&bp->b_dep); @@ -2423,8 +2424,11 @@ loop: if (vp->v_type != VREG) printf("getblk: vmioing file type %d???\n", vp->v_type); #endif + VOP_GETVOBJECT(vp, &bp->b_object); + vm_object_reference(bp->b_object); } else { bp->b_flags &= ~B_VMIO; + bp->b_object = NULL; } allocbuf(bp, size); @@ -2628,7 +2632,7 @@ allocbuf(struct buf *bp, int size) */ vp = bp->b_vp; - VOP_GETVOBJECT(vp, &obj); + obj = bp->b_object; while (bp->b_npages < desiredpages) { vm_page_t m; @@ -2813,7 +2817,7 @@ bufdonebio(struct bio *bp) void bufdone(struct buf *bp) { - int s, error; + int s; void (*biodone)(struct buf *); GIANT_REQUIRED; @@ -2855,17 +2859,13 @@ bufdone(struct buf *bp) int iosize; struct vnode *vp = bp->b_vp; - error = VOP_GETVOBJECT(vp, &obj); + obj = bp->b_object; #if defined(VFS_BIO_DEBUG) if (vp->v_usecount == 0) { panic("biodone: zero vnode ref count"); } - if (error) { - panic("biodone: missing VM object"); - } - if ((vp->v_flag & VOBJBUF) == 0) { panic("biodone: vnode is not setup for merged cache"); } @@ -2875,9 +2875,6 @@ bufdone(struct buf *bp) KASSERT(bp->b_offset != NOOFFSET, ("biodone: no buffer offset")); - if (error) { - panic("biodone: no object"); - } #if defined(VFS_BIO_DEBUG) if (obj->paging_in_progress < bp->b_npages) { printf("biodone: paging in progress(%d) < bp->b_npages(%d)\n", @@ -2999,10 +2996,9 @@ vfs_unbusy_pages(struct buf * bp) runningbufwakeup(bp); if (bp->b_flags & B_VMIO) { - struct vnode *vp = bp->b_vp; vm_object_t obj; - VOP_GETVOBJECT(vp, &obj); + obj = bp->b_object; for (i = 0; i < bp->b_npages; i++) { vm_page_t m = bp->b_pages[i]; @@ -3081,11 +3077,10 @@ vfs_busy_pages(struct buf * bp, int clear_modify) GIANT_REQUIRED; if (bp->b_flags & B_VMIO) { - struct vnode *vp = bp->b_vp; vm_object_t obj; vm_ooffset_t foff; - VOP_GETVOBJECT(vp, &obj); + obj = bp->b_object; foff = bp->b_offset; KASSERT(bp->b_offset != NOOFFSET, ("vfs_busy_pages: no buffer offset")); diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 882fc39..d8e960a 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1139,6 +1139,10 @@ brelvp(bp) splx(s); bp->b_vp = (struct vnode *) 0; vdrop(vp); + if (bp->b_object) { + vm_object_deallocate(bp->b_object); + bp->b_object = NULL; + } } /* diff --git a/sys/sys/buf.h b/sys/sys/buf.h index 0f6f579..6353276 100644 --- a/sys/sys/buf.h +++ b/sys/sys/buf.h @@ -76,6 +76,8 @@ struct buf_ops { extern struct buf_ops buf_ops_bio; +struct vm_object; + /* * The buffer header describes an I/O operation in the kernel. * @@ -128,6 +130,7 @@ struct buf { int b_kvasize; /* size of kva for buffer */ daddr_t b_lblkno; /* Logical block number. */ struct vnode *b_vp; /* Device vnode. */ + struct vm_object *b_object; /* Object for vp */ int b_dirtyoff; /* Offset in buffer of dirty region. */ int b_dirtyend; /* Offset of end of dirty region. */ struct ucred *b_rcred; /* Read credentials reference. */ |