diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 30dc7535814f..02b13cf3b9ae 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 @@ getnewbuf(int slpflag, int slptimeo, int size, int maxsize) 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 @@ getblk(struct vnode * vp, daddr_t blkno, int size, int slpflag, int slptimeo) 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 882fc391d557..d8e960a2ba10 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 0f6f579fd4b1..63532761f535 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. */