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.
This commit is contained in:
Jeff Roberson 2002-07-06 08:59:52 +00:00
parent fe0f1bf4b1
commit 9a236af3ad
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=99489
3 changed files with 17 additions and 15 deletions

View File

@ -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"));

View File

@ -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;
}
}
/*

View File

@ -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. */