1 /* $NetBSD: kernfs_vnops.c,v 1.35 1995/02/03 16:18:46 mycroft Exp $ */ 2 3 /* 4 * Copyright (c) 1992, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software donated to Berkeley by 8 * Jan-Simon Pendry. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)kernfs_vnops.c 8.9 (Berkeley) 6/15/94 39 */ 40 41 /* 42 * Kernel parameter filesystem (/kern) 43 */ 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/kernel.h> 48 #include <sys/vmmeter.h> 49 #include <sys/types.h> 50 #include <sys/time.h> 51 #include <sys/proc.h> 52 #include <sys/vnode.h> 53 #include <sys/malloc.h> 54 #include <sys/file.h> 55 #include <sys/stat.h> 56 #include <sys/mount.h> 57 #include <sys/namei.h> 58 #include <sys/buf.h> 59 #include <sys/dirent.h> 60 #include <sys/msgbuf.h> 61 #include <miscfs/kernfs/kernfs.h> 62 63 #define KSTRING 256 /* Largest I/O available via this filesystem */ 64 #define UIO_MX 32 65 66 #define READ_MODE (S_IRUSR|S_IRGRP|S_IROTH) 67 #define WRITE_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH) 68 #define DIR_MODE (S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) 69 70 struct kern_target { 71 u_char kt_type; 72 u_char kt_namlen; 73 char *kt_name; 74 void *kt_data; 75 #define KTT_NULL 1 76 #define KTT_TIME 5 77 #define KTT_INT 17 78 #define KTT_STRING 31 79 #define KTT_HOSTNAME 47 80 #define KTT_AVENRUN 53 81 #define KTT_DEVICE 71 82 #define KTT_MSGBUF 89 83 u_char kt_tag; 84 u_char kt_vtype; 85 mode_t kt_mode; 86 } kern_targets[] = { 87 /* NOTE: The name must be less than UIO_MX-16 chars in length */ 88 #define N(s) sizeof(s)-1, s 89 /* name data tag type ro/rw */ 90 { DT_DIR, N("."), 0, KTT_NULL, VDIR, DIR_MODE }, 91 { DT_DIR, N(".."), 0, KTT_NULL, VDIR, DIR_MODE }, 92 { DT_REG, N("boottime"), &boottime.tv_sec, KTT_INT, VREG, READ_MODE }, 93 { DT_REG, N("copyright"), copyright, KTT_STRING, VREG, READ_MODE }, 94 { DT_REG, N("hostname"), 0, KTT_HOSTNAME, VREG, WRITE_MODE }, 95 { DT_REG, N("hz"), &hz, KTT_INT, VREG, READ_MODE }, 96 { DT_REG, N("loadavg"), 0, KTT_AVENRUN, VREG, READ_MODE }, 97 { DT_REG, N("msgbuf"), 0, KTT_MSGBUF, VREG, READ_MODE }, 98 { DT_REG, N("pagesize"), &cnt.v_page_size, KTT_INT, VREG, READ_MODE }, 99 { DT_REG, N("physmem"), &physmem, KTT_INT, VREG, READ_MODE }, 100 #if 0 101 { DT_DIR, N("root"), 0, KTT_NULL, VDIR, DIR_MODE }, 102 #endif 103 { DT_BLK, N("rootdev"), &rootdev, KTT_DEVICE, VBLK, READ_MODE }, 104 { DT_CHR, N("rrootdev"), &rrootdev, KTT_DEVICE, VCHR, READ_MODE }, 105 { DT_REG, N("time"), 0, KTT_TIME, VREG, READ_MODE }, 106 { DT_REG, N("version"), version, KTT_STRING, VREG, READ_MODE }, 107 #undef N 108 }; 109 static int nkern_targets = sizeof(kern_targets) / sizeof(kern_targets[0]); 110 111 int 112 kernfs_xread(kt, off, bufp, len) 113 struct kern_target *kt; 114 int off; 115 char **bufp; 116 int len; 117 { 118 119 switch (kt->kt_tag) { 120 case KTT_TIME: { 121 struct timeval tv; 122 123 microtime(&tv); 124 sprintf(*bufp, "%d %d\n", tv.tv_sec, tv.tv_usec); 125 break; 126 } 127 128 case KTT_INT: { 129 int *ip = kt->kt_data; 130 131 sprintf(*bufp, "%d\n", *ip); 132 break; 133 } 134 135 case KTT_STRING: { 136 char *cp = kt->kt_data; 137 138 *bufp = cp; 139 break; 140 } 141 142 case KTT_MSGBUF: { 143 extern struct msgbuf *msgbufp; 144 long n; 145 146 if (off >= MSG_BSIZE) 147 return (0); 148 n = msgbufp->msg_bufx + off; 149 if (n >= MSG_BSIZE) 150 n -= MSG_BSIZE; 151 len = min(MSG_BSIZE - n, MSG_BSIZE - off); 152 *bufp = msgbufp->msg_bufc + n; 153 return (len); 154 } 155 156 case KTT_HOSTNAME: { 157 char *cp = hostname; 158 int xlen = hostnamelen; 159 160 if (xlen >= (len-2)) 161 return (EINVAL); 162 163 bcopy(cp, *bufp, xlen); 164 (*bufp)[xlen] = '\n'; 165 (*bufp)[xlen+1] = '\0'; 166 break; 167 } 168 169 case KTT_AVENRUN: 170 averunnable.fscale = FSCALE; 171 sprintf(*bufp, "%ld %ld %ld %ld\n", 172 averunnable.ldavg[0], averunnable.ldavg[1], 173 averunnable.ldavg[2], averunnable.fscale); 174 break; 175 176 default: 177 return (0); 178 } 179 180 len = strlen(*bufp); 181 if (len <= off) 182 return (0); 183 *bufp += off; 184 return (len - off); 185 } 186 187 int 188 kernfs_xwrite(kt, buf, len) 189 struct kern_target *kt; 190 char *buf; 191 int len; 192 { 193 194 switch (kt->kt_tag) { 195 case KTT_HOSTNAME: 196 if (buf[len-1] == '\n') 197 --len; 198 bcopy(buf, hostname, len); 199 hostname[len] = '\0'; 200 hostnamelen = len; 201 return (0); 202 203 default: 204 return (EIO); 205 } 206 } 207 208 209 /* 210 * vp is the current namei directory 211 * ndp is the name to locate in that directory... 212 */ 213 kernfs_lookup(ap) 214 struct vop_lookup_args /* { 215 struct vnode * a_dvp; 216 struct vnode ** a_vpp; 217 struct componentname * a_cnp; 218 } */ *ap; 219 { 220 struct componentname *cnp = ap->a_cnp; 221 struct vnode **vpp = ap->a_vpp; 222 struct vnode *dvp = ap->a_dvp; 223 char *pname = cnp->cn_nameptr; 224 struct kern_target *kt; 225 struct vnode *fvp; 226 int error, i; 227 228 #ifdef KERNFS_DIAGNOSTIC 229 printf("kernfs_lookup(%x)\n", ap); 230 printf("kernfs_lookup(dp = %x, vpp = %x, cnp = %x)\n", dvp, vpp, ap->a_cnp); 231 printf("kernfs_lookup(%s)\n", pname); 232 #endif 233 234 *vpp = NULLVP; 235 236 if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME) 237 return (EROFS); 238 239 if (cnp->cn_namelen == 1 && *pname == '.') { 240 *vpp = dvp; 241 VREF(dvp); 242 /*VOP_LOCK(dvp);*/ 243 return (0); 244 } 245 246 #if 0 247 if (cnp->cn_namelen == 4 && bcmp(pname, "root", 4) == 0) { 248 *vpp = rootdir; 249 VREF(rootdir); 250 VOP_LOCK(rootdir); 251 return (0); 252 } 253 #endif 254 255 for (kt = kern_targets, i = 0; i < nkern_targets; kt++, i++) { 256 if (cnp->cn_namelen == kt->kt_namlen && 257 bcmp(kt->kt_name, pname, cnp->cn_namelen) == 0) 258 goto found; 259 } 260 261 #ifdef KERNFS_DIAGNOSTIC 262 printf("kernfs_lookup: i = %d, failed", i); 263 #endif 264 265 return (cnp->cn_nameiop == LOOKUP ? ENOENT : EROFS); 266 267 found: 268 if (kt->kt_tag == KTT_DEVICE) { 269 dev_t *dp = kt->kt_data; 270 loop: 271 if (*dp == NODEV || !vfinddev(*dp, kt->kt_vtype, &fvp)) 272 return (ENOENT); 273 *vpp = fvp; 274 if (vget(fvp, 1)) 275 goto loop; 276 return (0); 277 } 278 279 #ifdef KERNFS_DIAGNOSTIC 280 printf("kernfs_lookup: allocate new vnode\n"); 281 #endif 282 if (error = getnewvnode(VT_KERNFS, dvp->v_mount, kernfs_vnodeop_p, 283 &fvp)) 284 return (error); 285 286 MALLOC(fvp->v_data, void *, sizeof(struct kernfs_node), M_TEMP, 287 M_WAITOK); 288 VTOKERN(fvp)->kf_kt = kt; 289 fvp->v_type = kt->kt_vtype; 290 *vpp = fvp; 291 292 #ifdef KERNFS_DIAGNOSTIC 293 printf("kernfs_lookup: newvp = %x\n", fvp); 294 #endif 295 return (0); 296 } 297 298 kernfs_open(ap) 299 struct vop_open_args /* { 300 struct vnode *a_vp; 301 int a_mode; 302 struct ucred *a_cred; 303 struct proc *a_p; 304 } */ *ap; 305 { 306 307 /* Only need to check access permissions. */ 308 return (0); 309 } 310 311 int 312 kernfs_access(ap) 313 struct vop_access_args /* { 314 struct vnode *a_vp; 315 int a_mode; 316 struct ucred *a_cred; 317 struct proc *a_p; 318 } */ *ap; 319 { 320 struct vnode *vp = ap->a_vp; 321 mode_t fmode = 322 (vp->v_flag & VROOT) ? DIR_MODE : VTOKERN(vp)->kf_kt->kt_mode; 323 324 return (vaccess(fmode, (uid_t)0, (gid_t)0, ap->a_mode, ap->a_cred)); 325 } 326 327 kernfs_getattr(ap) 328 struct vop_getattr_args /* { 329 struct vnode *a_vp; 330 struct vattr *a_vap; 331 struct ucred *a_cred; 332 struct proc *a_p; 333 } */ *ap; 334 { 335 struct vnode *vp = ap->a_vp; 336 struct vattr *vap = ap->a_vap; 337 int error = 0; 338 char strbuf[KSTRING], *buf; 339 340 bzero((caddr_t) vap, sizeof(*vap)); 341 vattr_null(vap); 342 vap->va_uid = 0; 343 vap->va_gid = 0; 344 vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0]; 345 vap->va_size = 0; 346 vap->va_blocksize = DEV_BSIZE; 347 microtime(&vap->va_atime); 348 vap->va_mtime = vap->va_atime; 349 vap->va_ctime = vap->va_ctime; 350 vap->va_gen = 0; 351 vap->va_flags = 0; 352 vap->va_rdev = 0; 353 vap->va_bytes = 0; 354 355 if (vp->v_flag & VROOT) { 356 #ifdef KERNFS_DIAGNOSTIC 357 printf("kernfs_getattr: stat rootdir\n"); 358 #endif 359 vap->va_type = VDIR; 360 vap->va_mode = DIR_MODE; 361 vap->va_nlink = 2; 362 vap->va_fileid = 2; 363 vap->va_size = DEV_BSIZE; 364 } else { 365 struct kern_target *kt = VTOKERN(vp)->kf_kt; 366 int nbytes, total; 367 #ifdef KERNFS_DIAGNOSTIC 368 printf("kernfs_getattr: stat target %s\n", kt->kt_name); 369 #endif 370 vap->va_type = kt->kt_vtype; 371 vap->va_mode = kt->kt_mode; 372 vap->va_nlink = 1; 373 vap->va_fileid = 1 + (kt - kern_targets) / sizeof(*kt); 374 total = 0; 375 while (buf = strbuf, 376 nbytes = kernfs_xread(kt, total, &buf, sizeof(strbuf))) 377 total += nbytes; 378 vap->va_size = total; 379 } 380 381 #ifdef KERNFS_DIAGNOSTIC 382 printf("kernfs_getattr: return error %d\n", error); 383 #endif 384 return (error); 385 } 386 387 kernfs_setattr(ap) 388 struct vop_setattr_args /* { 389 struct vnode *a_vp; 390 struct vattr *a_vap; 391 struct ucred *a_cred; 392 struct proc *a_p; 393 } */ *ap; 394 { 395 396 /* 397 * Silently ignore attribute changes. 398 * This allows for open with truncate to have no 399 * effect until some data is written. I want to 400 * do it this way because all writes are atomic. 401 */ 402 return (0); 403 } 404 405 int 406 kernfs_read(ap) 407 struct vop_read_args /* { 408 struct vnode *a_vp; 409 struct uio *a_uio; 410 int a_ioflag; 411 struct ucred *a_cred; 412 } */ *ap; 413 { 414 struct vnode *vp = ap->a_vp; 415 struct uio *uio = ap->a_uio; 416 struct kern_target *kt; 417 char strbuf[KSTRING], *buf; 418 int off, len; 419 int error; 420 421 if (vp->v_type == VDIR) 422 return (EOPNOTSUPP); 423 424 kt = VTOKERN(vp)->kf_kt; 425 426 #ifdef KERNFS_DIAGNOSTIC 427 printf("kern_read %s\n", kt->kt_name); 428 #endif 429 430 off = uio->uio_offset; 431 #if 0 432 while (buf = strbuf, 433 #else 434 if (buf = strbuf, 435 #endif 436 len = kernfs_xread(kt, off, &buf, sizeof(strbuf))) { 437 if (error = uiomove(buf, len, uio)) 438 return (error); 439 off += len; 440 } 441 return (0); 442 } 443 444 int 445 kernfs_write(ap) 446 struct vop_write_args /* { 447 struct vnode *a_vp; 448 struct uio *a_uio; 449 int a_ioflag; 450 struct ucred *a_cred; 451 } */ *ap; 452 { 453 struct vnode *vp = ap->a_vp; 454 struct uio *uio = ap->a_uio; 455 struct kern_target *kt; 456 int error, xlen; 457 char strbuf[KSTRING]; 458 459 if (vp->v_type == VDIR) 460 return (EOPNOTSUPP); 461 462 kt = VTOKERN(vp)->kf_kt; 463 464 if (uio->uio_offset != 0) 465 return (EINVAL); 466 467 xlen = min(uio->uio_resid, KSTRING-1); 468 if (error = uiomove(strbuf, xlen, uio)) 469 return (error); 470 471 if (uio->uio_resid != 0) 472 return (EIO); 473 474 strbuf[xlen] = '\0'; 475 xlen = strlen(strbuf); 476 return (kernfs_xwrite(kt, strbuf, xlen)); 477 } 478 479 kernfs_readdir(ap) 480 struct vop_readdir_args /* { 481 struct vnode *a_vp; 482 struct uio *a_uio; 483 struct ucred *a_cred; 484 int *a_eofflag; 485 u_long *a_cookies; 486 int a_ncookies; 487 } */ *ap; 488 { 489 struct uio *uio = ap->a_uio; 490 struct kern_target *kt; 491 struct dirent d; 492 int i; 493 int error; 494 495 if (ap->a_vp->v_type != VDIR) 496 return (ENOTDIR); 497 498 /* 499 * We don't allow exporting kernfs mounts, and currently local 500 * requests do not need cookies. 501 */ 502 if (ap->a_ncookies != NULL) 503 panic("kernfs_readdir: not hungry"); 504 505 i = uio->uio_offset / UIO_MX; 506 error = 0; 507 for (kt = &kern_targets[i]; 508 uio->uio_resid >= UIO_MX && i < nkern_targets; kt++, i++) { 509 struct dirent *dp = &d; 510 #ifdef KERNFS_DIAGNOSTIC 511 printf("kernfs_readdir: i = %d\n", i); 512 #endif 513 514 if (kt->kt_tag == KTT_DEVICE) { 515 dev_t *dp = kt->kt_data; 516 struct vnode *fvp; 517 518 if (*dp == NODEV || !vfinddev(*dp, kt->kt_vtype, &fvp)) 519 continue; 520 } 521 522 bzero((caddr_t)dp, UIO_MX); 523 dp->d_namlen = kt->kt_namlen; 524 bcopy(kt->kt_name, dp->d_name, kt->kt_namlen+1); 525 526 #ifdef KERNFS_DIAGNOSTIC 527 printf("kernfs_readdir: name = %s, len = %d\n", 528 dp->d_name, dp->d_namlen); 529 #endif 530 /* 531 * Fill in the remaining fields 532 */ 533 dp->d_reclen = UIO_MX; 534 dp->d_fileno = i + 3; 535 dp->d_type = kt->kt_type; 536 /* 537 * And ship to userland 538 */ 539 if (error = uiomove((caddr_t)dp, UIO_MX, uio)) 540 break; 541 } 542 543 uio->uio_offset = i * UIO_MX; 544 545 return (error); 546 } 547 548 kernfs_inactive(ap) 549 struct vop_inactive_args /* { 550 struct vnode *a_vp; 551 } */ *ap; 552 { 553 struct vnode *vp = ap->a_vp; 554 555 #ifdef KERNFS_DIAGNOSTIC 556 printf("kernfs_inactive(%x)\n", vp); 557 #endif 558 /* 559 * Clear out the v_type field to avoid 560 * nasty things happening in vgone(). 561 */ 562 vp->v_type = VNON; 563 return (0); 564 } 565 566 kernfs_reclaim(ap) 567 struct vop_reclaim_args /* { 568 struct vnode *a_vp; 569 } */ *ap; 570 { 571 struct vnode *vp = ap->a_vp; 572 573 #ifdef KERNFS_DIAGNOSTIC 574 printf("kernfs_reclaim(%x)\n", vp); 575 #endif 576 if (vp->v_data) { 577 FREE(vp->v_data, M_TEMP); 578 vp->v_data = 0; 579 } 580 return (0); 581 } 582 583 /* 584 * Return POSIX pathconf information applicable to special devices. 585 */ 586 kernfs_pathconf(ap) 587 struct vop_pathconf_args /* { 588 struct vnode *a_vp; 589 int a_name; 590 register_t *a_retval; 591 } */ *ap; 592 { 593 594 switch (ap->a_name) { 595 case _PC_LINK_MAX: 596 *ap->a_retval = LINK_MAX; 597 return (0); 598 case _PC_MAX_CANON: 599 *ap->a_retval = MAX_CANON; 600 return (0); 601 case _PC_MAX_INPUT: 602 *ap->a_retval = MAX_INPUT; 603 return (0); 604 case _PC_PIPE_BUF: 605 *ap->a_retval = PIPE_BUF; 606 return (0); 607 case _PC_CHOWN_RESTRICTED: 608 *ap->a_retval = 1; 609 return (0); 610 case _PC_VDISABLE: 611 *ap->a_retval = _POSIX_VDISABLE; 612 return (0); 613 default: 614 return (EINVAL); 615 } 616 /* NOTREACHED */ 617 } 618 619 /* 620 * Print out the contents of a /dev/fd vnode. 621 */ 622 /* ARGSUSED */ 623 kernfs_print(ap) 624 struct vop_print_args /* { 625 struct vnode *a_vp; 626 } */ *ap; 627 { 628 629 printf("tag VT_KERNFS, kernfs vnode\n"); 630 return (0); 631 } 632 633 /*void*/ 634 kernfs_vfree(ap) 635 struct vop_vfree_args /* { 636 struct vnode *a_pvp; 637 ino_t a_ino; 638 int a_mode; 639 } */ *ap; 640 { 641 642 return (0); 643 } 644 645 /* 646 * /dev/fd vnode unsupported operation 647 */ 648 kernfs_enotsupp() 649 { 650 651 return (EOPNOTSUPP); 652 } 653 654 /* 655 * /dev/fd "should never get here" operation 656 */ 657 kernfs_badop() 658 { 659 660 panic("kernfs: bad op"); 661 /* NOTREACHED */ 662 } 663 664 /* 665 * kernfs vnode null operation 666 */ 667 kernfs_nullop() 668 { 669 670 return (0); 671 } 672 673 #define kernfs_create ((int (*) __P((struct vop_create_args *)))kernfs_enotsupp) 674 #define kernfs_mknod ((int (*) __P((struct vop_mknod_args *)))kernfs_enotsupp) 675 #define kernfs_close ((int (*) __P((struct vop_close_args *)))nullop) 676 #define kernfs_ioctl ((int (*) __P((struct vop_ioctl_args *)))kernfs_enotsupp) 677 #define kernfs_select ((int (*) __P((struct vop_select_args *)))kernfs_enotsupp) 678 #define kernfs_mmap ((int (*) __P((struct vop_mmap_args *)))kernfs_enotsupp) 679 #define kernfs_fsync ((int (*) __P((struct vop_fsync_args *)))nullop) 680 #define kernfs_seek ((int (*) __P((struct vop_seek_args *)))nullop) 681 #define kernfs_remove ((int (*) __P((struct vop_remove_args *)))kernfs_enotsupp) 682 #define kernfs_link ((int (*) __P((struct vop_link_args *)))kernfs_enotsupp) 683 #define kernfs_rename ((int (*) __P((struct vop_rename_args *)))kernfs_enotsupp) 684 #define kernfs_mkdir ((int (*) __P((struct vop_mkdir_args *)))kernfs_enotsupp) 685 #define kernfs_rmdir ((int (*) __P((struct vop_rmdir_args *)))kernfs_enotsupp) 686 #define kernfs_symlink ((int (*) __P((struct vop_symlink_args *)))kernfs_enotsupp) 687 #define kernfs_readlink \ 688 ((int (*) __P((struct vop_readlink_args *)))kernfs_enotsupp) 689 #define kernfs_abortop ((int (*) __P((struct vop_abortop_args *)))nullop) 690 #define kernfs_lock ((int (*) __P((struct vop_lock_args *)))nullop) 691 #define kernfs_unlock ((int (*) __P((struct vop_unlock_args *)))nullop) 692 #define kernfs_bmap ((int (*) __P((struct vop_bmap_args *)))kernfs_badop) 693 #define kernfs_strategy ((int (*) __P((struct vop_strategy_args *)))kernfs_badop) 694 #define kernfs_islocked ((int (*) __P((struct vop_islocked_args *)))nullop) 695 #define kernfs_advlock ((int (*) __P((struct vop_advlock_args *)))kernfs_enotsupp) 696 #define kernfs_blkatoff \ 697 ((int (*) __P((struct vop_blkatoff_args *)))kernfs_enotsupp) 698 #define kernfs_valloc ((int(*) __P(( \ 699 struct vnode *pvp, \ 700 int mode, \ 701 struct ucred *cred, \ 702 struct vnode **vpp))) kernfs_enotsupp) 703 #define kernfs_truncate \ 704 ((int (*) __P((struct vop_truncate_args *)))kernfs_enotsupp) 705 #define kernfs_update ((int (*) __P((struct vop_update_args *)))kernfs_enotsupp) 706 #define kernfs_bwrite ((int (*) __P((struct vop_bwrite_args *)))kernfs_enotsupp) 707 708 int (**kernfs_vnodeop_p)(); 709 struct vnodeopv_entry_desc kernfs_vnodeop_entries[] = { 710 { &vop_default_desc, vn_default_error }, 711 { &vop_lookup_desc, kernfs_lookup }, /* lookup */ 712 { &vop_create_desc, kernfs_create }, /* create */ 713 { &vop_mknod_desc, kernfs_mknod }, /* mknod */ 714 { &vop_open_desc, kernfs_open }, /* open */ 715 { &vop_close_desc, kernfs_close }, /* close */ 716 { &vop_access_desc, kernfs_access }, /* access */ 717 { &vop_getattr_desc, kernfs_getattr }, /* getattr */ 718 { &vop_setattr_desc, kernfs_setattr }, /* setattr */ 719 { &vop_read_desc, kernfs_read }, /* read */ 720 { &vop_write_desc, kernfs_write }, /* write */ 721 { &vop_ioctl_desc, kernfs_ioctl }, /* ioctl */ 722 { &vop_select_desc, kernfs_select }, /* select */ 723 { &vop_mmap_desc, kernfs_mmap }, /* mmap */ 724 { &vop_fsync_desc, kernfs_fsync }, /* fsync */ 725 { &vop_seek_desc, kernfs_seek }, /* seek */ 726 { &vop_remove_desc, kernfs_remove }, /* remove */ 727 { &vop_link_desc, kernfs_link }, /* link */ 728 { &vop_rename_desc, kernfs_rename }, /* rename */ 729 { &vop_mkdir_desc, kernfs_mkdir }, /* mkdir */ 730 { &vop_rmdir_desc, kernfs_rmdir }, /* rmdir */ 731 { &vop_symlink_desc, kernfs_symlink }, /* symlink */ 732 { &vop_readdir_desc, kernfs_readdir }, /* readdir */ 733 { &vop_readlink_desc, kernfs_readlink },/* readlink */ 734 { &vop_abortop_desc, kernfs_abortop }, /* abortop */ 735 { &vop_inactive_desc, kernfs_inactive },/* inactive */ 736 { &vop_reclaim_desc, kernfs_reclaim }, /* reclaim */ 737 { &vop_lock_desc, kernfs_lock }, /* lock */ 738 { &vop_unlock_desc, kernfs_unlock }, /* unlock */ 739 { &vop_bmap_desc, kernfs_bmap }, /* bmap */ 740 { &vop_strategy_desc, kernfs_strategy },/* strategy */ 741 { &vop_print_desc, kernfs_print }, /* print */ 742 { &vop_islocked_desc, kernfs_islocked },/* islocked */ 743 { &vop_pathconf_desc, kernfs_pathconf },/* pathconf */ 744 { &vop_advlock_desc, kernfs_advlock }, /* advlock */ 745 { &vop_blkatoff_desc, kernfs_blkatoff },/* blkatoff */ 746 { &vop_valloc_desc, kernfs_valloc }, /* valloc */ 747 { &vop_vfree_desc, kernfs_vfree }, /* vfree */ 748 { &vop_truncate_desc, kernfs_truncate },/* truncate */ 749 { &vop_update_desc, kernfs_update }, /* update */ 750 { &vop_bwrite_desc, kernfs_bwrite }, /* bwrite */ 751 { (struct vnodeop_desc*)NULL, (int(*)())NULL } 752 }; 753 struct vnodeopv_desc kernfs_vnodeop_opv_desc = 754 { &kernfs_vnodeop_p, kernfs_vnodeop_entries }; 755