When vnode bypass cannot be performed on the cdev file descriptor for

read/write/poll/ioctl, call standard vnode filedescriptor fop.  This
restores the special handling for terminals by calling the deadfs VOP,
instead of always returning ENXIO for destroyed devices or revoked
terminals.

Since destroyed (and not revoked) device would use devfs_specops VOP
vector, make dead_read/write/poll non-static and fill VOP table with
pointers to the functions, to instead of VOP_PANIC.

Noted and reviewed by:	bde
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
This commit is contained in:
kib 2014-10-15 13:16:51 +00:00
parent 66572524ce
commit 6b880aa521
3 changed files with 22 additions and 13 deletions

View File

@ -43,9 +43,6 @@
*/
static vop_lookup_t dead_lookup;
static vop_open_t dead_open;
static vop_poll_t dead_poll;
static vop_read_t dead_read;
static vop_write_t dead_write;
static vop_getwritemount_t dead_getwritemount;
static vop_rename_t dead_rename;
@ -130,7 +127,7 @@ dead_open(ap)
* Vnode op for read
*/
/* ARGSUSED */
static int
int
dead_read(ap)
struct vop_read_args /* {
struct vnode *a_vp;
@ -151,7 +148,7 @@ dead_read(ap)
* Vnode op for write
*/
/* ARGSUSED */
static int
int
dead_write(ap)
struct vop_write_args /* {
struct vnode *a_vp;
@ -163,7 +160,7 @@ dead_write(ap)
return (EIO);
}
static int
int
dead_poll(ap)
struct vop_poll_args *ap;
{

View File

@ -737,8 +737,10 @@ devfs_ioctl_f(struct file *fp, u_long com, void *data, struct ucred *cred, struc
fpop = td->td_fpop;
error = devfs_fp_check(fp, &dev, &dsw, &ref);
if (error)
if (error != 0) {
error = vnops.fo_ioctl(fp, com, data, cred, td);
return (error);
}
if (com == FIODTYPE) {
*(int *)data = dsw->d_flags & D_TYPEMASK;
@ -1152,8 +1154,10 @@ devfs_poll_f(struct file *fp, int events, struct ucred *cred, struct thread *td)
fpop = td->td_fpop;
error = devfs_fp_check(fp, &dev, &dsw, &ref);
if (error)
return (poll_no_poll(events));
if (error != 0) {
error = vnops.fo_poll(fp, events, cred, td);
return (error);
}
error = dsw->d_poll(dev, events, td);
td->td_fpop = fpop;
dev_relthread(dev, ref);
@ -1185,8 +1189,10 @@ devfs_read_f(struct file *fp, struct uio *uio, struct ucred *cred,
return (EINVAL);
fpop = td->td_fpop;
error = devfs_fp_check(fp, &dev, &dsw, &ref);
if (error)
if (error != 0) {
error = vnops.fo_read(fp, uio, cred, flags, td);
return (error);
}
resid = uio->uio_resid;
ioflag = fp->f_flag & (O_NONBLOCK | O_DIRECT);
if (ioflag & O_DIRECT)
@ -1660,8 +1666,10 @@ devfs_write_f(struct file *fp, struct uio *uio, struct ucred *cred,
return (EINVAL);
fpop = td->td_fpop;
error = devfs_fp_check(fp, &dev, &dsw, &ref);
if (error)
if (error != 0) {
error = vnops.fo_write(fp, uio, cred, flags, td);
return (error);
}
KASSERT(uio->uio_td == td, ("uio_td %p is not td %p", uio->uio_td, td));
ioflag = fp->f_flag & (O_NONBLOCK | O_DIRECT | O_FSYNC);
if (ioflag & O_DIRECT)
@ -1744,8 +1752,9 @@ static struct vop_vector devfs_specops = {
.vop_mknod = VOP_PANIC,
.vop_open = devfs_open,
.vop_pathconf = devfs_pathconf,
.vop_poll = dead_poll,
.vop_print = devfs_print,
.vop_read = VOP_PANIC,
.vop_read = dead_read,
.vop_readdir = VOP_PANIC,
.vop_readlink = VOP_PANIC,
.vop_reallocblks = VOP_PANIC,
@ -1761,7 +1770,7 @@ static struct vop_vector devfs_specops = {
.vop_strategy = VOP_PANIC,
.vop_symlink = VOP_PANIC,
.vop_vptocnp = devfs_vptocnp,
.vop_write = VOP_PANIC,
.vop_write = dead_write,
};
/*

View File

@ -758,6 +758,9 @@ int vop_enoent(struct vop_generic_args *ap);
int vop_enotty(struct vop_generic_args *ap);
int vop_null(struct vop_generic_args *ap);
int vop_panic(struct vop_generic_args *ap);
int dead_poll(struct vop_poll_args *ap);
int dead_read(struct vop_read_args *ap);
int dead_write(struct vop_write_args *ap);
/* These are called from within the actual VOPS. */
void vop_create_post(void *a, int rc);