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