* Copyright (c) 1989 The Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* @(#)spec_vnops.c 7.7 (Berkeley) %G%
#include "../ufs/inode.h"
struct vnodeops blk_vnodeops
= {
* Trivial lookup routine that always fails.
* Open called to allow handler
* of special files to initialize and
* validate before actual IO.
register struct vnode
*vp
;
dev_t dev
= (dev_t
)vp
->v_rdev
;
register int maj
= major(dev
);
if ((u_int
)maj
>= nchrdev
)
return ((*cdevsw
[maj
].d_open
)(dev
, mode
, S_IFCHR
));
if ((u_int
)maj
>= nblkdev
)
return ((*bdevsw
[maj
].d_open
)(dev
, mode
, S_IFBLK
));
* Check access permissions for a block device.
blk_access(vp
, mode
, cred
)
return (iaccess(VTOI(vp
), mode
, cred
));
blk_read(vp
, uio
, offp
, ioflag
, cred
)
register struct vnode
*vp
;
if (vp
->v_type
== VBLK
&& vp
->v_data
)
error
= readblkvp(vp
, uio
, cred
, ioflag
);
*offp
+= count
- uio
->uio_resid
;
if (vp
->v_type
== VBLK
&& vp
->v_data
)
blk_write(vp
, uio
, offp
, ioflag
, cred
)
register struct vnode
*vp
;
if (vp
->v_type
== VBLK
&& vp
->v_data
)
error
= writeblkvp(vp
, uio
, cred
, ioflag
);
*offp
+= count
- uio
->uio_resid
;
if (vp
->v_type
== VBLK
&& vp
->v_data
)
* Device ioctl operation.
blk_ioctl(vp
, com
, data
, fflag
, cred
)
return ((*cdevsw
[major(dev
)].d_ioctl
)(dev
, com
, data
, fflag
));
return ((*bdevsw
[major(dev
)].d_ioctl
)(dev
, com
, data
, fflag
));
blk_select(vp
, which
, cred
)
return (*cdevsw
[major(dev
)].d_select
)(dev
, which
);
* Just call the device strategy routine
(*bdevsw
[major(bp
->b_dev
)].d_strategy
)(bp
);
register struct inode
*ip
= VTOI(vp
);
register struct inode
*ip
= VTOI(vp
);
blk_close(vp
, flag
, cred
)
register struct vnode
*vp
;
register struct inode
*ip
= VTOI(vp
);
if (vp
->v_count
> 1 && !(ip
->i_flag
& ILOCKED
))
ITIMES(ip
, &time
, &time
);
cfunc
= cdevsw
[major(dev
)].d_close
;
* 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.
* We don't want to really close the device if it is still
* in use. Since every use (buffer, inode, swap, cmap)
* holds a reference to the vnode, and because we ensure
* that there cannot be more than one vnode per device,
* we need only check that we are down to the last
* reference before closing.
cfunc
= bdevsw
[major(dev
)].d_close
;
panic("blk_close: not special");
/* XXX what is this doing below the vnode op call */
if (setjmp(&u
.u_qsave
)) {
* If device close routine is interrupted,
* must return so closef can clean up.
error
= (*cfunc
)(dev
, flag
, mode
);
* Block device bad operation
panic("blk_badop called");
* Block device null operation