1 /* 2 * Copyright (c) 1990, 1993, 1995 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)fifo_vnops.c 8.10 (Berkeley) 5/27/95 34 * $FreeBSD: src/sys/miscfs/fifofs/fifo_vnops.c,v 1.45.2.4 2003/04/22 10:11:24 bde Exp $ 35 * $DragonFly: src/sys/vfs/fifofs/fifo_vnops.c,v 1.35 2006/12/23 00:41:29 swildner Exp $ 36 */ 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/unistd.h> 41 #include <sys/kernel.h> 42 #include <sys/lock.h> 43 #include <sys/malloc.h> 44 #include <sys/thread2.h> 45 #include <sys/vnode.h> 46 #include <sys/socket.h> 47 #include <sys/socketvar.h> 48 #include <sys/filio.h> 49 #include <sys/fcntl.h> 50 #include <sys/file.h> 51 #include <sys/event.h> 52 #include <sys/poll.h> 53 #include <sys/un.h> 54 55 #include <sys/thread2.h> 56 57 #include "fifo.h" 58 59 /* 60 * This structure is associated with the FIFO vnode and stores 61 * the state associated with the FIFO. 62 */ 63 struct fifoinfo { 64 struct socket *fi_readsock; 65 struct socket *fi_writesock; 66 long fi_readers; 67 long fi_writers; 68 }; 69 70 static int fifo_badop (void); 71 static int fifo_print (struct vop_print_args *); 72 static int fifo_lookup (struct vop_old_lookup_args *); 73 static int fifo_open (struct vop_open_args *); 74 static int fifo_close (struct vop_close_args *); 75 static int fifo_read (struct vop_read_args *); 76 static int fifo_write (struct vop_write_args *); 77 static int fifo_ioctl (struct vop_ioctl_args *); 78 static int fifo_poll (struct vop_poll_args *); 79 static int fifo_kqfilter (struct vop_kqfilter_args *); 80 static int fifo_inactive (struct vop_inactive_args *); 81 static int fifo_bmap (struct vop_bmap_args *); 82 static int fifo_pathconf (struct vop_pathconf_args *); 83 static int fifo_advlock (struct vop_advlock_args *); 84 85 static void filt_fifordetach(struct knote *kn); 86 static int filt_fiforead(struct knote *kn, long hint); 87 static void filt_fifowdetach(struct knote *kn); 88 static int filt_fifowrite(struct knote *kn, long hint); 89 90 static struct filterops fiforead_filtops = 91 { 1, NULL, filt_fifordetach, filt_fiforead }; 92 static struct filterops fifowrite_filtops = 93 { 1, NULL, filt_fifowdetach, filt_fifowrite }; 94 95 struct vop_ops fifo_vnode_vops = { 96 .vop_default = vop_defaultop, 97 .vop_access = (void *)vop_ebadf, 98 .vop_advlock = fifo_advlock, 99 .vop_bmap = fifo_bmap, 100 .vop_close = fifo_close, 101 .vop_old_create = (void *)fifo_badop, 102 .vop_getattr = (void *)vop_ebadf, 103 .vop_inactive = fifo_inactive, 104 .vop_ioctl = fifo_ioctl, 105 .vop_kqfilter = fifo_kqfilter, 106 .vop_old_link = (void *)fifo_badop, 107 .vop_old_lookup = fifo_lookup, 108 .vop_old_mkdir = (void *)fifo_badop, 109 .vop_old_mknod = (void *)fifo_badop, 110 .vop_open = fifo_open, 111 .vop_pathconf = fifo_pathconf, 112 .vop_poll = fifo_poll, 113 .vop_print = fifo_print, 114 .vop_read = fifo_read, 115 .vop_readdir = (void *)fifo_badop, 116 .vop_readlink = (void *)fifo_badop, 117 .vop_reallocblks = (void *)fifo_badop, 118 .vop_reclaim = (void *)vop_null, 119 .vop_old_remove = (void *)fifo_badop, 120 .vop_old_rename = (void *)fifo_badop, 121 .vop_old_rmdir = (void *)fifo_badop, 122 .vop_setattr = (void *)vop_ebadf, 123 .vop_old_symlink = (void *)fifo_badop, 124 .vop_write = fifo_write 125 }; 126 127 VNODEOP_SET(fifo_vnode_vops); 128 129 static MALLOC_DEFINE(M_FIFOINFO, "Fifo info", "Fifo info entries"); 130 131 /* 132 * fifo_vnoperate() 133 */ 134 int 135 fifo_vnoperate(struct vop_generic_args *ap) 136 { 137 return (VOCALL(&fifo_vnode_vops, ap)); 138 } 139 140 /* 141 * Trivial lookup routine that always fails. 142 * 143 * fifo_lookup(struct vnode *a_dvp, struct vnode **a_vpp, 144 * struct componentname *a_cnp) 145 */ 146 /* ARGSUSED */ 147 static int 148 fifo_lookup(struct vop_old_lookup_args *ap) 149 { 150 *ap->a_vpp = NULL; 151 return (ENOTDIR); 152 } 153 154 /* 155 * Open called to set up a new instance of a fifo or 156 * to find an active instance of a fifo. 157 * 158 * fifo_open(struct vnode *a_vp, int a_mode, struct ucred *a_cred, 159 * struct thread *a_td) 160 */ 161 /* ARGSUSED */ 162 static int 163 fifo_open(struct vop_open_args *ap) 164 { 165 struct thread *td = curthread; 166 struct vnode *vp = ap->a_vp; 167 struct fifoinfo *fip; 168 struct socket *rso, *wso; 169 int error; 170 171 if ((fip = vp->v_fifoinfo) == NULL) { 172 MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_FIFOINFO, M_WAITOK); 173 vp->v_fifoinfo = fip; 174 error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, td); 175 if (error) { 176 kfree(fip, M_FIFOINFO); 177 vp->v_fifoinfo = NULL; 178 return (error); 179 } 180 fip->fi_readsock = rso; 181 error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, td); 182 if (error) { 183 soclose(rso, FNONBLOCK); 184 kfree(fip, M_FIFOINFO); 185 vp->v_fifoinfo = NULL; 186 return (error); 187 } 188 fip->fi_writesock = wso; 189 error = unp_connect2(wso, rso); 190 if (error) { 191 soclose(wso, FNONBLOCK); 192 soclose(rso, FNONBLOCK); 193 kfree(fip, M_FIFOINFO); 194 vp->v_fifoinfo = NULL; 195 return (error); 196 } 197 fip->fi_readers = fip->fi_writers = 0; 198 wso->so_snd.sb_lowat = PIPE_BUF; 199 rso->so_state |= SS_CANTRCVMORE; 200 } 201 if (ap->a_mode & FREAD) { 202 fip->fi_readers++; 203 if (fip->fi_readers == 1) { 204 fip->fi_writesock->so_state &= ~SS_CANTSENDMORE; 205 if (fip->fi_writers > 0) { 206 wakeup((caddr_t)&fip->fi_writers); 207 sowwakeup(fip->fi_writesock); 208 } 209 } 210 } 211 if (ap->a_mode & FWRITE) { 212 fip->fi_writers++; 213 if (fip->fi_writers == 1) { 214 fip->fi_readsock->so_state &= ~SS_CANTRCVMORE; 215 if (fip->fi_readers > 0) { 216 wakeup((caddr_t)&fip->fi_readers); 217 sorwakeup(fip->fi_writesock); 218 } 219 } 220 } 221 if ((ap->a_mode & FREAD) && (ap->a_mode & O_NONBLOCK) == 0) { 222 if (fip->fi_writers == 0) { 223 vn_unlock(vp); 224 error = tsleep((caddr_t)&fip->fi_readers, 225 PCATCH, "fifoor", 0); 226 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 227 if (error) 228 goto bad; 229 /* 230 * We must have got woken up because we had a writer. 231 * That (and not still having one) is the condition 232 * that we must wait for. 233 */ 234 } 235 } 236 if (ap->a_mode & FWRITE) { 237 if (ap->a_mode & O_NONBLOCK) { 238 if (fip->fi_readers == 0) { 239 error = ENXIO; 240 goto bad; 241 } 242 } else { 243 if (fip->fi_readers == 0) { 244 vn_unlock(vp); 245 error = tsleep((caddr_t)&fip->fi_writers, 246 PCATCH, "fifoow", 0); 247 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 248 if (error) 249 goto bad; 250 /* 251 * We must have got woken up because we had 252 * a reader. That (and not still having one) 253 * is the condition that we must wait for. 254 */ 255 } 256 } 257 } 258 return (vop_stdopen(ap)); 259 bad: 260 vop_stdopen(ap); /* bump opencount/writecount as appropriate */ 261 VOP_CLOSE(vp, ap->a_mode); 262 return (error); 263 } 264 265 /* 266 * Vnode op for read 267 * 268 * fifo_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag, 269 * struct ucred *a_cred) 270 */ 271 /* ARGSUSED */ 272 static int 273 fifo_read(struct vop_read_args *ap) 274 { 275 struct uio *uio = ap->a_uio; 276 struct socket *rso = ap->a_vp->v_fifoinfo->fi_readsock; 277 int error, startresid; 278 int flags; 279 280 #ifdef DIAGNOSTIC 281 if (uio->uio_rw != UIO_READ) 282 panic("fifo_read mode"); 283 #endif 284 if (uio->uio_resid == 0) 285 return (0); 286 if (ap->a_ioflag & IO_NDELAY) 287 flags = MSG_FNONBLOCKING; 288 else 289 flags = 0; 290 startresid = uio->uio_resid; 291 vn_unlock(ap->a_vp); 292 error = soreceive(rso, (struct sockaddr **)0, uio, (struct mbuf **)0, 293 (struct mbuf **)0, &flags); 294 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY); 295 return (error); 296 } 297 298 /* 299 * Vnode op for write 300 * 301 * fifo_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag, 302 * struct ucred *a_cred) 303 */ 304 /* ARGSUSED */ 305 static int 306 fifo_write(struct vop_write_args *ap) 307 { 308 struct socket *wso = ap->a_vp->v_fifoinfo->fi_writesock; 309 struct thread *td = ap->a_uio->uio_td; 310 int error; 311 int flags; 312 313 #ifdef DIAGNOSTIC 314 if (ap->a_uio->uio_rw != UIO_WRITE) 315 panic("fifo_write mode"); 316 #endif 317 if (ap->a_ioflag & IO_NDELAY) 318 flags = MSG_FNONBLOCKING; 319 else 320 flags = 0; 321 vn_unlock(ap->a_vp); 322 error = sosend(wso, (struct sockaddr *)0, ap->a_uio, 0, 323 (struct mbuf *)0, flags, td); 324 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY); 325 return (error); 326 } 327 328 /* 329 * Device ioctl operation. 330 * 331 * fifo_ioctl(struct vnode *a_vp, int a_command, caddr_t a_data, int a_fflag, 332 * struct ucred *a_cred, struct thread *a_td) 333 */ 334 /* ARGSUSED */ 335 static int 336 fifo_ioctl(struct vop_ioctl_args *ap) 337 { 338 struct file filetmp; /* Local */ 339 int error; 340 341 if (ap->a_fflag & FREAD) { 342 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_readsock; 343 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_cred); 344 if (error) 345 return (error); 346 } 347 if (ap->a_fflag & FWRITE) { 348 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_writesock; 349 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_cred); 350 if (error) 351 return (error); 352 } 353 return (0); 354 } 355 356 /* 357 * fifo_kqfilter(struct vnode *a_vp, struct knote *a_kn) 358 */ 359 /* ARGSUSED */ 360 static int 361 fifo_kqfilter(struct vop_kqfilter_args *ap) 362 { 363 struct fifoinfo *fi = ap->a_vp->v_fifoinfo; 364 struct socket *so; 365 struct sockbuf *sb; 366 367 switch (ap->a_kn->kn_filter) { 368 case EVFILT_READ: 369 ap->a_kn->kn_fop = &fiforead_filtops; 370 so = fi->fi_readsock; 371 sb = &so->so_rcv; 372 break; 373 case EVFILT_WRITE: 374 ap->a_kn->kn_fop = &fifowrite_filtops; 375 so = fi->fi_writesock; 376 sb = &so->so_snd; 377 break; 378 default: 379 return (1); 380 } 381 382 ap->a_kn->kn_hook = (caddr_t)so; 383 384 SLIST_INSERT_HEAD(&sb->sb_sel.si_note, ap->a_kn, kn_selnext); 385 sb->sb_flags |= SB_KNOTE; 386 387 return (0); 388 } 389 390 static void 391 filt_fifordetach(struct knote *kn) 392 { 393 struct socket *so = (struct socket *)kn->kn_hook; 394 395 SLIST_REMOVE(&so->so_rcv.sb_sel.si_note, kn, knote, kn_selnext); 396 if (SLIST_EMPTY(&so->so_rcv.sb_sel.si_note)) 397 so->so_rcv.sb_flags &= ~SB_KNOTE; 398 } 399 400 static int 401 filt_fiforead(struct knote *kn, long hint) 402 { 403 struct socket *so = (struct socket *)kn->kn_hook; 404 405 kn->kn_data = so->so_rcv.sb_cc; 406 if (so->so_state & SS_CANTRCVMORE) { 407 kn->kn_flags |= EV_EOF; 408 return (1); 409 } 410 kn->kn_flags &= ~EV_EOF; 411 return (kn->kn_data > 0); 412 } 413 414 static void 415 filt_fifowdetach(struct knote *kn) 416 { 417 struct socket *so = (struct socket *)kn->kn_hook; 418 419 SLIST_REMOVE(&so->so_snd.sb_sel.si_note, kn, knote, kn_selnext); 420 if (SLIST_EMPTY(&so->so_snd.sb_sel.si_note)) 421 so->so_snd.sb_flags &= ~SB_KNOTE; 422 } 423 424 static int 425 filt_fifowrite(struct knote *kn, long hint) 426 { 427 struct socket *so = (struct socket *)kn->kn_hook; 428 429 kn->kn_data = sbspace(&so->so_snd); 430 if (so->so_state & SS_CANTSENDMORE) { 431 kn->kn_flags |= EV_EOF; 432 return (1); 433 } 434 kn->kn_flags &= ~EV_EOF; 435 return (kn->kn_data >= so->so_snd.sb_lowat); 436 } 437 438 /* 439 * fifo_poll(struct vnode *a_vp, int a_events, struct ucred *a_cred, 440 * struct thread *a_td) 441 */ 442 /* ARGSUSED */ 443 static int 444 fifo_poll(struct vop_poll_args *ap) 445 { 446 struct file filetmp; 447 int events, revents = 0; 448 449 events = ap->a_events & 450 (POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM | POLLRDBAND); 451 if (events) { 452 /* 453 * If POLLIN or POLLRDNORM is requested and POLLINIGNEOF is 454 * not, then convert the first two to the last one. This 455 * tells the socket poll function to ignore EOF so that we 456 * block if there is no writer (and no data). Callers can 457 * set POLLINIGNEOF to get non-blocking behavior. 458 */ 459 if (events & (POLLIN | POLLRDNORM) && 460 !(events & POLLINIGNEOF)) { 461 events &= ~(POLLIN | POLLRDNORM); 462 events |= POLLINIGNEOF; 463 } 464 465 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_readsock; 466 if (filetmp.f_data) 467 revents |= soo_poll(&filetmp, events, ap->a_cred); 468 469 /* Reverse the above conversion. */ 470 if ((revents & POLLINIGNEOF) && 471 !(ap->a_events & POLLINIGNEOF)) { 472 revents |= (ap->a_events & (POLLIN | POLLRDNORM)); 473 revents &= ~POLLINIGNEOF; 474 } 475 } 476 events = ap->a_events & (POLLOUT | POLLWRNORM | POLLWRBAND); 477 if (events) { 478 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_writesock; 479 if (filetmp.f_data) 480 revents |= soo_poll(&filetmp, events, ap->a_cred); 481 } 482 return (revents); 483 } 484 485 /* 486 * fifo_inactive(struct vnode *a_vp, struct thread *a_td) 487 */ 488 static int 489 fifo_inactive(struct vop_inactive_args *ap) 490 { 491 return (0); 492 } 493 494 /* 495 * This is a noop, simply returning what one has been given. 496 * 497 * fifo_bmap(struct vnode *a_vp, off_t a_loffset, struct vnode **a_vpp, 498 * off_t *a_doffsetp, int *a_runp, int *a_runb) 499 */ 500 static int 501 fifo_bmap(struct vop_bmap_args *ap) 502 { 503 if (ap->a_vpp != NULL) 504 *ap->a_vpp = ap->a_vp; 505 if (ap->a_doffsetp != NULL) 506 *ap->a_doffsetp = ap->a_loffset; 507 if (ap->a_runp != NULL) 508 *ap->a_runp = 0; 509 if (ap->a_runb != NULL) 510 *ap->a_runb = 0; 511 return (0); 512 } 513 514 /* 515 * Device close routine 516 * 517 * fifo_close(struct vnode *a_vp, int a_fflag, struct ucred *a_cred, 518 * struct thread *a_td) 519 */ 520 /* ARGSUSED */ 521 static int 522 fifo_close(struct vop_close_args *ap) 523 { 524 struct vnode *vp = ap->a_vp; 525 struct fifoinfo *fip = vp->v_fifoinfo; 526 int error1, error2; 527 528 if (ap->a_fflag & FREAD) { 529 fip->fi_readers--; 530 if (fip->fi_readers == 0) 531 socantsendmore(fip->fi_writesock); 532 } 533 if (ap->a_fflag & FWRITE) { 534 fip->fi_writers--; 535 if (fip->fi_writers == 0) 536 socantrcvmore(fip->fi_readsock); 537 } 538 if (vp->v_usecount > 1) { 539 vop_stdclose(ap); 540 return (0); 541 } 542 error1 = soclose(fip->fi_readsock, FNONBLOCK); 543 error2 = soclose(fip->fi_writesock, FNONBLOCK); 544 FREE(fip, M_FIFOINFO); 545 vp->v_fifoinfo = NULL; 546 if (error1) 547 return (error1); 548 vop_stdclose(ap); 549 return (error2); 550 } 551 552 553 /* 554 * Print out internal contents of a fifo vnode. 555 */ 556 int 557 fifo_printinfo(struct vnode *vp) 558 { 559 struct fifoinfo *fip = vp->v_fifoinfo; 560 561 kprintf(", fifo with %ld readers and %ld writers", 562 fip->fi_readers, fip->fi_writers); 563 return (0); 564 } 565 566 /* 567 * Print out the contents of a fifo vnode. 568 * 569 * fifo_print(struct vnode *a_vp) 570 */ 571 static int 572 fifo_print(struct vop_print_args *ap) 573 { 574 kprintf("tag VT_NON"); 575 fifo_printinfo(ap->a_vp); 576 kprintf("\n"); 577 return (0); 578 } 579 580 /* 581 * Return POSIX pathconf information applicable to fifo's. 582 * 583 * fifo_pathconf(struct vnode *a_vp, int a_name, int *a_retval) 584 */ 585 int 586 fifo_pathconf(struct vop_pathconf_args *ap) 587 { 588 switch (ap->a_name) { 589 case _PC_LINK_MAX: 590 *ap->a_retval = LINK_MAX; 591 return (0); 592 case _PC_PIPE_BUF: 593 *ap->a_retval = PIPE_BUF; 594 return (0); 595 case _PC_CHOWN_RESTRICTED: 596 *ap->a_retval = 1; 597 return (0); 598 default: 599 return (EINVAL); 600 } 601 /* NOTREACHED */ 602 } 603 604 /* 605 * Fifo advisory byte-level locks. 606 * 607 * fifo_advlock(struct vnode *a_vp, caddr_t a_id, int a_op, struct flock *a_fl, 608 * int a_flags) 609 */ 610 /* ARGSUSED */ 611 static int 612 fifo_advlock(struct vop_advlock_args *ap) 613 { 614 return ((ap->a_flags & F_POSIX) ? EINVAL : EOPNOTSUPP); 615 } 616 617 /* 618 * Fifo bad operation 619 */ 620 static int 621 fifo_badop(void) 622 { 623 panic("fifo_badop called"); 624 /* NOTREACHED */ 625 } 626