1 /* 2 * Copyright (c) 1990, 1992 Jan-Simon Pendry 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Jan-Simon Pendry. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * $Id: kernfs_vnops.c,v 1.13 1993/11/20 01:57:07 cgd Exp $ 37 */ 38 39 /* 40 * Kernel parameter filesystem 41 */ 42 43 #include "param.h" 44 #include "systm.h" 45 #include "kernel.h" 46 #include "types.h" 47 #include "time.h" 48 #include "proc.h" 49 #include "file.h" 50 #include "vnode.h" 51 #include "stat.h" 52 #include "mount.h" 53 #include "namei.h" 54 #include "buf.h" 55 #include "miscfs/kernfs/kernfs.h" 56 57 #include "../ufs/dir.h" /* For readdir() XXX */ 58 59 struct kernfs_target kernfs_targets[] = { 60 /* NOTE: The name must be less than UIO_MX-16 chars in length */ 61 DIR_TARGET(".", 0, KTT_NULL, KTM_DIR_PERMS ) 62 DIR_TARGET("..", 0, KTT_NULL, KTM_DIR_PERMS ) 63 REG_TARGET("copyright", copyright, KTT_STRING, KTM_RO_PERMS ) 64 REG_TARGET("hostname", 0, KTT_HOSTNAME, KTM_RW_PERMS ) 65 REG_TARGET("hz", &hz, KTT_INT, KTM_RO_PERMS ) 66 REG_TARGET("loadavg", 0, KTT_AVENRUN, KTM_RO_PERMS ) 67 REG_TARGET("physmem", &physmem, KTT_INT, KTM_RO_PERMS ) 68 #ifdef KERNFS_HAVE_ROOTDIR 69 DIR_TARGET("root", 0, KTT_NULL, KTM_DIR_PERMS ) 70 #endif 71 BLK_TARGET("rootdev", 0, KTT_NULL, KTM_RO_PERMS ) 72 CHR_TARGET("rrootdev", 0, KTT_NULL, KTM_RO_PERMS ) 73 REG_TARGET("time", 0, KTT_TIME, KTM_RO_PERMS ) 74 REG_TARGET("version", version, KTT_STRING, KTM_RO_PERMS ) 75 }; 76 77 static int nkernfs_targets = sizeof(kernfs_targets) / sizeof(kernfs_targets[0]); 78 79 static int 80 kernfs_xread(kt, buf, len, lenp) 81 struct kernfs_target *kt; 82 char *buf; 83 int len; 84 int *lenp; 85 { 86 int xlen; 87 88 switch (kt->kt_tag) { 89 case KTT_TIME: { 90 struct timeval tv; 91 microtime(&tv); 92 sprintf(buf, "%d %d\n", tv.tv_sec, tv.tv_usec); 93 break; 94 } 95 96 case KTT_INT: { 97 int *ip = kt->kt_data; 98 sprintf(buf, "%d\n", *ip); 99 break; 100 } 101 102 case KTT_STRING: { 103 char *cp = kt->kt_data; 104 int xlen = strlen(cp) + 1; 105 106 if (xlen >= len) 107 return (EINVAL); 108 109 bcopy(cp, buf, xlen); 110 break; 111 } 112 113 case KTT_HOSTNAME: { 114 char *cp = hostname; 115 int xlen = hostnamelen; 116 117 if (xlen + 2 > len) /* extra space for null and newline */ 118 return (EINVAL); 119 120 bcopy(cp, buf, xlen); /* safer than sprintf */ 121 buf[xlen] = '\n'; 122 buf[xlen+1] = '\0'; 123 break; 124 } 125 126 case KTT_AVENRUN: 127 sprintf(buf, "%d %d %d %d\n", 128 averunnable[0], 129 averunnable[1], 130 averunnable[2], 131 FSCALE); 132 break; 133 134 default: 135 return (EINVAL); 136 } 137 138 *lenp = strlen(buf); 139 return (0); 140 } 141 142 static int 143 kernfs_xwrite(kt, buf, len) 144 struct kernfs_target *kt; 145 char *buf; 146 int len; 147 { 148 switch (kt->kt_tag) { 149 case KTT_HOSTNAME: { 150 if (buf[len-1] == '\n') 151 --len; 152 bcopy(buf, hostname, len); 153 /* kernfs_write set buf[value_passed_as_len] = \0. 154 * therefore, buf len (hostnamelen) = len. 155 */ 156 hostnamelen = len; 157 hostname[hostnamelen] = '\0'; /* null end of string. */ 158 return (0); 159 } 160 161 default: 162 return (EIO); 163 } 164 } 165 166 /* 167 * vp is the current namei directory 168 * ndp is the name to locate in that directory... 169 */ 170 kernfs_lookup(dvp, ndp, p) 171 struct vnode *dvp; 172 struct nameidata *ndp; 173 struct proc *p; 174 { 175 char *pname = ndp->ni_ptr; 176 int error = ENOENT; 177 int i; 178 struct vnode *fvp; 179 180 #ifdef KERNFS_DIAGNOSTIC 181 printf("kernfs_lookup(%s)\n", pname); 182 #endif 183 if (ndp->ni_namelen == 1 && *pname == '.') { 184 ndp->ni_dvp = dvp; 185 ndp->ni_vp = dvp; 186 VREF(dvp); 187 /*VOP_LOCK(dvp);*/ 188 return (0); 189 } 190 191 #ifdef KERNFS_HAVE_ROOTDIR 192 if (ndp->ni_namelen == 4 && bcmp(pname, "root", 4) == 0) { 193 ndp->ni_dvp = dvp; 194 ndp->ni_vp = rootdir; 195 VREF(rootdir); 196 VOP_LOCK(rootdir); 197 return (0); 198 } 199 #endif 200 201 /* 202 * /kern/rootdev is the root device 203 */ 204 if (ndp->ni_namelen == 7 && bcmp(pname, "rootdev", 7) == 0) { 205 if (vfinddev(rootdev, VBLK, &fvp)) 206 return (ENXIO); 207 ndp->ni_dvp = dvp; 208 ndp->ni_vp = fvp; 209 VREF(fvp); 210 VOP_LOCK(fvp); 211 return (0); 212 } 213 214 /* 215 * /kern/rrootdev is the root device 216 */ 217 if (ndp->ni_namelen == 8 && bcmp(pname, "rrootdev", 7) == 0) { 218 ndp->ni_dvp = dvp; 219 ndp->ni_vp = rrootdevvp; 220 VREF(rrootdevvp); 221 VOP_LOCK(rrootdevvp); 222 return (0); 223 } 224 225 for (i = 0; i < nkernfs_targets; i++) { 226 struct kernfs_target *kt = &kernfs_targets[i]; 227 if (ndp->ni_namelen == strlen(kt->kt_name) && 228 bcmp(kt->kt_name, pname, ndp->ni_namelen) == 0) { 229 error = 0; 230 break; 231 } 232 } 233 234 #ifdef KERNFS_DIAGNOSTIC 235 printf("kernfs_lookup: i = %d, error = %d\n", i, error); 236 #endif 237 238 if (error) 239 goto bad; 240 241 #ifdef KERNFS_DIAGNOSTIC 242 printf("kernfs_lookup: allocate new vnode\n"); 243 #endif 244 error = getnewvnode(VT_KERNFS, dvp->v_mount, &kernfs_vnodeops, &fvp); 245 if (error) 246 goto bad; 247 VTOKERN(fvp)->kf_kt = &kernfs_targets[i]; 248 fvp->v_type = VTOKERN(fvp)->kf_kt->kt_vtype; 249 ndp->ni_dvp = dvp; 250 ndp->ni_vp = fvp; 251 #ifdef KERNFS_DIAGNOSTIC 252 printf("kernfs_lookup: newvp = %x\n", fvp); 253 #endif 254 return (0); 255 256 bad:; 257 ndp->ni_dvp = dvp; 258 ndp->ni_vp = NULL; 259 #ifdef KERNFS_DIAGNOSTIC 260 printf("kernfs_lookup: error = %d\n", error); 261 #endif 262 return (error); 263 } 264 265 kernfs_open(vp, mode, cred, p) 266 struct vnode *vp; 267 int mode; 268 struct ucred *cred; 269 struct proc *p; 270 { 271 /* if access succeeded, this always does, too */ 272 273 return (0); 274 } 275 276 /* 277 * Check mode permission on target pointer. Mode is READ, WRITE or EXEC. 278 * The mode is shifted to select the owner/group/other fields. The 279 * super user is granted all permissions. 280 */ 281 kernfs_access(vp, mode, cred, p) 282 struct vnode *vp; 283 register int mode; 284 struct ucred *cred; 285 struct proc *p; 286 { 287 struct kernfs_target *kt = VTOKERN(vp)->kf_kt; 288 register gid_t *gp; 289 int i, error; 290 291 #ifdef KERN_DIAGNOSTIC 292 if (!VOP_ISLOCKED(vp)) { 293 vprint("kernfs_access: not locked", vp); 294 panic("kernfs_access: not locked"); 295 } 296 #endif 297 /* 298 * If you're the super-user, you always get access. 299 */ 300 if (cred->cr_uid == 0) 301 return (0); 302 /* 303 * Access check is based on only one of owner, group, public. 304 * If not owner, then check group. If not a member of the 305 * group, then check public access. 306 */ 307 if (cred->cr_uid != /* kt->kt_uid XXX */ 0) { 308 mode >>= 3; 309 gp = cred->cr_groups; 310 for (i = 0; i < cred->cr_ngroups; i++, gp++) 311 if (/* kt->kt_gid XXX */ 0 == *gp) 312 goto found; 313 mode >>= 3; 314 found: 315 ; 316 } 317 if ((kt->kt_perms & mode) == mode) 318 return (0); 319 return (EACCES); 320 } 321 322 kernfs_getattr(vp, vap, cred, p) 323 struct vnode *vp; 324 struct vattr *vap; 325 struct ucred *cred; 326 struct proc *p; 327 { 328 int error = 0; 329 char strbuf[KSTRING]; 330 struct kernfs_target *kt = VTOKERN(vp)->kf_kt; 331 332 bzero((caddr_t) vap, sizeof(*vap)); 333 vattr_null(vap); 334 vap->va_uid = kt->kt_uid; 335 vap->va_gid = kt->kt_gid; 336 vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0]; 337 /* vap->va_qsize = 0; */ 338 vap->va_blocksize = DEV_BSIZE; 339 microtime(&vap->va_atime); 340 vap->va_mtime = vap->va_atime; 341 vap->va_ctime = vap->va_ctime; 342 vap->va_gen = 0; 343 vap->va_flags = 0; 344 vap->va_rdev = 0; 345 /* vap->va_qbytes = 0; */ 346 vap->va_bytes = 0; 347 vap->va_type = kt->kt_vtype; 348 vap->va_mode = kt->kt_perms; 349 350 if (vp->v_flag & VROOT) { 351 #ifdef KERNFS_DIAGNOSTIC 352 printf("kernfs_getattr: stat rootdir\n"); 353 #endif 354 vap->va_nlink = 2; 355 vap->va_fileid = 2; 356 vap->va_size = DEV_BSIZE; 357 } else { 358 #ifdef KERNFS_DIAGNOSTIC 359 printf("kernfs_getattr: stat target %s\n", kt->kt_name); 360 #endif 361 vap->va_nlink = 1; 362 vap->va_fileid = 3 + (kt - kernfs_targets) / sizeof(*kt); 363 error = kernfs_xread(kt, strbuf, sizeof(strbuf), &vap->va_size); 364 } 365 366 vp->v_type = vap->va_type; 367 #ifdef KERNFS_DIAGNOSTIC 368 printf("kernfs_getattr: return error %d\n", error); 369 #endif 370 return (error); 371 } 372 373 374 /* 375 * Change the mode on a file. 376 */ 377 kernfs_chmod1(vp, mode, p) 378 register struct vnode *vp; 379 register int mode; 380 struct proc *p; 381 { 382 register struct ucred *cred = p->p_ucred; 383 register struct kernfs_target *kt = VTOKERN(vp)->kf_kt; 384 int error; 385 386 if ((mode & kt->kt_maxperms) != mode) /* can't set ro var to rw */ 387 return (EPERM); 388 389 if (cred->cr_uid != kt->kt_uid && 390 (error = suser(cred, &p->p_acflag))) 391 return (error); 392 if (cred->cr_uid) { 393 if (vp->v_type != VDIR && (mode & S_ISVTX)) 394 return (EFTYPE); 395 if (!groupmember(kt->kt_gid, cred) && (mode & S_ISGID)) 396 return (EPERM); 397 } 398 kt->kt_perms &= ~07777; 399 kt->kt_perms |= mode & 07777; 400 /* ip->i_flag |= ICHG;*/ 401 return (0); 402 } 403 404 /* 405 * Perform chown operation on kernfs_target kt 406 */ 407 kernfs_chown1(vp, uid, gid, p) 408 register struct vnode *vp; 409 uid_t uid; 410 gid_t gid; 411 struct proc *p; 412 { 413 register struct kernfs_target *kt = VTOKERN(vp)->kf_kt; 414 register struct ucred *cred = p->p_ucred; 415 uid_t ouid; 416 gid_t ogid; 417 int error = 0; 418 419 if (uid == (u_short)VNOVAL) 420 uid = kt->kt_uid; 421 if (gid == (u_short)VNOVAL) 422 gid = kt->kt_gid; 423 /* 424 * If we don't own the file, are trying to change the owner 425 * of the file, or are not a member of the target group, 426 * the caller must be superuser or the call fails. 427 */ 428 if ((cred->cr_uid != kt->kt_uid || uid != kt->kt_uid || 429 !groupmember((gid_t)gid, cred)) && 430 (error = suser(cred, &p->p_acflag))) 431 return (error); 432 ouid = kt->kt_uid; 433 ogid = kt->kt_gid; 434 435 kt->kt_uid = uid; 436 kt->kt_gid = gid; 437 438 /* if (ouid != uid || ogid != gid) 439 ip->i_flag |= ICHG;*/ 440 if (ouid != uid && cred->cr_uid != 0) 441 kt->kt_perms &= ~S_ISUID; 442 if (ogid != gid && cred->cr_uid != 0) 443 kt->kt_perms &= ~S_ISGID; 444 return (0); 445 } 446 447 /* 448 * Set attribute vnode op. called from several syscalls 449 */ 450 kernfs_setattr(vp, vap, cred, p) 451 struct vnode *vp; 452 struct vattr *vap; 453 struct ucred *cred; 454 struct proc *p; 455 { 456 int error = 0; 457 458 /* 459 * Check for unsetable attributes. 460 */ 461 if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) || 462 (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) || 463 (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) || 464 ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) { 465 return (EINVAL); 466 } 467 /* 468 * Go through the fields and update iff not VNOVAL. 469 */ 470 if (vap->va_uid != (u_short)VNOVAL || vap->va_gid != (u_short)VNOVAL) 471 if (error = kernfs_chown1(vp, vap->va_uid, vap->va_gid, p)) 472 return (error); 473 if (vap->va_size != VNOVAL) { 474 if (vp->v_type == VDIR) 475 return (EISDIR); 476 /* else just nod and smile... */ 477 } 478 if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) { 479 /* if (cred->cr_uid != ip->i_uid && 480 (error = suser(cred, &p->p_acflag))) 481 return (error); 482 if (vap->va_atime.tv_sec != VNOVAL) 483 ip->i_flag |= IACC; 484 if (vap->va_mtime.tv_sec != VNOVAL) 485 ip->i_flag |= IUPD; 486 ip->i_flag |= ICHG; 487 if (error = iupdat(ip, &vap->va_atime, &vap->va_mtime, 1)) 488 return (error); 489 */ 490 } 491 if (vap->va_mode != (u_short)VNOVAL) 492 error = kernfs_chmod1(vp, (int)vap->va_mode, p); 493 if (vap->va_flags != VNOVAL) { 494 /* if (cred->cr_uid != ip->i_uid && 495 (error = suser(cred, &p->p_acflag))) 496 return (error); 497 if (cred->cr_uid == 0) { 498 ip->i_flags = vap->va_flags; 499 } else { 500 ip->i_flags &= 0xffff0000; 501 ip->i_flags |= (vap->va_flags & 0xffff); 502 } 503 ip->i_flag |= ICHG; 504 */ 505 } 506 return (error); 507 } 508 509 static int 510 kernfs_read(vp, uio, ioflag, cred) 511 struct vnode *vp; 512 struct uio *uio; 513 int ioflag; 514 struct ucred *cred; 515 { 516 struct kernfs_target *kt = VTOKERN(vp)->kf_kt; 517 char strbuf[KSTRING]; 518 int off = uio->uio_offset; 519 int len = 0; 520 char *cp = strbuf; 521 int error; 522 #ifdef KERNFS_DIAGNOSTIC 523 printf("kern_read %s\n", kt->kt_name); 524 #endif 525 526 error = kernfs_xread(kt, strbuf, sizeof(strbuf), &len); 527 if (error) 528 return (error); 529 cp = strbuf + off; 530 len -= off; 531 return (uiomove(cp, len, uio)); 532 } 533 534 static int 535 kernfs_write(vp, uio, ioflag, cred) 536 struct vnode *vp; 537 struct uio *uio; 538 int ioflag; 539 struct ucred *cred; 540 { 541 struct kernfs_target *kt = VTOKERN(vp)->kf_kt; 542 char strbuf[KSTRING]; 543 int len = uio->uio_resid; 544 char *cp = strbuf; 545 int xlen; 546 int error; 547 548 if (uio->uio_offset != 0) 549 return (EINVAL); 550 551 xlen = min(uio->uio_resid, KSTRING-1); 552 error = uiomove(strbuf, xlen, uio); 553 if (error) 554 return (error); 555 556 if (uio->uio_resid != 0) 557 return (EIO); 558 559 strbuf[xlen] = '\0'; 560 return (kernfs_xwrite(kt, strbuf, xlen)); 561 } 562 563 kernfs_readdir(vp, uio, cred, eofflagp, cookies, ncookies) 564 struct vnode *vp; 565 struct uio *uio; 566 struct ucred *cred; 567 int *eofflagp; 568 u_int *cookies; 569 int ncookies; 570 { 571 struct filedesc *fdp; 572 int i; 573 int error; 574 575 i = uio->uio_offset / UIO_MX; 576 error = 0; 577 while (uio->uio_resid > 0 && (!cookies || ncookies > 0)) { 578 #ifdef KERNFS_DIAGNOSTIC 579 printf("kernfs_readdir: i = %d\n", i); 580 #endif 581 if (i >= nkernfs_targets) { 582 *eofflagp = 1; 583 break; 584 } 585 { 586 struct direct d; 587 struct direct *dp = &d; 588 struct kernfs_target *kt = &kernfs_targets[i]; 589 590 bzero((caddr_t) dp, UIO_MX); 591 592 dp->d_namlen = strlen(kt->kt_name); 593 bcopy(kt->kt_name, dp->d_name, dp->d_namlen+1); 594 595 #ifdef KERNFS_DIAGNOSTIC 596 printf("kernfs_readdir: name = %s, len = %d\n", 597 dp->d_name, dp->d_namlen); 598 #endif 599 /* 600 * Fill in the remaining fields 601 */ 602 dp->d_reclen = UIO_MX; 603 dp->d_ino = i + 3; 604 /* 605 * And ship to userland 606 */ 607 error = uiomove((caddr_t) dp, UIO_MX, uio); 608 if (error) 609 break; 610 if (cookies) { 611 *cookies = (i + 1) * UIO_MX; 612 ncookies--; 613 } 614 } 615 i++; 616 } 617 618 uio->uio_offset = i * UIO_MX; 619 620 return (error); 621 } 622 623 kernfs_inactive(vp, p) 624 struct vnode *vp; 625 struct proc *p; 626 { 627 /* 628 * Clear out the v_type field to avoid 629 * nasty things happening in vgone(). 630 */ 631 vp->v_type = VNON; 632 #ifdef KERNFS_DIAGNOSTIC 633 printf("kernfs_inactive(%x)\n", vp); 634 #endif 635 return (0); 636 } 637 638 /* 639 * Print out the contents of a kernfs vnode. 640 */ 641 /* ARGSUSED */ 642 void 643 kernfs_print(vp) 644 struct vnode *vp; 645 { 646 printf("tag VT_KERNFS, kernfs vnode\n"); 647 } 648 649 /* 650 * kernfs vnode unsupported operation 651 */ 652 kernfs_enotsupp() 653 { 654 return (EOPNOTSUPP); 655 } 656 657 /* 658 * kernfs "should never get here" operation 659 */ 660 kernfs_badop() 661 { 662 panic("kernfs: bad op"); 663 /* NOTREACHED */ 664 } 665 666 /* 667 * kernfs vnode null operation 668 */ 669 kernfs_nullop() 670 { 671 return (0); 672 } 673 674 #define kernfs_create ((int (*) __P(( \ 675 struct nameidata *ndp, \ 676 struct vattr *vap, \ 677 struct proc *p))) kernfs_enotsupp) 678 #define kernfs_mknod ((int (*) __P(( \ 679 struct nameidata *ndp, \ 680 struct vattr *vap, \ 681 struct ucred *cred, \ 682 struct proc *p))) kernfs_enotsupp) 683 #define kernfs_close ((int (*) __P(( \ 684 struct vnode *vp, \ 685 int fflag, \ 686 struct ucred *cred, \ 687 struct proc *p))) nullop) 688 #define kernfs_ioctl ((int (*) __P(( \ 689 struct vnode *vp, \ 690 int command, \ 691 caddr_t data, \ 692 int fflag, \ 693 struct ucred *cred, \ 694 struct proc *p))) kernfs_enotsupp) 695 #define kernfs_select ((int (*) __P(( \ 696 struct vnode *vp, \ 697 int which, \ 698 int fflags, \ 699 struct ucred *cred, \ 700 struct proc *p))) kernfs_enotsupp) 701 #define kernfs_mmap ((int (*) __P(( \ 702 struct vnode *vp, \ 703 int fflags, \ 704 struct ucred *cred, \ 705 struct proc *p))) kernfs_enotsupp) 706 #define kernfs_fsync ((int (*) __P(( \ 707 struct vnode *vp, \ 708 int fflags, \ 709 struct ucred *cred, \ 710 int waitfor, \ 711 struct proc *p))) nullop) 712 #define kernfs_seek ((int (*) __P(( \ 713 struct vnode *vp, \ 714 off_t oldoff, \ 715 off_t newoff, \ 716 struct ucred *cred))) nullop) 717 #define kernfs_remove ((int (*) __P(( \ 718 struct nameidata *ndp, \ 719 struct proc *p))) kernfs_enotsupp) 720 #define kernfs_link ((int (*) __P(( \ 721 struct vnode *vp, \ 722 struct nameidata *ndp, \ 723 struct proc *p))) kernfs_enotsupp) 724 #define kernfs_rename ((int (*) __P(( \ 725 struct nameidata *fndp, \ 726 struct nameidata *tdnp, \ 727 struct proc *p))) kernfs_enotsupp) 728 #define kernfs_mkdir ((int (*) __P(( \ 729 struct nameidata *ndp, \ 730 struct vattr *vap, \ 731 struct proc *p))) kernfs_enotsupp) 732 #define kernfs_rmdir ((int (*) __P(( \ 733 struct nameidata *ndp, \ 734 struct proc *p))) kernfs_enotsupp) 735 #define kernfs_symlink ((int (*) __P(( \ 736 struct nameidata *ndp, \ 737 struct vattr *vap, \ 738 char *target, \ 739 struct proc *p))) kernfs_enotsupp) 740 #define kernfs_readlink ((int (*) __P(( \ 741 struct vnode *vp, \ 742 struct uio *uio, \ 743 struct ucred *cred))) kernfs_enotsupp) 744 #define kernfs_abortop ((int (*) __P(( \ 745 struct nameidata *ndp))) nullop) 746 #ifdef KERNFS_DIAGNOSTIC 747 int kernfs_reclaim(vp) 748 struct vnode *vp; 749 { 750 printf("kernfs_reclaim(%x)\n", vp); 751 return (0); 752 } 753 #else 754 #define kernfs_reclaim ((int (*) __P(( \ 755 struct vnode *vp))) nullop) 756 #endif 757 #define kernfs_lock ((int (*) __P(( \ 758 struct vnode *vp))) nullop) 759 #define kernfs_unlock ((int (*) __P(( \ 760 struct vnode *vp))) nullop) 761 #define kernfs_bmap ((int (*) __P(( \ 762 struct vnode *vp, \ 763 daddr_t bn, \ 764 struct vnode **vpp, \ 765 daddr_t *bnp))) kernfs_badop) 766 #define kernfs_strategy ((int (*) __P(( \ 767 struct buf *bp))) kernfs_badop) 768 #define kernfs_islocked ((int (*) __P(( \ 769 struct vnode *vp))) nullop) 770 #define kernfs_advlock ((int (*) __P(( \ 771 struct vnode *vp, \ 772 caddr_t id, \ 773 int op, \ 774 struct flock *fl, \ 775 int flags))) kernfs_enotsupp) 776 777 struct vnodeops kernfs_vnodeops = { 778 kernfs_lookup, /* lookup */ 779 kernfs_create, /* create */ 780 kernfs_mknod, /* mknod */ 781 kernfs_open, /* open */ 782 kernfs_close, /* close */ 783 kernfs_access, /* access */ 784 kernfs_getattr, /* getattr */ 785 kernfs_setattr, /* setattr */ 786 kernfs_read, /* read */ 787 kernfs_write, /* write */ 788 kernfs_ioctl, /* ioctl */ 789 kernfs_select, /* select */ 790 kernfs_mmap, /* mmap */ 791 kernfs_fsync, /* fsync */ 792 kernfs_seek, /* seek */ 793 kernfs_remove, /* remove */ 794 kernfs_link, /* link */ 795 kernfs_rename, /* rename */ 796 kernfs_mkdir, /* mkdir */ 797 kernfs_rmdir, /* rmdir */ 798 kernfs_symlink, /* symlink */ 799 kernfs_readdir, /* readdir */ 800 kernfs_readlink, /* readlink */ 801 kernfs_abortop, /* abortop */ 802 kernfs_inactive, /* inactive */ 803 kernfs_reclaim, /* reclaim */ 804 kernfs_lock, /* lock */ 805 kernfs_unlock, /* unlock */ 806 kernfs_bmap, /* bmap */ 807 kernfs_strategy, /* strategy */ 808 kernfs_print, /* print */ 809 kernfs_islocked, /* islocked */ 810 kernfs_advlock, /* advlock */ 811 }; 812