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:
parent
fe0f1bf4b1
commit
9a236af3ad
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=99489
@ -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"));
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user