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