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$ 35 */ 36 37 #include <sys/param.h> 38 #include <sys/event.h> 39 #include <sys/filio.h> 40 #include <sys/fcntl.h> 41 #include <sys/file.h> 42 #include <sys/kernel.h> 43 #include <sys/lock.h> 44 #include <sys/mutex.h> 45 #include <sys/malloc.h> 46 #include <sys/poll.h> 47 #include <sys/proc.h> /* XXXKSE */ 48 #include <sys/signalvar.h> 49 #include <sys/socket.h> 50 #include <sys/socketvar.h> 51 #include <sys/sx.h> 52 #include <sys/systm.h> 53 #include <sys/un.h> 54 #include <sys/unistd.h> 55 #include <sys/vnode.h> 56 #include <fs/fifofs/fifo.h> 57 58 /* 59 * This structure is associated with the FIFO vnode and stores 60 * the state associated with the FIFO. 61 */ 62 struct fifoinfo { 63 struct socket *fi_readsock; 64 struct socket *fi_writesock; 65 long fi_readers; 66 long fi_writers; 67 }; 68 69 static int fifo_print(struct vop_print_args *); 70 static int fifo_lookup(struct vop_lookup_args *); 71 static int fifo_open(struct vop_open_args *); 72 static int fifo_close(struct vop_close_args *); 73 static int fifo_read(struct vop_read_args *); 74 static int fifo_write(struct vop_write_args *); 75 static int fifo_ioctl(struct vop_ioctl_args *); 76 static int fifo_poll(struct vop_poll_args *); 77 static int fifo_kqfilter(struct vop_kqfilter_args *); 78 static int fifo_pathconf(struct vop_pathconf_args *); 79 static int fifo_advlock(struct vop_advlock_args *); 80 81 static void filt_fifordetach(struct knote *kn); 82 static int filt_fiforead(struct knote *kn, long hint); 83 static void filt_fifowdetach(struct knote *kn); 84 static int filt_fifowrite(struct knote *kn, long hint); 85 86 static struct filterops fiforead_filtops = 87 { 1, NULL, filt_fifordetach, filt_fiforead }; 88 static struct filterops fifowrite_filtops = 89 { 1, NULL, filt_fifowdetach, filt_fifowrite }; 90 91 vop_t **fifo_vnodeop_p; 92 static struct vnodeopv_entry_desc fifo_vnodeop_entries[] = { 93 { &vop_default_desc, (vop_t *) vop_defaultop }, 94 { &vop_access_desc, (vop_t *) vop_ebadf }, 95 { &vop_advlock_desc, (vop_t *) fifo_advlock }, 96 { &vop_close_desc, (vop_t *) fifo_close }, 97 { &vop_create_desc, (vop_t *) vop_panic }, 98 { &vop_getattr_desc, (vop_t *) vop_ebadf }, 99 { &vop_getwritemount_desc, (vop_t *) vop_stdgetwritemount }, 100 { &vop_ioctl_desc, (vop_t *) fifo_ioctl }, 101 { &vop_kqfilter_desc, (vop_t *) fifo_kqfilter }, 102 { &vop_lease_desc, (vop_t *) vop_null }, 103 { &vop_link_desc, (vop_t *) vop_panic }, 104 { &vop_lookup_desc, (vop_t *) fifo_lookup }, 105 { &vop_mkdir_desc, (vop_t *) vop_panic }, 106 { &vop_mknod_desc, (vop_t *) vop_panic }, 107 { &vop_open_desc, (vop_t *) fifo_open }, 108 { &vop_pathconf_desc, (vop_t *) fifo_pathconf }, 109 { &vop_poll_desc, (vop_t *) fifo_poll }, 110 { &vop_print_desc, (vop_t *) fifo_print }, 111 { &vop_read_desc, (vop_t *) fifo_read }, 112 { &vop_readdir_desc, (vop_t *) vop_panic }, 113 { &vop_readlink_desc, (vop_t *) vop_panic }, 114 { &vop_reallocblks_desc, (vop_t *) vop_panic }, 115 { &vop_reclaim_desc, (vop_t *) vop_null }, 116 { &vop_remove_desc, (vop_t *) vop_panic }, 117 { &vop_rename_desc, (vop_t *) vop_panic }, 118 { &vop_rmdir_desc, (vop_t *) vop_panic }, 119 { &vop_setattr_desc, (vop_t *) vop_ebadf }, 120 { &vop_symlink_desc, (vop_t *) vop_panic }, 121 { &vop_write_desc, (vop_t *) fifo_write }, 122 { NULL, NULL } 123 }; 124 static struct vnodeopv_desc fifo_vnodeop_opv_desc = 125 { &fifo_vnodeop_p, fifo_vnodeop_entries }; 126 127 VNODEOP_SET(fifo_vnodeop_opv_desc); 128 129 int 130 fifo_vnoperate(ap) 131 struct vop_generic_args /* { 132 struct vnodeop_desc *a_desc; 133 <other random data follows, presumably> 134 } */ *ap; 135 { 136 return (VOCALL(fifo_vnodeop_p, ap->a_desc->vdesc_offset, ap)); 137 } 138 139 /* 140 * Trivial lookup routine that always fails. 141 */ 142 /* ARGSUSED */ 143 static int 144 fifo_lookup(ap) 145 struct vop_lookup_args /* { 146 struct vnode * a_dvp; 147 struct vnode ** a_vpp; 148 struct componentname * a_cnp; 149 } */ *ap; 150 { 151 152 *ap->a_vpp = NULL; 153 return (ENOTDIR); 154 } 155 156 /* 157 * Open called to set up a new instance of a fifo or 158 * to find an active instance of a fifo. 159 */ 160 /* ARGSUSED */ 161 static int 162 fifo_open(ap) 163 struct vop_open_args /* { 164 struct vnode *a_vp; 165 int a_mode; 166 struct ucred *a_cred; 167 struct thread *a_td; 168 } */ *ap; 169 { 170 struct vnode *vp = ap->a_vp; 171 struct fifoinfo *fip; 172 struct thread *td = ap->a_td; 173 struct ucred *cred = ap->a_cred; 174 struct socket *rso, *wso; 175 int error; 176 177 if ((fip = vp->v_fifoinfo) == NULL) { 178 MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK); 179 error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, cred, td); 180 if (error) 181 goto fail1; 182 fip->fi_readsock = rso; 183 error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, cred, td); 184 if (error) 185 goto fail2; 186 fip->fi_writesock = wso; 187 error = unp_connect2(wso, rso); 188 if (error) { 189 (void)soclose(wso); 190 fail2: 191 (void)soclose(rso); 192 fail1: 193 free(fip, M_VNODE); 194 return (error); 195 } 196 fip->fi_readers = fip->fi_writers = 0; 197 wso->so_snd.sb_lowat = PIPE_BUF; 198 rso->so_state |= SS_CANTRCVMORE; 199 vp->v_fifoinfo = fip; 200 } 201 202 /* 203 * General access to fi_readers and fi_writers is protected using 204 * the vnode lock. 205 * 206 * Protect the increment of fi_readers and fi_writers and the 207 * associated calls to wakeup() with the vnode interlock in 208 * addition to the vnode lock. This allows the vnode lock to 209 * be dropped for the msleep() calls below, and using the vnode 210 * interlock as the msleep() mutex prevents the wakeup from 211 * being missed. 212 */ 213 VI_LOCK(vp); 214 if (ap->a_mode & FREAD) { 215 fip->fi_readers++; 216 if (fip->fi_readers == 1) { 217 fip->fi_writesock->so_state &= ~SS_CANTSENDMORE; 218 if (fip->fi_writers > 0) { 219 wakeup(&fip->fi_writers); 220 VI_UNLOCK(vp); 221 sowwakeup(fip->fi_writesock); 222 VI_LOCK(vp); 223 } 224 } 225 } 226 if (ap->a_mode & FWRITE) { 227 if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0) { 228 VI_UNLOCK(vp); 229 return (ENXIO); 230 } 231 fip->fi_writers++; 232 if (fip->fi_writers == 1) { 233 fip->fi_readsock->so_state &= ~SS_CANTRCVMORE; 234 if (fip->fi_readers > 0) { 235 wakeup(&fip->fi_readers); 236 VI_UNLOCK(vp); 237 sorwakeup(fip->fi_writesock); 238 VI_LOCK(vp); 239 } 240 } 241 } 242 if ((ap->a_mode & O_NONBLOCK) == 0) { 243 if ((ap->a_mode & FREAD) && fip->fi_writers == 0) { 244 VOP_UNLOCK(vp, 0, td); 245 error = msleep(&fip->fi_readers, VI_MTX(vp), 246 PCATCH | PSOCK, "fifoor", 0); 247 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY | LK_INTERLOCK, td); 248 if (error) { 249 fip->fi_readers--; 250 if (fip->fi_readers == 0) 251 socantsendmore(fip->fi_writesock); 252 return (error); 253 } 254 VI_LOCK(vp); 255 /* 256 * We must have got woken up because we had a writer. 257 * That (and not still having one) is the condition 258 * that we must wait for. 259 */ 260 } 261 if ((ap->a_mode & FWRITE) && fip->fi_readers == 0) { 262 VOP_UNLOCK(vp, 0, td); 263 error = msleep(&fip->fi_writers, VI_MTX(vp), 264 PCATCH | PSOCK, "fifoow", 0); 265 vn_lock(vp, 266 LK_EXCLUSIVE | LK_RETRY | LK_INTERLOCK, td); 267 if (error) { 268 fip->fi_writers--; 269 if (fip->fi_writers == 0) 270 socantrcvmore(fip->fi_readsock); 271 return (error); 272 } 273 /* 274 * We must have got woken up because we had 275 * a reader. That (and not still having one) 276 * is the condition that we must wait for. 277 */ 278 return (0); 279 } 280 } 281 VI_UNLOCK(vp); 282 return (0); 283 } 284 285 /* 286 * Vnode op for read 287 */ 288 /* ARGSUSED */ 289 static int 290 fifo_read(ap) 291 struct vop_read_args /* { 292 struct vnode *a_vp; 293 struct uio *a_uio; 294 int a_ioflag; 295 struct ucred *a_cred; 296 } */ *ap; 297 { 298 struct uio *uio = ap->a_uio; 299 struct socket *rso = ap->a_vp->v_fifoinfo->fi_readsock; 300 struct thread *td = uio->uio_td; 301 int error; 302 303 #ifdef DIAGNOSTIC 304 if (uio->uio_rw != UIO_READ) 305 panic("fifo_read mode"); 306 #endif 307 if (uio->uio_resid == 0) 308 return (0); 309 if (ap->a_ioflag & IO_NDELAY) 310 rso->so_state |= SS_NBIO; 311 VOP_UNLOCK(ap->a_vp, 0, td); 312 error = soreceive(rso, (struct sockaddr **)0, uio, (struct mbuf **)0, 313 (struct mbuf **)0, (int *)0); 314 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, td); 315 if (ap->a_ioflag & IO_NDELAY) 316 rso->so_state &= ~SS_NBIO; 317 return (error); 318 } 319 320 /* 321 * Vnode op for write 322 */ 323 /* ARGSUSED */ 324 static int 325 fifo_write(ap) 326 struct vop_write_args /* { 327 struct vnode *a_vp; 328 struct uio *a_uio; 329 int a_ioflag; 330 struct ucred *a_cred; 331 } */ *ap; 332 { 333 struct socket *wso = ap->a_vp->v_fifoinfo->fi_writesock; 334 struct thread *td = ap->a_uio->uio_td; 335 int error; 336 337 #ifdef DIAGNOSTIC 338 if (ap->a_uio->uio_rw != UIO_WRITE) 339 panic("fifo_write mode"); 340 #endif 341 if (ap->a_ioflag & IO_NDELAY) 342 wso->so_state |= SS_NBIO; 343 VOP_UNLOCK(ap->a_vp, 0, td); 344 error = sosend(wso, (struct sockaddr *)0, ap->a_uio, 0, 345 (struct mbuf *)0, 0, td); 346 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, td); 347 if (ap->a_ioflag & IO_NDELAY) 348 wso->so_state &= ~SS_NBIO; 349 return (error); 350 } 351 352 /* 353 * Device ioctl operation. 354 */ 355 /* ARGSUSED */ 356 static int 357 fifo_ioctl(ap) 358 struct vop_ioctl_args /* { 359 struct vnode *a_vp; 360 u_long a_command; 361 caddr_t a_data; 362 int a_fflag; 363 struct ucred *a_cred; 364 struct thread *a_td; 365 } */ *ap; 366 { 367 struct file filetmp; /* Local, so need not be locked. */ 368 int error; 369 370 if (ap->a_command == FIONBIO) 371 return (0); 372 if (ap->a_fflag & FREAD) { 373 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_readsock; 374 filetmp.f_cred = ap->a_cred; 375 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, 376 ap->a_td->td_ucred, ap->a_td); 377 if (error) 378 return (error); 379 } 380 if (ap->a_fflag & FWRITE) { 381 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_writesock; 382 filetmp.f_cred = ap->a_cred; 383 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, 384 ap->a_td->td_ucred, ap->a_td); 385 if (error) 386 return (error); 387 } 388 return (0); 389 } 390 391 /* ARGSUSED */ 392 static int 393 fifo_kqfilter(ap) 394 struct vop_kqfilter_args /* { 395 struct vnode *a_vp; 396 struct knote *a_kn; 397 } */ *ap; 398 { 399 struct fifoinfo *fi = ap->a_vp->v_fifoinfo; 400 struct socket *so; 401 struct sockbuf *sb; 402 403 switch (ap->a_kn->kn_filter) { 404 case EVFILT_READ: 405 ap->a_kn->kn_fop = &fiforead_filtops; 406 so = fi->fi_readsock; 407 sb = &so->so_rcv; 408 break; 409 case EVFILT_WRITE: 410 ap->a_kn->kn_fop = &fifowrite_filtops; 411 so = fi->fi_writesock; 412 sb = &so->so_snd; 413 break; 414 default: 415 return (1); 416 } 417 418 ap->a_kn->kn_hook = (caddr_t)so; 419 420 SLIST_INSERT_HEAD(&sb->sb_sel.si_note, ap->a_kn, kn_selnext); 421 sb->sb_flags |= SB_KNOTE; 422 423 return (0); 424 } 425 426 static void 427 filt_fifordetach(struct knote *kn) 428 { 429 struct socket *so = (struct socket *)kn->kn_hook; 430 431 SLIST_REMOVE(&so->so_rcv.sb_sel.si_note, kn, knote, kn_selnext); 432 if (SLIST_EMPTY(&so->so_rcv.sb_sel.si_note)) 433 so->so_rcv.sb_flags &= ~SB_KNOTE; 434 } 435 436 static int 437 filt_fiforead(struct knote *kn, long hint) 438 { 439 struct socket *so = (struct socket *)kn->kn_hook; 440 441 kn->kn_data = so->so_rcv.sb_cc; 442 if (so->so_state & SS_CANTRCVMORE) { 443 kn->kn_flags |= EV_EOF; 444 return (1); 445 } 446 kn->kn_flags &= ~EV_EOF; 447 return (kn->kn_data > 0); 448 } 449 450 static void 451 filt_fifowdetach(struct knote *kn) 452 { 453 struct socket *so = (struct socket *)kn->kn_hook; 454 455 SLIST_REMOVE(&so->so_snd.sb_sel.si_note, kn, knote, kn_selnext); 456 if (SLIST_EMPTY(&so->so_snd.sb_sel.si_note)) 457 so->so_snd.sb_flags &= ~SB_KNOTE; 458 } 459 460 static int 461 filt_fifowrite(struct knote *kn, long hint) 462 { 463 struct socket *so = (struct socket *)kn->kn_hook; 464 465 kn->kn_data = sbspace(&so->so_snd); 466 if (so->so_state & SS_CANTSENDMORE) { 467 kn->kn_flags |= EV_EOF; 468 return (1); 469 } 470 kn->kn_flags &= ~EV_EOF; 471 return (kn->kn_data >= so->so_snd.sb_lowat); 472 } 473 474 /* ARGSUSED */ 475 static int 476 fifo_poll(ap) 477 struct vop_poll_args /* { 478 struct vnode *a_vp; 479 int a_events; 480 struct ucred *a_cred; 481 struct thread *a_td; 482 } */ *ap; 483 { 484 struct file filetmp; 485 int events, revents = 0; 486 487 events = ap->a_events & 488 (POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM | POLLRDBAND); 489 if (events) { 490 /* 491 * If POLLIN or POLLRDNORM is requested and POLLINIGNEOF is 492 * not, then convert the first two to the last one. This 493 * tells the socket poll function to ignore EOF so that we 494 * block if there is no writer (and no data). Callers can 495 * set POLLINIGNEOF to get non-blocking behavior. 496 */ 497 if (events & (POLLIN | POLLRDNORM) && 498 !(events & POLLINIGNEOF)) { 499 events &= ~(POLLIN | POLLRDNORM); 500 events |= POLLINIGNEOF; 501 } 502 503 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_readsock; 504 filetmp.f_cred = ap->a_cred; 505 if (filetmp.f_data) 506 revents |= soo_poll(&filetmp, events, 507 ap->a_td->td_ucred, ap->a_td); 508 509 /* Reverse the above conversion. */ 510 if ((revents & POLLINIGNEOF) && 511 !(ap->a_events & POLLINIGNEOF)) { 512 revents |= (ap->a_events & (POLLIN | POLLRDNORM)); 513 revents &= ~POLLINIGNEOF; 514 } 515 } 516 events = ap->a_events & (POLLOUT | POLLWRNORM | POLLWRBAND); 517 if (events) { 518 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_writesock; 519 filetmp.f_cred = ap->a_cred; 520 if (filetmp.f_data) { 521 revents |= soo_poll(&filetmp, events, 522 ap->a_td->td_ucred, ap->a_td); 523 } 524 } 525 return (revents); 526 } 527 528 /* 529 * Device close routine 530 */ 531 /* ARGSUSED */ 532 static int 533 fifo_close(ap) 534 struct vop_close_args /* { 535 struct vnode *a_vp; 536 int a_fflag; 537 struct ucred *a_cred; 538 struct thread *a_td; 539 } */ *ap; 540 { 541 struct vnode *vp = ap->a_vp; 542 struct thread *td = ap->a_td; 543 struct fifoinfo *fip = vp->v_fifoinfo; 544 545 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 546 547 if (ap->a_fflag & FREAD) { 548 fip->fi_readers--; 549 if (fip->fi_readers == 0) 550 socantsendmore(fip->fi_writesock); 551 } 552 if (ap->a_fflag & FWRITE) { 553 fip->fi_writers--; 554 if (fip->fi_writers == 0) 555 socantrcvmore(fip->fi_readsock); 556 } 557 VI_LOCK(vp); 558 if (vp->v_usecount == 1) { 559 vp->v_fifoinfo = NULL; 560 VI_UNLOCK(vp); 561 (void)soclose(fip->fi_readsock); 562 (void)soclose(fip->fi_writesock); 563 FREE(fip, M_VNODE); 564 } else 565 VI_UNLOCK(vp); 566 VOP_UNLOCK(vp, 0, td); 567 return (0); 568 } 569 570 /* 571 * Print out internal contents of a fifo vnode. 572 */ 573 int 574 fifo_printinfo(vp) 575 struct vnode *vp; 576 { 577 register struct fifoinfo *fip = vp->v_fifoinfo; 578 579 printf(", fifo with %ld readers and %ld writers", 580 fip->fi_readers, fip->fi_writers); 581 return (0); 582 } 583 584 /* 585 * Print out the contents of a fifo vnode. 586 */ 587 static int 588 fifo_print(ap) 589 struct vop_print_args /* { 590 struct vnode *a_vp; 591 } */ *ap; 592 { 593 fifo_printinfo(ap->a_vp); 594 printf("\n"); 595 return (0); 596 } 597 598 /* 599 * Return POSIX pathconf information applicable to fifo's. 600 */ 601 static int 602 fifo_pathconf(ap) 603 struct vop_pathconf_args /* { 604 struct vnode *a_vp; 605 int a_name; 606 int *a_retval; 607 } */ *ap; 608 { 609 610 switch (ap->a_name) { 611 case _PC_LINK_MAX: 612 *ap->a_retval = LINK_MAX; 613 return (0); 614 case _PC_PIPE_BUF: 615 *ap->a_retval = PIPE_BUF; 616 return (0); 617 case _PC_CHOWN_RESTRICTED: 618 *ap->a_retval = 1; 619 return (0); 620 default: 621 return (EINVAL); 622 } 623 /* NOTREACHED */ 624 } 625 626 /* 627 * Fifo advisory byte-level locks. 628 */ 629 /* ARGSUSED */ 630 static int 631 fifo_advlock(ap) 632 struct vop_advlock_args /* { 633 struct vnode *a_vp; 634 caddr_t a_id; 635 int a_op; 636 struct flock *a_fl; 637 int a_flags; 638 } */ *ap; 639 { 640 641 return (ap->a_flags & F_FLOCK ? EOPNOTSUPP : EINVAL); 642 } 643