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 /* 34 * Filesystem FIFO type ops. All entry points are MPSAFE. We primarily 35 * use v_token to interlock operations. 36 */ 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/unistd.h> 40 #include <sys/kernel.h> 41 #include <sys/lock.h> 42 #include <sys/malloc.h> 43 #include <sys/thread2.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 54 #include <sys/thread2.h> 55 56 #include "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_badop (void); 70 static int fifo_print (struct vop_print_args *); 71 static int fifo_lookup (struct vop_old_lookup_args *); 72 static int fifo_open (struct vop_open_args *); 73 static int fifo_close (struct vop_close_args *); 74 static int fifo_read (struct vop_read_args *); 75 static int fifo_write (struct vop_write_args *); 76 static int fifo_ioctl (struct vop_ioctl_args *); 77 static int fifo_poll (struct vop_poll_args *); 78 static int fifo_kqfilter (struct vop_kqfilter_args *); 79 static int fifo_inactive (struct vop_inactive_args *); 80 static int fifo_bmap (struct vop_bmap_args *); 81 static int fifo_pathconf (struct vop_pathconf_args *); 82 static int fifo_advlock (struct vop_advlock_args *); 83 84 static void filt_fifordetach(struct knote *kn); 85 static int filt_fiforead(struct knote *kn, long hint); 86 static void filt_fifowdetach(struct knote *kn); 87 static int filt_fifowrite(struct knote *kn, long hint); 88 89 static struct filterops fiforead_filtops = 90 { 1, NULL, filt_fifordetach, filt_fiforead }; 91 static struct filterops fifowrite_filtops = 92 { 1, NULL, filt_fifowdetach, filt_fifowrite }; 93 94 struct vop_ops fifo_vnode_vops = { 95 .vop_default = vop_defaultop, 96 .vop_access = (void *)vop_ebadf, 97 .vop_advlock = fifo_advlock, 98 .vop_bmap = fifo_bmap, 99 .vop_close = fifo_close, 100 .vop_old_create = (void *)fifo_badop, 101 .vop_getattr = (void *)vop_ebadf, 102 .vop_inactive = fifo_inactive, 103 .vop_ioctl = fifo_ioctl, 104 .vop_kqfilter = fifo_kqfilter, 105 .vop_old_link = (void *)fifo_badop, 106 .vop_old_lookup = fifo_lookup, 107 .vop_old_mkdir = (void *)fifo_badop, 108 .vop_old_mknod = (void *)fifo_badop, 109 .vop_open = fifo_open, 110 .vop_pathconf = fifo_pathconf, 111 .vop_poll = fifo_poll, 112 .vop_print = fifo_print, 113 .vop_read = fifo_read, 114 .vop_readdir = (void *)fifo_badop, 115 .vop_readlink = (void *)fifo_badop, 116 .vop_reallocblks = (void *)fifo_badop, 117 .vop_reclaim = (void *)vop_null, 118 .vop_old_remove = (void *)fifo_badop, 119 .vop_old_rename = (void *)fifo_badop, 120 .vop_old_rmdir = (void *)fifo_badop, 121 .vop_setattr = (void *)vop_ebadf, 122 .vop_old_symlink = (void *)fifo_badop, 123 .vop_write = fifo_write 124 }; 125 126 VNODEOP_SET(fifo_vnode_vops); 127 128 static MALLOC_DEFINE(M_FIFOINFO, "Fifo info", "Fifo info entries"); 129 130 /* 131 * fifo_vnoperate() 132 */ 133 int 134 fifo_vnoperate(struct vop_generic_args *ap) 135 { 136 return (VOCALL(&fifo_vnode_vops, ap)); 137 } 138 139 /* 140 * Trivial lookup routine that always fails. 141 * 142 * fifo_lookup(struct vnode *a_dvp, struct vnode **a_vpp, 143 * struct componentname *a_cnp) 144 */ 145 /* ARGSUSED */ 146 static int 147 fifo_lookup(struct vop_old_lookup_args *ap) 148 { 149 *ap->a_vpp = NULL; 150 return (ENOTDIR); 151 } 152 153 /* 154 * Open called to set up a new instance of a fifo or 155 * to find an active instance of a fifo. 156 * 157 * fifo_open(struct vnode *a_vp, int a_mode, struct ucred *a_cred, 158 * struct file *a_fp) 159 */ 160 /* ARGSUSED */ 161 static int 162 fifo_open(struct vop_open_args *ap) 163 { 164 struct thread *td = curthread; 165 struct vnode *vp = ap->a_vp; 166 struct fifoinfo *fip; 167 struct socket *rso, *wso; 168 int error; 169 170 lwkt_gettoken(&vp->v_token); 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 goto done; 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 goto done; 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 goto done; 196 } 197 fip->fi_readers = fip->fi_writers = 0; 198 wso->so_snd.ssb_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 vsetflags(vp, VNOTSEEKABLE); 259 error = vop_stdopen(ap); 260 lwkt_reltoken(&vp->v_token); 261 return (error); 262 bad: 263 vop_stdopen(ap); /* bump opencount/writecount as appropriate */ 264 VOP_CLOSE(vp, ap->a_mode); 265 done: 266 lwkt_reltoken(&vp->v_token); 267 return (error); 268 } 269 270 /* 271 * Vnode op for read 272 * 273 * fifo_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag, 274 * struct ucred *a_cred) 275 */ 276 /* ARGSUSED */ 277 static int 278 fifo_read(struct vop_read_args *ap) 279 { 280 struct uio *uio = ap->a_uio; 281 struct vnode *vp = ap->a_vp; 282 struct socket *rso = vp->v_fifoinfo->fi_readsock; 283 int error, startresid; 284 int flags; 285 286 #ifdef DIAGNOSTIC 287 if (uio->uio_rw != UIO_READ) 288 panic("fifo_read mode"); 289 #endif 290 if (uio->uio_resid == 0) 291 return (0); 292 if (ap->a_ioflag & IO_NDELAY) 293 flags = MSG_FNONBLOCKING; 294 else 295 flags = 0; 296 startresid = uio->uio_resid; 297 vn_unlock(vp); 298 lwkt_gettoken(&vp->v_token); 299 error = soreceive(rso, NULL, uio, NULL, NULL, &flags); 300 lwkt_reltoken(&vp->v_token); 301 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 302 return (error); 303 } 304 305 /* 306 * Vnode op for write 307 * 308 * fifo_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag, 309 * struct ucred *a_cred) 310 */ 311 /* ARGSUSED */ 312 static int 313 fifo_write(struct vop_write_args *ap) 314 { 315 struct thread *td = ap->a_uio->uio_td; 316 struct vnode *vp = ap->a_vp; 317 struct socket *wso = vp->v_fifoinfo->fi_writesock; 318 int error; 319 int flags; 320 321 #ifdef DIAGNOSTIC 322 if (ap->a_uio->uio_rw != UIO_WRITE) 323 panic("fifo_write mode"); 324 #endif 325 if (ap->a_ioflag & IO_NDELAY) 326 flags = MSG_FNONBLOCKING; 327 else 328 flags = 0; 329 vn_unlock(vp); 330 lwkt_gettoken(&vp->v_token); 331 error = sosend(wso, NULL, ap->a_uio, 0, NULL, flags, td); 332 lwkt_reltoken(&vp->v_token); 333 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 334 return (error); 335 } 336 337 /* 338 * Device ioctl operation. 339 * 340 * fifo_ioctl(struct vnode *a_vp, int a_command, caddr_t a_data, int a_fflag, 341 * struct ucred *a_cred, struct sysmsg *a_sysmsg) 342 */ 343 /* ARGSUSED */ 344 static int 345 fifo_ioctl(struct vop_ioctl_args *ap) 346 { 347 struct file filetmp; /* Local */ 348 struct vnode *vp = ap->a_vp; 349 int error; 350 351 if (ap->a_fflag & FREAD) { 352 filetmp.f_data = vp->v_fifoinfo->fi_readsock; 353 lwkt_gettoken(&vp->v_token); 354 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, 355 ap->a_cred, ap->a_sysmsg); 356 lwkt_reltoken(&vp->v_token); 357 if (error) 358 return (error); 359 } 360 if (ap->a_fflag & FWRITE) { 361 filetmp.f_data = vp->v_fifoinfo->fi_writesock; 362 lwkt_gettoken(&vp->v_token); 363 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, 364 ap->a_cred, ap->a_sysmsg); 365 lwkt_reltoken(&vp->v_token); 366 if (error) 367 return (error); 368 } 369 return (0); 370 } 371 372 /* 373 * fifo_kqfilter(struct vnode *a_vp, struct knote *a_kn) 374 */ 375 /* ARGSUSED */ 376 static int 377 fifo_kqfilter(struct vop_kqfilter_args *ap) 378 { 379 struct vnode *vp = ap->a_vp; 380 struct fifoinfo *fi = vp->v_fifoinfo; 381 struct socket *so; 382 struct signalsockbuf *ssb; 383 384 lwkt_gettoken(&vp->v_token); 385 386 switch (ap->a_kn->kn_filter) { 387 case EVFILT_READ: 388 ap->a_kn->kn_fop = &fiforead_filtops; 389 so = fi->fi_readsock; 390 ssb = &so->so_rcv; 391 break; 392 case EVFILT_WRITE: 393 ap->a_kn->kn_fop = &fifowrite_filtops; 394 so = fi->fi_writesock; 395 ssb = &so->so_snd; 396 break; 397 default: 398 lwkt_reltoken(&vp->v_token); 399 return (EOPNOTSUPP); 400 } 401 402 ap->a_kn->kn_hook = (caddr_t)vp; 403 ssb_insert_knote(ssb, ap->a_kn); 404 405 lwkt_reltoken(&vp->v_token); 406 return (0); 407 } 408 409 static void 410 filt_fifordetach(struct knote *kn) 411 { 412 struct vnode *vp = (void *)kn->kn_hook; 413 struct socket *so = vp->v_fifoinfo->fi_readsock; 414 415 lwkt_gettoken(&vp->v_token); 416 ssb_remove_knote(&so->so_rcv, kn); 417 lwkt_reltoken(&vp->v_token); 418 } 419 420 static int 421 filt_fiforead(struct knote *kn, long hint) 422 { 423 struct vnode *vp = (void *)kn->kn_hook; 424 struct socket *so = vp->v_fifoinfo->fi_readsock; 425 426 lwkt_gettoken(&vp->v_token); 427 kn->kn_data = so->so_rcv.ssb_cc; 428 if (so->so_state & SS_CANTRCVMORE) { 429 kn->kn_flags |= EV_EOF; 430 lwkt_reltoken(&vp->v_token); 431 return (1); 432 } 433 kn->kn_flags &= ~EV_EOF; 434 lwkt_reltoken(&vp->v_token); 435 return (kn->kn_data > 0); 436 } 437 438 static void 439 filt_fifowdetach(struct knote *kn) 440 { 441 struct vnode *vp = (void *)kn->kn_hook; 442 struct socket *so = vp->v_fifoinfo->fi_writesock; 443 444 lwkt_gettoken(&vp->v_token); 445 ssb_remove_knote(&so->so_snd, kn); 446 lwkt_reltoken(&vp->v_token); 447 } 448 449 static int 450 filt_fifowrite(struct knote *kn, long hint) 451 { 452 struct vnode *vp = (void *)kn->kn_hook; 453 struct socket *so = vp->v_fifoinfo->fi_writesock; 454 455 lwkt_gettoken(&vp->v_token); 456 kn->kn_data = ssb_space(&so->so_snd); 457 if (so->so_state & SS_CANTSENDMORE) { 458 kn->kn_flags |= EV_EOF; 459 lwkt_reltoken(&vp->v_token); 460 return (1); 461 } 462 kn->kn_flags &= ~EV_EOF; 463 lwkt_reltoken(&vp->v_token); 464 return (kn->kn_data >= so->so_snd.ssb_lowat); 465 } 466 467 /* 468 * fifo_poll(struct vnode *a_vp, int a_events, struct ucred *a_cred) 469 */ 470 /* ARGSUSED */ 471 static int 472 fifo_poll(struct vop_poll_args *ap) 473 { 474 struct vnode *vp = ap->a_vp; 475 struct file filetmp; 476 int events, revents = 0; 477 478 lwkt_gettoken(&vp->v_token); 479 events = ap->a_events & 480 (POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM | POLLRDBAND); 481 if (events) { 482 /* 483 * If POLLIN or POLLRDNORM is requested and POLLINIGNEOF is 484 * not, then convert the first two to the last one. This 485 * tells the socket poll function to ignore EOF so that we 486 * block if there is no writer (and no data). Callers can 487 * set POLLINIGNEOF to get non-blocking behavior. 488 */ 489 if (events & (POLLIN | POLLRDNORM) && 490 !(events & POLLINIGNEOF)) { 491 events &= ~(POLLIN | POLLRDNORM); 492 events |= POLLINIGNEOF; 493 } 494 495 filetmp.f_data = vp->v_fifoinfo->fi_readsock; 496 if (filetmp.f_data) 497 revents |= soo_poll(&filetmp, events, ap->a_cred); 498 499 /* Reverse the above conversion. */ 500 if ((revents & POLLINIGNEOF) && 501 !(ap->a_events & POLLINIGNEOF)) { 502 revents |= (ap->a_events & (POLLIN | POLLRDNORM)); 503 revents &= ~POLLINIGNEOF; 504 } 505 } 506 events = ap->a_events & (POLLOUT | POLLWRNORM | POLLWRBAND); 507 if (events) { 508 filetmp.f_data = vp->v_fifoinfo->fi_writesock; 509 if (filetmp.f_data) 510 revents |= soo_poll(&filetmp, events, ap->a_cred); 511 } 512 lwkt_reltoken(&vp->v_token); 513 return (revents); 514 } 515 516 /* 517 * fifo_inactive(struct vnode *a_vp) 518 */ 519 static int 520 fifo_inactive(struct vop_inactive_args *ap) 521 { 522 return (0); 523 } 524 525 /* 526 * This is a noop, simply returning what one has been given. 527 * 528 * fifo_bmap(struct vnode *a_vp, off_t a_loffset, 529 * off_t *a_doffsetp, int *a_runp, int *a_runb) 530 */ 531 static int 532 fifo_bmap(struct vop_bmap_args *ap) 533 { 534 if (ap->a_doffsetp != NULL) 535 *ap->a_doffsetp = ap->a_loffset; 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 * fifo_close(struct vnode *a_vp, int a_fflag) 547 */ 548 /* ARGSUSED */ 549 static int 550 fifo_close(struct vop_close_args *ap) 551 { 552 struct vnode *vp = ap->a_vp; 553 struct fifoinfo *fip; 554 int error1, error2; 555 556 lwkt_gettoken(&vp->v_token); 557 fip = vp->v_fifoinfo; 558 if (ap->a_fflag & FREAD) { 559 fip->fi_readers--; 560 if (fip->fi_readers == 0) 561 socantsendmore(fip->fi_writesock); 562 } 563 if (ap->a_fflag & FWRITE) { 564 fip->fi_writers--; 565 if (fip->fi_writers == 0) 566 socantrcvmore(fip->fi_readsock); 567 } 568 if (vp->v_sysref.refcnt > 1) { 569 vop_stdclose(ap); 570 lwkt_reltoken(&vp->v_token); 571 return (0); 572 } 573 error1 = soclose(fip->fi_readsock, FNONBLOCK); 574 error2 = soclose(fip->fi_writesock, FNONBLOCK); 575 FREE(fip, M_FIFOINFO); 576 vp->v_fifoinfo = NULL; 577 if (error1) { 578 error2 = error1; 579 } else { 580 vop_stdclose(ap); 581 } 582 lwkt_reltoken(&vp->v_token); 583 return (error2); 584 } 585 586 587 /* 588 * Print out internal contents of a fifo vnode. 589 */ 590 int 591 fifo_printinfo(struct vnode *vp) 592 { 593 struct fifoinfo *fip = vp->v_fifoinfo; 594 595 kprintf(", fifo with %ld readers and %ld writers", 596 fip->fi_readers, fip->fi_writers); 597 return (0); 598 } 599 600 /* 601 * Print out the contents of a fifo vnode. 602 * 603 * fifo_print(struct vnode *a_vp) 604 */ 605 static int 606 fifo_print(struct vop_print_args *ap) 607 { 608 kprintf("tag VT_NON"); 609 fifo_printinfo(ap->a_vp); 610 kprintf("\n"); 611 return (0); 612 } 613 614 /* 615 * Return POSIX pathconf information applicable to fifo's. 616 * 617 * fifo_pathconf(struct vnode *a_vp, int a_name, int *a_retval) 618 */ 619 int 620 fifo_pathconf(struct vop_pathconf_args *ap) 621 { 622 switch (ap->a_name) { 623 case _PC_LINK_MAX: 624 *ap->a_retval = LINK_MAX; 625 return (0); 626 case _PC_PIPE_BUF: 627 *ap->a_retval = PIPE_BUF; 628 return (0); 629 case _PC_CHOWN_RESTRICTED: 630 *ap->a_retval = 1; 631 return (0); 632 default: 633 return (EINVAL); 634 } 635 /* NOTREACHED */ 636 } 637 638 /* 639 * Fifo advisory byte-level locks. 640 * 641 * fifo_advlock(struct vnode *a_vp, caddr_t a_id, int a_op, struct flock *a_fl, 642 * int a_flags) 643 */ 644 /* ARGSUSED */ 645 static int 646 fifo_advlock(struct vop_advlock_args *ap) 647 { 648 return ((ap->a_flags & F_POSIX) ? EINVAL : EOPNOTSUPP); 649 } 650 651 /* 652 * Fifo bad operation 653 */ 654 static int 655 fifo_badop(void) 656 { 657 panic("fifo_badop called"); 658 /* NOTREACHED */ 659 } 660