Files
Arquivotheca.SunOS-4.1.4/sys/old/bdev_vnodeops.c
seta75D ff309bfe1c Init
2021-10-11 18:37:13 -03:00

240 lines
4.1 KiB
C

#ifndef lint
static char sccsid[] = "@(#)bdev_vnodeops.c 1.1 94/10/31";
#endif
/*
* Copyright (c) 1986 by Sun Microsystems, Inc.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/user.h>
#include <sys/conf.h>
#include <sys/buf.h>
#include <sys/vfs.h>
#include <sys/vnode.h>
#include <sys/bootconf.h>
/*
* Convert a block dev into a vnode pointer suitable for bio.
*/
struct dev_vnode {
struct vnode dv_vnode;
struct dev_vnode *dv_link;
} *dev_vnode_headp;
bdev_badop()
{
panic("bdev_badop");
}
/*ARGSUSED*/
int
bdev_open(vpp, flag, cred)
struct vnode **vpp;
int flag;
struct ucred *cred;
{
return ((*bdevsw[major((*vpp)->v_rdev)].d_open)((*vpp)->v_rdev, flag));
}
/*ARGSUSED*/
int
bdev_close(vp, flag, cred)
struct vnode *vp;
int flag;
struct ucred *cred;
{
/*
* On last close of a block device (that isn't mounted)
* we must invalidate any in core blocks, so that
* we can, for instance, change floppy disks.
*/
bflush(vp);
binval(vp);
return ((*bdevsw[major(vp->v_rdev)].d_close)(vp->v_rdev, flag));
}
/*
* For now, the only value we actually return is size.
*/
/*ARGSUSED*/
int
bdev_getattr(vp, vap, cred)
struct vnode *vp;
register struct vattr *vap;
struct ucred *cred;
{
int (*size)();
bzero((caddr_t) vap, sizeof (struct vattr));
size = bdevsw[major(vp->v_rdev)].d_psize;
if (size) {
vap->va_size = (*size)(vp->v_rdev) * DEV_BSIZE;
}
return (0);
}
/*ARGSUSED*/
int
bdev_inactive(vp)
struct vnode *vp;
{
/* could free the vnode here */
return (0);
}
int
bdev_strategy(bp)
struct buf *bp;
{
(*bdevsw[major(bp->b_vp->v_rdev)].d_strategy)(bp);
return (0);
}
int
bdev_dump(vp, addr, bn, count)
struct vnode *vp;
caddr_t addr;
int bn;
int count;
{
return ((*bdevsw[major(vp->v_rdev)].d_dump)
(vp->v_rdev, addr, bn, count));
}
struct vnodeops dev_vnode_ops = {
bdev_open,
bdev_close,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_getattr,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_inactive,
bdev_badop,
bdev_strategy,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_dump,
};
/*
* Convert a block device into a special purpose vnode for bio
*/
struct vnode *
bdevvp(dev)
dev_t dev;
{
register struct dev_vnode *dvp;
register struct dev_vnode *endvp;
endvp = (struct dev_vnode *)0;
for (dvp = dev_vnode_headp; dvp; dvp = dvp->dv_link) {
if (dvp->dv_vnode.v_rdev == dev) {
VN_HOLD(&dvp->dv_vnode);
return (&dvp->dv_vnode);
}
endvp = dvp;
}
dvp = (struct dev_vnode *)
kmem_alloc((u_int)sizeof (struct dev_vnode));
bzero((caddr_t)dvp, sizeof (struct dev_vnode));
dvp->dv_vnode.v_count = 1;
dvp->dv_vnode.v_op = &dev_vnode_ops;
dvp->dv_vnode.v_rdev = dev;
if (endvp != (struct dev_vnode *)0) {
endvp->dv_link = dvp;
} else {
dev_vnode_headp = dvp;
}
return (&dvp->dv_vnode);
}
/* ARGSUSED */
int
bdev_mountroot(vfsp, vpp, name)
struct vfs *vfsp;
struct vnode **vpp;
char *name;
{
return (EINVAL);
}
/*ARGSUSED*/
int
bdev_swapvp(vfsp, vpp, name)
struct vfs *vfsp;
struct vnode **vpp;
char *name;
{
extern char *strcpy();
extern dev_t getblockdev();
if (*name == '\0') {
/*
* No swap name specified, use root dev partition "b"
* if it is a block device, otherwise fail.
* XXX should look through device list or something here
* if root is not local.
*/
if (rootvp->v_op == &dev_vnode_ops) {
*vpp = bdevvp(makedev(major(rootvp->v_rdev), 1));
(void) strcpy(name, rootfs.bo_name);
name[3] = 'b';
return (0);
} else {
dev_t dev;
if (dev = getblockdev("swap", name)) {
*vpp = bdevvp(makedev(major(dev), 1));
name[3] = 'b';
return (0);
}
return (ENODEV);
}
} else {
dev_t dev;
if (dev = getblockdev("swap", name)) {
*vpp = bdevvp(dev);
return (0);
}
return (ENODEV);
}
}
struct vfsops bdev_vfsops = {
bdev_badop, /* mount */
bdev_badop, /* unmount */
bdev_badop, /* root */
bdev_badop, /* statfs */
bdev_badop, /* sync */
bdev_badop, /* vget */
bdev_mountroot, /* mountroot */
bdev_swapvp, /* swapvp */
};