This patch removes the VOP_BWRITE() vector.

VOP_BWRITE() was a hack which made it possible for NFS client
side to use struct buf with non-bio backing.

This patch takes a more general approach and adds a bp->b_op
vector where more methods can be added.

The success of this patch depends on bp->b_op being initialized
all relevant places for some value of "relevant" which is not
easy to determine.  For now the buffers have grown a b_magic
element which will make such issues a tiny bit easier to debug.
This commit is contained in:
Poul-Henning Kamp 2001-04-17 08:56:39 +00:00
parent 4b7369ea64
commit f84e29a06c
19 changed files with 74 additions and 66 deletions

View File

@ -137,7 +137,6 @@ struct vnodeopv_entry_desc coda_vnodeop_entries[] = {
{ &vop_islocked_desc, coda_islocked }, /* islocked */
{ &vop_pathconf_desc, coda_vop_error }, /* pathconf */
{ &vop_advlock_desc, coda_vop_nop }, /* advlock */
{ &vop_bwrite_desc, coda_vop_error }, /* bwrite */
{ &vop_lease_desc, coda_vop_nop }, /* lease */
{ &vop_poll_desc, (vop_t *) vop_stdpoll },
{ &vop_getpages_desc, coda_fbsd_getpages }, /* pager intf.*/

View File

@ -137,7 +137,6 @@ struct vnodeopv_entry_desc coda_vnodeop_entries[] = {
{ &vop_islocked_desc, coda_islocked }, /* islocked */
{ &vop_pathconf_desc, coda_vop_error }, /* pathconf */
{ &vop_advlock_desc, coda_vop_nop }, /* advlock */
{ &vop_bwrite_desc, coda_vop_error }, /* bwrite */
{ &vop_lease_desc, coda_vop_nop }, /* lease */
{ &vop_poll_desc, (vop_t *) vop_stdpoll },
{ &vop_getpages_desc, coda_fbsd_getpages }, /* pager intf.*/

View File

@ -1359,7 +1359,6 @@ struct vnodeopv_entry_desc hpfs_vnodeop_entries[] = {
{ &vop_getpages_desc, (vop_t *) hpfs_getpages },
{ &vop_putpages_desc, (vop_t *) hpfs_putpages },
{ &vop_strategy_desc, (vop_t *)hpfs_strategy },
{ &vop_bwrite_desc, (vop_t *)vop_stdbwrite },
{ &vop_read_desc, (vop_t *)hpfs_read },
{ &vop_write_desc, (vop_t *)hpfs_write },
{ &vop_ioctl_desc, (vop_t *)hpfs_ioctl },

View File

@ -875,7 +875,6 @@ struct vnodeopv_entry_desc ntfs_vnodeop_entries[] = {
{ &vop_getpages_desc, (vop_t *) ntfs_getpages },
{ &vop_putpages_desc, (vop_t *) ntfs_putpages },
{ &vop_strategy_desc, (vop_t *)ntfs_strategy },
{ &vop_bwrite_desc, (vop_t *)vop_stdbwrite },
{ &vop_read_desc, (vop_t *)ntfs_read },
{ &vop_write_desc, (vop_t *)ntfs_write },

View File

@ -58,6 +58,11 @@ static MALLOC_DEFINE(M_BIOBUF, "BIO buffer", "BIO buffer");
struct bio_ops bioops; /* I/O operation notification */
struct buf_ops buf_ops_bio = {
"buf_ops_bio",
bwrite
};
struct buf *buf; /* buffer header pool */
struct swqueue bswlist;
struct mtx buftimelock; /* Interlock on setting prio and timo */
@ -1685,6 +1690,8 @@ getnewbuf(int slpflag, int slptimeo, int size, int maxsize)
bp->b_bcount = 0;
bp->b_npages = 0;
bp->b_dirtyoff = bp->b_dirtyend = 0;
bp->b_magic = B_MAGIC_BIO;
bp->b_op = &buf_ops_bio;
LIST_INIT(&bp->b_dep);
@ -2088,7 +2095,7 @@ vfs_setdirty(struct buf *bp)
* case it is returned with B_INVAL clear and B_CACHE set based on the
* backing VM.
*
* getblk() also forces a VOP_BWRITE() for any B_DELWRI buffer whos
* getblk() also forces a BUF_WRITE() for any B_DELWRI buffer whos
* B_CACHE bit is clear.
*
* What this means, basically, is that the caller should use B_CACHE to

View File

@ -755,6 +755,8 @@ cluster_wbuild(vp, size, start_lbn, len)
*/
TAILQ_INIT(&bp->b_cluster.cluster_head);
bp->b_bcount = 0;
bp->b_magic = tbp->b_magic;
bp->b_op = tbp->b_op;
bp->b_bufsize = 0;
bp->b_npages = 0;
if (tbp->b_wcred != NOCRED) {

View File

@ -80,7 +80,6 @@ vop_t **default_vnodeop_p;
static struct vnodeopv_entry_desc default_vnodeop_entries[] = {
{ &vop_default_desc, (vop_t *) vop_eopnotsupp },
{ &vop_advlock_desc, (vop_t *) vop_einval },
{ &vop_bwrite_desc, (vop_t *) vop_stdbwrite },
{ &vop_close_desc, (vop_t *) vop_null },
{ &vop_createvobject_desc, (vop_t *) vop_stdcreatevobject },
{ &vop_destroyvobject_desc, (vop_t *) vop_stddestroyvobject },
@ -333,13 +332,6 @@ vop_stdpoll(ap)
return (vn_pollrecord(ap->a_vp, ap->a_p, ap->a_events));
}
int
vop_stdbwrite(ap)
struct vop_bwrite_args *ap;
{
return (bwrite(ap->a_bp));
}
/*
* Stubs to use when there is no locking to be done on the underlying object.
* A minimal shared lock is necessary to ensure that the underlying object

View File

@ -748,7 +748,7 @@ vinvalbuf(vp, flags, cred, p, slpflag, slptimeo)
* believe there is a slight chance that a delayed
* write will occur while sleeping just above, so
* check for it. Note that vfs_bio_awrite expects
* buffers to reside on a queue, while VOP_BWRITE and
* buffers to reside on a queue, while BUF_WRITE and
* brelse do not.
*/
if (((bp->b_flags & (B_DELWRI | B_INVAL)) == B_DELWRI) &&

View File

@ -748,7 +748,7 @@ vinvalbuf(vp, flags, cred, p, slpflag, slptimeo)
* believe there is a slight chance that a delayed
* write will occur while sleeping just above, so
* check for it. Note that vfs_bio_awrite expects
* buffers to reside on a queue, while VOP_BWRITE and
* buffers to reside on a queue, while BUF_WRITE and
* brelse do not.
*/
if (((bp->b_flags & (B_DELWRI | B_INVAL)) == B_DELWRI) &&

View File

@ -483,14 +483,6 @@ vop_freeblks {
IN daddr_t length;
};
#
#% bwrite vp L L L
#
vop_bwrite {
IN struct vnode *vp;
IN struct buf *bp;
};
#
#% getacl vp L L L
#

View File

@ -63,6 +63,23 @@
#include <nfs/nqnfs.h>
#include <nfs/nfsnode.h>
/*
* Just call nfs_writebp() with the force argument set to 1.
*
* NOTE: B_DONE may or may not be set in a_bp on call.
*/
static int
nfs_bwrite(struct buf *bp)
{
return (nfs_writebp(bp, 1, curproc));
}
struct buf_ops buf_ops_nfs = {
"buf_ops_nfs",
nfs_bwrite
};
static struct buf *nfs_getcacheblk __P((struct vnode *vp, daddr_t bn, int size,
struct proc *p));
@ -890,6 +907,8 @@ nfs_write(ap)
bcount += n;
allocbuf(bp, bcount);
bp->b_flags |= save;
bp->b_magic = B_MAGIC_NFS;
bp->b_op = &buf_ops_nfs;
}
} else {
/*

View File

@ -129,7 +129,6 @@ static int nfsspec_access __P((struct vop_access_args *));
static int nfs_readlink __P((struct vop_readlink_args *));
static int nfs_print __P((struct vop_print_args *));
static int nfs_advlock __P((struct vop_advlock_args *));
static int nfs_bwrite __P((struct vop_bwrite_args *));
/*
* Global vfs data structures for nfs
*/
@ -139,7 +138,6 @@ static struct vnodeopv_entry_desc nfsv2_vnodeop_entries[] = {
{ &vop_access_desc, (vop_t *) nfs_access },
{ &vop_advlock_desc, (vop_t *) nfs_advlock },
{ &vop_bmap_desc, (vop_t *) nfs_bmap },
{ &vop_bwrite_desc, (vop_t *) nfs_bwrite },
{ &vop_close_desc, (vop_t *) nfs_close },
{ &vop_create_desc, (vop_t *) nfs_create },
{ &vop_fsync_desc, (vop_t *) nfs_fsync },
@ -3090,23 +3088,10 @@ nfs_print(ap)
}
/*
* Just call nfs_writebp() with the force argument set to 1.
*
* NOTE: B_DONE may or may not be set in a_bp on call.
*/
static int
nfs_bwrite(ap)
struct vop_bwrite_args /* {
struct vnode *a_bp;
} */ *ap;
{
return (nfs_writebp(ap->a_bp, 1, curproc));
}
/*
* This is a clone of vn_bwrite(), except that B_WRITEINPROG isn't set unless
* the force flag is one and it also handles the B_NEEDCOMMIT flag. We set
* B_CACHE if this is a VMIO buffer.
* This is the "real" nfs::bwrite(struct buf*).
* B_WRITEINPROG isn't set unless the force flag is one and it
* handles the B_NEEDCOMMIT flag.
* We set B_CACHE if this is a VMIO buffer.
*/
int
nfs_writebp(bp, force, procp)

View File

@ -63,6 +63,23 @@
#include <nfs/nqnfs.h>
#include <nfs/nfsnode.h>
/*
* Just call nfs_writebp() with the force argument set to 1.
*
* NOTE: B_DONE may or may not be set in a_bp on call.
*/
static int
nfs_bwrite(struct buf *bp)
{
return (nfs_writebp(bp, 1, curproc));
}
struct buf_ops buf_ops_nfs = {
"buf_ops_nfs",
nfs_bwrite
};
static struct buf *nfs_getcacheblk __P((struct vnode *vp, daddr_t bn, int size,
struct proc *p));
@ -890,6 +907,8 @@ nfs_write(ap)
bcount += n;
allocbuf(bp, bcount);
bp->b_flags |= save;
bp->b_magic = B_MAGIC_NFS;
bp->b_op = &buf_ops_nfs;
}
} else {
/*

View File

@ -129,7 +129,6 @@ static int nfsspec_access __P((struct vop_access_args *));
static int nfs_readlink __P((struct vop_readlink_args *));
static int nfs_print __P((struct vop_print_args *));
static int nfs_advlock __P((struct vop_advlock_args *));
static int nfs_bwrite __P((struct vop_bwrite_args *));
/*
* Global vfs data structures for nfs
*/
@ -139,7 +138,6 @@ static struct vnodeopv_entry_desc nfsv2_vnodeop_entries[] = {
{ &vop_access_desc, (vop_t *) nfs_access },
{ &vop_advlock_desc, (vop_t *) nfs_advlock },
{ &vop_bmap_desc, (vop_t *) nfs_bmap },
{ &vop_bwrite_desc, (vop_t *) nfs_bwrite },
{ &vop_close_desc, (vop_t *) nfs_close },
{ &vop_create_desc, (vop_t *) nfs_create },
{ &vop_fsync_desc, (vop_t *) nfs_fsync },
@ -3090,23 +3088,10 @@ nfs_print(ap)
}
/*
* Just call nfs_writebp() with the force argument set to 1.
*
* NOTE: B_DONE may or may not be set in a_bp on call.
*/
static int
nfs_bwrite(ap)
struct vop_bwrite_args /* {
struct vnode *a_bp;
} */ *ap;
{
return (nfs_writebp(ap->a_bp, 1, curproc));
}
/*
* This is a clone of vn_bwrite(), except that B_WRITEINPROG isn't set unless
* the force flag is one and it also handles the B_NEEDCOMMIT flag. We set
* B_CACHE if this is a VMIO buffer.
* This is the "real" nfs::bwrite(struct buf*).
* B_WRITEINPROG isn't set unless the force flag is one and it
* handles the B_NEEDCOMMIT flag.
* We set B_CACHE if this is a VMIO buffer.
*/
int
nfs_writebp(bp, force, procp)

View File

@ -875,7 +875,6 @@ struct vnodeopv_entry_desc ntfs_vnodeop_entries[] = {
{ &vop_getpages_desc, (vop_t *) ntfs_getpages },
{ &vop_putpages_desc, (vop_t *) ntfs_putpages },
{ &vop_strategy_desc, (vop_t *)ntfs_strategy },
{ &vop_bwrite_desc, (vop_t *)vop_stdbwrite },
{ &vop_read_desc, (vop_t *)ntfs_read },
{ &vop_write_desc, (vop_t *)ntfs_write },

View File

@ -68,6 +68,13 @@ extern struct bio_ops {
int (*io_countdeps) __P((struct buf *, int));
} bioops;
struct buf_ops {
char *bop_name;
int (*bop_write) __P((struct buf *));
};
extern struct buf_ops buf_ops_bio;
/*
* The buffer header describes an I/O operation in the kernel.
*
@ -99,6 +106,10 @@ struct buf {
#define b_ioflags b_io.bio_flags
#define b_pblkno b_io.bio_pblkno
#define b_resid b_io.bio_resid
struct buf_ops *b_op;
unsigned b_magic;
#define B_MAGIC_BIO 0x10b10b10
#define B_MAGIC_NFS 0x67238234
void (*b_iodone) __P((struct buf *));
off_t b_offset; /* Offset into file. */
LIST_ENTRY(buf) b_hash; /* Hash chain. */
@ -410,7 +421,9 @@ bufq_first(struct buf_queue_head *head)
return (TAILQ_FIRST(&head->queue));
}
#define BUF_WRITE(bp) VOP_BWRITE((bp)->b_vp, (bp))
#define BUF_WRITE(bp) \
(bp)->b_op->bop_write(bp)
#define BUF_STRATEGY(bp) VOP_STRATEGY((bp)->b_vp, (bp))
static __inline void

View File

@ -540,7 +540,6 @@ struct ucred;
struct uio;
struct vattr;
struct vnode;
struct vop_bwrite_args;
extern int (*lease_check_hook) __P((struct vop_lease_args *));
@ -620,7 +619,6 @@ int vfs_object_create __P((struct vnode *vp, struct proc *p,
void vfs_timestamp __P((struct timespec *));
void vfs_write_resume __P((struct mount *mp));
void vfs_write_suspend __P((struct mount *mp));
int vop_stdbwrite __P((struct vop_bwrite_args *ap));
int vop_stdgetwritemount __P((struct vop_getwritemount_args *));
int vop_stdinactive __P((struct vop_inactive_args *));
int vop_stdislocked __P((struct vop_islocked_args *));

View File

@ -70,7 +70,6 @@ vop_t **mfs_vnodeop_p;
static struct vnodeopv_entry_desc mfs_vnodeop_entries[] = {
{ &vop_default_desc, (vop_t *) mfs_badop },
{ &vop_bmap_desc, (vop_t *) mfs_bmap },
{ &vop_bwrite_desc, (vop_t *) vop_defaultop },
{ &vop_close_desc, (vop_t *) mfs_close },
{ &vop_createvobject_desc, (vop_t *) vop_stdcreatevobject },
{ &vop_destroyvobject_desc, (vop_t *) vop_stddestroyvobject },

View File

@ -355,6 +355,8 @@ initpbuf(struct buf *bp)
bp->b_ioflags = 0;
bp->b_iodone = NULL;
bp->b_error = 0;
bp->b_magic = B_MAGIC_BIO;
bp->b_op = &buf_ops_bio;
BUF_LOCK(bp, LK_EXCLUSIVE);
}