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.40 2007/08/13 17:31:56 dillon 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 file *a_fp) 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.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 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, NULL, uio, NULL, NULL, &flags); 293 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY); 294 return (error); 295 } 296 297 /* 298 * Vnode op for write 299 * 300 * fifo_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag, 301 * struct ucred *a_cred) 302 */ 303 /* ARGSUSED */ 304 static int 305 fifo_write(struct vop_write_args *ap) 306 { 307 struct socket *wso = ap->a_vp->v_fifoinfo->fi_writesock; 308 struct thread *td = ap->a_uio->uio_td; 309 int error; 310 int flags; 311 312 #ifdef DIAGNOSTIC 313 if (ap->a_uio->uio_rw != UIO_WRITE) 314 panic("fifo_write mode"); 315 #endif 316 if (ap->a_ioflag & IO_NDELAY) 317 flags = MSG_FNONBLOCKING; 318 else 319 flags = 0; 320 vn_unlock(ap->a_vp); 321 error = sosend(wso, NULL, ap->a_uio, 0, NULL, flags, td); 322 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY); 323 return (error); 324 } 325 326 /* 327 * Device ioctl operation. 328 * 329 * fifo_ioctl(struct vnode *a_vp, int a_command, caddr_t a_data, int a_fflag, 330 * struct ucred *a_cred) 331 */ 332 /* ARGSUSED */ 333 static int 334 fifo_ioctl(struct vop_ioctl_args *ap) 335 { 336 struct file filetmp; /* Local */ 337 int error; 338 339 if (ap->a_fflag & FREAD) { 340 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_readsock; 341 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_cred); 342 if (error) 343 return (error); 344 } 345 if (ap->a_fflag & FWRITE) { 346 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_writesock; 347 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_cred); 348 if (error) 349 return (error); 350 } 351 return (0); 352 } 353 354 /* 355 * fifo_kqfilter(struct vnode *a_vp, struct knote *a_kn) 356 */ 357 /* ARGSUSED */ 358 static int 359 fifo_kqfilter(struct vop_kqfilter_args *ap) 360 { 361 struct fifoinfo *fi = ap->a_vp->v_fifoinfo; 362 struct socket *so; 363 struct signalsockbuf *ssb; 364 365 switch (ap->a_kn->kn_filter) { 366 case EVFILT_READ: 367 ap->a_kn->kn_fop = &fiforead_filtops; 368 so = fi->fi_readsock; 369 ssb = &so->so_rcv; 370 break; 371 case EVFILT_WRITE: 372 ap->a_kn->kn_fop = &fifowrite_filtops; 373 so = fi->fi_writesock; 374 ssb = &so->so_snd; 375 break; 376 default: 377 return (1); 378 } 379 380 ap->a_kn->kn_hook = (caddr_t)so; 381 382 ssb_insert_knote(ssb, ap->a_kn); 383 384 return (0); 385 } 386 387 static void 388 filt_fifordetach(struct knote *kn) 389 { 390 struct socket *so = (struct socket *)kn->kn_hook; 391 392 ssb_remove_knote(&so->so_rcv, kn); 393 } 394 395 static int 396 filt_fiforead(struct knote *kn, long hint) 397 { 398 struct socket *so = (struct socket *)kn->kn_hook; 399 400 kn->kn_data = so->so_rcv.ssb_cc; 401 if (so->so_state & SS_CANTRCVMORE) { 402 kn->kn_flags |= EV_EOF; 403 return (1); 404 } 405 kn->kn_flags &= ~EV_EOF; 406 return (kn->kn_data > 0); 407 } 408 409 static void 410 filt_fifowdetach(struct knote *kn) 411 { 412 struct socket *so = (struct socket *)kn->kn_hook; 413 414 ssb_remove_knote(&so->so_snd, kn); 415 } 416 417 static int 418 filt_fifowrite(struct knote *kn, long hint) 419 { 420 struct socket *so = (struct socket *)kn->kn_hook; 421 422 kn->kn_data = ssb_space(&so->so_snd); 423 if (so->so_state & SS_CANTSENDMORE) { 424 kn->kn_flags |= EV_EOF; 425 return (1); 426 } 427 kn->kn_flags &= ~EV_EOF; 428 return (kn->kn_data >= so->so_snd.ssb_lowat); 429 } 430 431 /* 432 * fifo_poll(struct vnode *a_vp, int a_events, struct ucred *a_cred) 433 */ 434 /* ARGSUSED */ 435 static int 436 fifo_poll(struct vop_poll_args *ap) 437 { 438 struct file filetmp; 439 int events, revents = 0; 440 441 events = ap->a_events & 442 (POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM | POLLRDBAND); 443 if (events) { 444 /* 445 * If POLLIN or POLLRDNORM is requested and POLLINIGNEOF is 446 * not, then convert the first two to the last one. This 447 * tells the socket poll function to ignore EOF so that we 448 * block if there is no writer (and no data). Callers can 449 * set POLLINIGNEOF to get non-blocking behavior. 450 */ 451 if (events & (POLLIN | POLLRDNORM) && 452 !(events & POLLINIGNEOF)) { 453 events &= ~(POLLIN | POLLRDNORM); 454 events |= POLLINIGNEOF; 455 } 456 457 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_readsock; 458 if (filetmp.f_data) 459 revents |= soo_poll(&filetmp, events, ap->a_cred); 460 461 /* Reverse the above conversion. */ 462 if ((revents & POLLINIGNEOF) && 463 !(ap->a_events & POLLINIGNEOF)) { 464 revents |= (ap->a_events & (POLLIN | POLLRDNORM)); 465 revents &= ~POLLINIGNEOF; 466 } 467 } 468 events = ap->a_events & (POLLOUT | POLLWRNORM | POLLWRBAND); 469 if (events) { 470 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_writesock; 471 if (filetmp.f_data) 472 revents |= soo_poll(&filetmp, events, ap->a_cred); 473 } 474 return (revents); 475 } 476 477 /* 478 * fifo_inactive(struct vnode *a_vp) 479 */ 480 static int 481 fifo_inactive(struct vop_inactive_args *ap) 482 { 483 return (0); 484 } 485 486 /* 487 * This is a noop, simply returning what one has been given. 488 * 489 * fifo_bmap(struct vnode *a_vp, off_t a_loffset, 490 * off_t *a_doffsetp, int *a_runp, int *a_runb) 491 */ 492 static int 493 fifo_bmap(struct vop_bmap_args *ap) 494 { 495 if (ap->a_doffsetp != NULL) 496 *ap->a_doffsetp = ap->a_loffset; 497 if (ap->a_runp != NULL) 498 *ap->a_runp = 0; 499 if (ap->a_runb != NULL) 500 *ap->a_runb = 0; 501 return (0); 502 } 503 504 /* 505 * Device close routine 506 * 507 * fifo_close(struct vnode *a_vp, int a_fflag) 508 */ 509 /* ARGSUSED */ 510 static int 511 fifo_close(struct vop_close_args *ap) 512 { 513 struct vnode *vp = ap->a_vp; 514 struct fifoinfo *fip = vp->v_fifoinfo; 515 int error1, error2; 516 517 if (ap->a_fflag & FREAD) { 518 fip->fi_readers--; 519 if (fip->fi_readers == 0) 520 socantsendmore(fip->fi_writesock); 521 } 522 if (ap->a_fflag & FWRITE) { 523 fip->fi_writers--; 524 if (fip->fi_writers == 0) 525 socantrcvmore(fip->fi_readsock); 526 } 527 if (vp->v_sysref.refcnt > 1) { 528 vop_stdclose(ap); 529 return (0); 530 } 531 error1 = soclose(fip->fi_readsock, FNONBLOCK); 532 error2 = soclose(fip->fi_writesock, FNONBLOCK); 533 FREE(fip, M_FIFOINFO); 534 vp->v_fifoinfo = NULL; 535 if (error1) 536 return (error1); 537 vop_stdclose(ap); 538 return (error2); 539 } 540 541 542 /* 543 * Print out internal contents of a fifo vnode. 544 */ 545 int 546 fifo_printinfo(struct vnode *vp) 547 { 548 struct fifoinfo *fip = vp->v_fifoinfo; 549 550 kprintf(", fifo with %ld readers and %ld writers", 551 fip->fi_readers, fip->fi_writers); 552 return (0); 553 } 554 555 /* 556 * Print out the contents of a fifo vnode. 557 * 558 * fifo_print(struct vnode *a_vp) 559 */ 560 static int 561 fifo_print(struct vop_print_args *ap) 562 { 563 kprintf("tag VT_NON"); 564 fifo_printinfo(ap->a_vp); 565 kprintf("\n"); 566 return (0); 567 } 568 569 /* 570 * Return POSIX pathconf information applicable to fifo's. 571 * 572 * fifo_pathconf(struct vnode *a_vp, int a_name, int *a_retval) 573 */ 574 int 575 fifo_pathconf(struct vop_pathconf_args *ap) 576 { 577 switch (ap->a_name) { 578 case _PC_LINK_MAX: 579 *ap->a_retval = LINK_MAX; 580 return (0); 581 case _PC_PIPE_BUF: 582 *ap->a_retval = PIPE_BUF; 583 return (0); 584 case _PC_CHOWN_RESTRICTED: 585 *ap->a_retval = 1; 586 return (0); 587 default: 588 return (EINVAL); 589 } 590 /* NOTREACHED */ 591 } 592 593 /* 594 * Fifo advisory byte-level locks. 595 * 596 * fifo_advlock(struct vnode *a_vp, caddr_t a_id, int a_op, struct flock *a_fl, 597 * int a_flags) 598 */ 599 /* ARGSUSED */ 600 static int 601 fifo_advlock(struct vop_advlock_args *ap) 602 { 603 return ((ap->a_flags & F_POSIX) ? EINVAL : EOPNOTSUPP); 604 } 605 606 /* 607 * Fifo bad operation 608 */ 609 static int 610 fifo_badop(void) 611 { 612 panic("fifo_badop called"); 613 /* NOTREACHED */ 614 } 615