1*55344Spendry /* 2*55344Spendry * Copyright (c) 1992 The Regents of the University of California 3*55344Spendry * Copyright (c) 1990, 1992 Jan-Simon Pendry 4*55344Spendry * All rights reserved. 5*55344Spendry * 6*55344Spendry * This code is derived from software donated to Berkeley by 7*55344Spendry * Jan-Simon Pendry. 8*55344Spendry * 9*55344Spendry * %sccs.include.redist.c% 10*55344Spendry * 11*55344Spendry * @(#)kernfs_vnops.c 7.1 (Berkeley) 07/18/92 12*55344Spendry */ 13*55344Spendry 14*55344Spendry /* 15*55344Spendry * Kernel parameter filesystem (/kern) 16*55344Spendry */ 17*55344Spendry 18*55344Spendry #include <sys/param.h> 19*55344Spendry #include <sys/systm.h> 20*55344Spendry #include <sys/kernel.h> 21*55344Spendry #include <sys/vmmeter.h> 22*55344Spendry #include <sys/types.h> 23*55344Spendry #include <sys/time.h> 24*55344Spendry #include <sys/proc.h> 25*55344Spendry #include <sys/vnode.h> 26*55344Spendry #include <sys/malloc.h> 27*55344Spendry #include <sys/file.h> 28*55344Spendry #include <sys/stat.h> 29*55344Spendry #include <sys/mount.h> 30*55344Spendry #include <sys/namei.h> 31*55344Spendry #include <sys/buf.h> 32*55344Spendry #include <sys/dirent.h> 33*55344Spendry #include <miscfs/kernfs/kernfs.h> 34*55344Spendry 35*55344Spendry #define KSTRING 256 /* Largest I/O available via this filesystem */ 36*55344Spendry #define UIO_MX 32 37*55344Spendry 38*55344Spendry struct kern_target { 39*55344Spendry char *kt_name; 40*55344Spendry void *kt_data; 41*55344Spendry #define KTT_NULL 1 42*55344Spendry #define KTT_TIME 5 43*55344Spendry #define KTT_INT 17 44*55344Spendry #define KTT_STRING 31 45*55344Spendry #define KTT_HOSTNAME 47 46*55344Spendry #define KTT_AVENRUN 53 47*55344Spendry int kt_tag; 48*55344Spendry #define KTM_RO 0 49*55344Spendry #define KTM_RO_MODE (S_IRUSR|S_IRGRP|S_IROTH) 50*55344Spendry #define KTM_RW 43 51*55344Spendry #define KTM_RW_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH) 52*55344Spendry #define KTM_DIR_MODE (S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) 53*55344Spendry int kt_rw; 54*55344Spendry int kt_vtype; 55*55344Spendry } kern_targets[] = { 56*55344Spendry /* NOTE: The name must be less than UIO_MX-16 chars in length */ 57*55344Spendry /* name data tag ro/rw */ 58*55344Spendry { ".", 0, KTT_NULL, KTM_RO, VDIR }, 59*55344Spendry { "copyright", copyright, KTT_STRING, KTM_RO, VREG }, 60*55344Spendry { "hostname", 0, KTT_HOSTNAME, KTM_RW, VREG }, 61*55344Spendry { "hz", &hz, KTT_INT, KTM_RO, VREG }, 62*55344Spendry { "loadavg", 0, KTT_AVENRUN, KTM_RO, VREG }, 63*55344Spendry { "pagesize", &cnt.v_page_size, KTT_INT, KTM_RO, VREG }, 64*55344Spendry { "physmem", &physmem, KTT_INT, KTM_RO, VREG }, 65*55344Spendry { "root", 0, KTT_NULL, KTM_RO, VDIR }, 66*55344Spendry { "rootdev", 0, KTT_NULL, KTM_RO, VBLK }, 67*55344Spendry { "time", 0, KTT_TIME, KTM_RO, VREG }, 68*55344Spendry { "version", version, KTT_STRING, KTM_RO, VREG }, 69*55344Spendry }; 70*55344Spendry 71*55344Spendry static int nkern_targets = sizeof(kern_targets) / sizeof(kern_targets[0]); 72*55344Spendry 73*55344Spendry static int 74*55344Spendry kernfs_xread(kt, buf, len, lenp) 75*55344Spendry struct kern_target *kt; 76*55344Spendry char *buf; 77*55344Spendry int len; 78*55344Spendry int *lenp; 79*55344Spendry { 80*55344Spendry int xlen; 81*55344Spendry 82*55344Spendry switch (kt->kt_tag) { 83*55344Spendry case KTT_TIME: { 84*55344Spendry struct timeval tv; 85*55344Spendry microtime(&tv); 86*55344Spendry sprintf(buf, "%d %d\n", tv.tv_sec, tv.tv_usec); 87*55344Spendry break; 88*55344Spendry } 89*55344Spendry 90*55344Spendry case KTT_INT: { 91*55344Spendry int *ip = kt->kt_data; 92*55344Spendry sprintf(buf, "%d\n", *ip); 93*55344Spendry break; 94*55344Spendry } 95*55344Spendry 96*55344Spendry case KTT_STRING: { 97*55344Spendry char *cp = kt->kt_data; 98*55344Spendry int xlen = strlen(cp) + 1; 99*55344Spendry 100*55344Spendry if (xlen >= len) 101*55344Spendry return (EINVAL); 102*55344Spendry 103*55344Spendry bcopy(cp, buf, xlen); 104*55344Spendry break; 105*55344Spendry } 106*55344Spendry 107*55344Spendry case KTT_HOSTNAME: { 108*55344Spendry char *cp = hostname; 109*55344Spendry int xlen = hostnamelen; 110*55344Spendry 111*55344Spendry if (xlen >= len) 112*55344Spendry return (EINVAL); 113*55344Spendry 114*55344Spendry sprintf(buf, "%s\n", cp); 115*55344Spendry break; 116*55344Spendry } 117*55344Spendry 118*55344Spendry case KTT_AVENRUN: 119*55344Spendry sprintf(buf, "%ld %ld %ld %ld\n", 120*55344Spendry averunnable.ldavg[0], 121*55344Spendry averunnable.ldavg[1], 122*55344Spendry averunnable.ldavg[2], 123*55344Spendry averunnable.fscale); 124*55344Spendry break; 125*55344Spendry 126*55344Spendry default: 127*55344Spendry return (EINVAL); 128*55344Spendry } 129*55344Spendry 130*55344Spendry *lenp = strlen(buf); 131*55344Spendry return (0); 132*55344Spendry } 133*55344Spendry 134*55344Spendry static int 135*55344Spendry kernfs_xwrite(kt, buf, len) 136*55344Spendry struct kern_target *kt; 137*55344Spendry char *buf; 138*55344Spendry int len; 139*55344Spendry { 140*55344Spendry switch (kt->kt_tag) { 141*55344Spendry case KTT_HOSTNAME: { 142*55344Spendry if (buf[len-1] == '\n') 143*55344Spendry --len; 144*55344Spendry bcopy(buf, hostname, len); 145*55344Spendry hostnamelen = len - 1; 146*55344Spendry return (0); 147*55344Spendry } 148*55344Spendry 149*55344Spendry default: 150*55344Spendry return (EIO); 151*55344Spendry } 152*55344Spendry } 153*55344Spendry 154*55344Spendry 155*55344Spendry /* 156*55344Spendry * vp is the current namei directory 157*55344Spendry * ndp is the name to locate in that directory... 158*55344Spendry */ 159*55344Spendry kernfs_lookup(ap) 160*55344Spendry struct vop_lookup_args /* { 161*55344Spendry struct vnode * a_dvp; 162*55344Spendry struct vnode ** a_vpp; 163*55344Spendry struct componentname * a_cnp; 164*55344Spendry } */ *ap; 165*55344Spendry { 166*55344Spendry struct vnode **vpp = ap->a_vpp; 167*55344Spendry struct vnode *dvp = ap->a_dvp; 168*55344Spendry struct componentname *cnp = ap->a_cnp; 169*55344Spendry char *pname; 170*55344Spendry struct proc *p; 171*55344Spendry int error; 172*55344Spendry struct vnode *fvp; 173*55344Spendry int i; 174*55344Spendry 175*55344Spendry #ifdef KERNFS_DIAGNOSTIC 176*55344Spendry printf("kernfs_lookup(%x)\n", ap); 177*55344Spendry printf("kernfs_lookup(dp = %x, vpp = %x, cnp = %x)\n", dvp, vpp, ap->a_cnp); 178*55344Spendry #endif 179*55344Spendry pname = cnp->cn_nameptr; 180*55344Spendry #ifdef KERNFS_DIAGNOSTIC 181*55344Spendry printf("kernfs_lookup(%s)\n", pname); 182*55344Spendry #endif 183*55344Spendry if (cnp->cn_namelen == 1 && *pname == '.') { 184*55344Spendry *vpp = dvp; 185*55344Spendry VREF(dvp); 186*55344Spendry /*VOP_LOCK(dvp);*/ 187*55344Spendry return (0); 188*55344Spendry } 189*55344Spendry 190*55344Spendry if (cnp->cn_namelen == 4 && bcmp(pname, "root", 4) == 0) { 191*55344Spendry *vpp = rootdir; 192*55344Spendry VREF(rootdir); 193*55344Spendry VOP_LOCK(rootdir); 194*55344Spendry return (0); 195*55344Spendry } 196*55344Spendry 197*55344Spendry /* 198*55344Spendry * /kern/rootdev is the root device 199*55344Spendry */ 200*55344Spendry if (cnp->cn_namelen == 7 && bcmp(pname, "rootdev", 7) == 0) { 201*55344Spendry *vpp = rootvp; 202*55344Spendry VREF(rootvp); 203*55344Spendry VOP_LOCK(rootvp); 204*55344Spendry return (0); 205*55344Spendry } 206*55344Spendry 207*55344Spendry for (i = 0; i < nkern_targets; i++) { 208*55344Spendry struct kern_target *kt = &kern_targets[i]; 209*55344Spendry if (cnp->cn_namelen == strlen(kt->kt_name) && 210*55344Spendry bcmp(kt->kt_name, pname, cnp->cn_namelen) == 0) { 211*55344Spendry error = 0; 212*55344Spendry break; 213*55344Spendry } 214*55344Spendry } 215*55344Spendry 216*55344Spendry #ifdef KERNFS_DIAGNOSTIC 217*55344Spendry printf("kernfs_lookup: i = %d, error = %d\n", i, error); 218*55344Spendry #endif 219*55344Spendry 220*55344Spendry if (error) 221*55344Spendry goto bad; 222*55344Spendry 223*55344Spendry #ifdef KERNFS_DIAGNOSTIC 224*55344Spendry printf("kernfs_lookup: allocate new vnode\n"); 225*55344Spendry #endif 226*55344Spendry error = getnewvnode(VT_UFS, dvp->v_mount, kernfs_vnodeop_p, &fvp); 227*55344Spendry if (error) 228*55344Spendry goto bad; 229*55344Spendry MALLOC(fvp->v_data, void *, sizeof(struct kernfs_node), M_TEMP, M_WAITOK); 230*55344Spendry VTOKERN(fvp)->kf_kt = &kern_targets[i]; 231*55344Spendry fvp->v_type = VTOKERN(fvp)->kf_kt->kt_vtype; 232*55344Spendry *vpp = fvp; 233*55344Spendry #ifdef KERNFS_DIAGNOSTIC 234*55344Spendry printf("kernfs_lookup: newvp = %x\n", fvp); 235*55344Spendry #endif 236*55344Spendry return (0); 237*55344Spendry 238*55344Spendry bad:; 239*55344Spendry *vpp = NULL; 240*55344Spendry #ifdef KERNFS_DIAGNOSTIC 241*55344Spendry printf("kernfs_lookup: error = %d\n", error); 242*55344Spendry #endif 243*55344Spendry return (error); 244*55344Spendry } 245*55344Spendry 246*55344Spendry kernfs_open(ap) 247*55344Spendry struct vop_open_args /* { 248*55344Spendry struct vnode *a_vp; 249*55344Spendry int a_mode; 250*55344Spendry struct ucred *a_cred; 251*55344Spendry struct proc *a_p; 252*55344Spendry } */ *ap; 253*55344Spendry { 254*55344Spendry struct vnode *vp = ap->a_vp; 255*55344Spendry 256*55344Spendry /* 257*55344Spendry * Can always open the root (modulo perms) 258*55344Spendry */ 259*55344Spendry if (vp->v_flag & VROOT) 260*55344Spendry return (0); 261*55344Spendry 262*55344Spendry #ifdef KERNFS_DIAGNOSTIC 263*55344Spendry printf("kernfs_open, mode = %x, file = %s\n", 264*55344Spendry ap->a_mode, VTOKERN(vp)->kf_kt->kt_name); 265*55344Spendry #endif 266*55344Spendry 267*55344Spendry if ((ap->a_mode & FWRITE) && VTOKERN(vp)->kf_kt->kt_rw != KTM_RW) 268*55344Spendry return (EBADF); 269*55344Spendry 270*55344Spendry return (0); 271*55344Spendry } 272*55344Spendry 273*55344Spendry static int 274*55344Spendry kernfs_access(ap) 275*55344Spendry struct vop_access_args /* { 276*55344Spendry struct vnode *a_vp; 277*55344Spendry int a_mode; 278*55344Spendry struct ucred *a_cred; 279*55344Spendry struct proc *a_p; 280*55344Spendry } */ *ap; 281*55344Spendry { 282*55344Spendry struct vnode *vp = ap->a_vp; 283*55344Spendry struct ucred *cred = ap->a_cred; 284*55344Spendry struct kern_target *kt = VTOKERN(vp)->kf_kt; 285*55344Spendry mode_t mode = ap->a_mode; 286*55344Spendry 287*55344Spendry if (mode & VEXEC) { 288*55344Spendry if (vp->v_flag & VROOT) 289*55344Spendry return (0); 290*55344Spendry return (EACCES); 291*55344Spendry } 292*55344Spendry 293*55344Spendry if (cred->cr_uid == 0) { 294*55344Spendry if ((mode & VWRITE) && (kt->kt_rw != KTM_RW)) 295*55344Spendry return (EROFS); 296*55344Spendry return (0); 297*55344Spendry } 298*55344Spendry 299*55344Spendry if (mode & VWRITE) 300*55344Spendry return (EACCES); 301*55344Spendry 302*55344Spendry return (0); 303*55344Spendry } 304*55344Spendry 305*55344Spendry 306*55344Spendry kernfs_getattr(ap) 307*55344Spendry struct vop_getattr_args /* { 308*55344Spendry struct vnode *a_vp; 309*55344Spendry struct vattr *a_vap; 310*55344Spendry struct ucred *a_cred; 311*55344Spendry struct proc *a_p; 312*55344Spendry } */ *ap; 313*55344Spendry { 314*55344Spendry struct vnode *vp = ap->a_vp; 315*55344Spendry struct vattr *vap = ap->a_vap; 316*55344Spendry int error = 0; 317*55344Spendry char strbuf[KSTRING]; 318*55344Spendry struct kern_target *kt = VTOKERN(vp)->kf_kt; 319*55344Spendry 320*55344Spendry bzero((caddr_t) vap, sizeof(*vap)); 321*55344Spendry vattr_null(vap); 322*55344Spendry vap->va_uid = 0; 323*55344Spendry vap->va_gid = 0; 324*55344Spendry vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0]; 325*55344Spendry /* vap->va_qsize = 0; */ 326*55344Spendry vap->va_blocksize = DEV_BSIZE; 327*55344Spendry microtime(&vap->va_atime); 328*55344Spendry vap->va_mtime = vap->va_atime; 329*55344Spendry vap->va_ctime = vap->va_ctime; 330*55344Spendry vap->va_gen = 0; 331*55344Spendry vap->va_flags = 0; 332*55344Spendry vap->va_rdev = 0; 333*55344Spendry /* vap->va_qbytes = 0; */ 334*55344Spendry vap->va_bytes = 0; 335*55344Spendry 336*55344Spendry if (vp->v_flag & VROOT) { 337*55344Spendry #ifdef KERNFS_DIAGNOSTIC 338*55344Spendry printf("kernfs_getattr: stat rootdir\n"); 339*55344Spendry #endif 340*55344Spendry vap->va_type = VDIR; 341*55344Spendry vap->va_mode = KTM_DIR_MODE; 342*55344Spendry vap->va_nlink = 2; 343*55344Spendry vap->va_fileid = 2; 344*55344Spendry vap->va_size = DEV_BSIZE; 345*55344Spendry } else { 346*55344Spendry int nbytes; 347*55344Spendry #ifdef KERNFS_DIAGNOSTIC 348*55344Spendry printf("kernfs_getattr: stat target %s\n", kt->kt_name); 349*55344Spendry #endif 350*55344Spendry vap->va_type = kt->kt_vtype; 351*55344Spendry vap->va_mode = (kt->kt_rw ? KTM_RW_MODE : KTM_RO_MODE); 352*55344Spendry vap->va_nlink = 1; 353*55344Spendry vap->va_fileid = 3 + (kt - kern_targets) / sizeof(*kt); 354*55344Spendry error = kernfs_xread(kt, strbuf, sizeof(strbuf), &nbytes); 355*55344Spendry vap->va_size = nbytes; 356*55344Spendry } 357*55344Spendry 358*55344Spendry vp->v_type = vap->va_type; 359*55344Spendry #ifdef KERNFS_DIAGNOSTIC 360*55344Spendry printf("kernfs_getattr: return error %d\n", error); 361*55344Spendry #endif 362*55344Spendry return (error); 363*55344Spendry } 364*55344Spendry 365*55344Spendry kernfs_setattr(ap) 366*55344Spendry struct vop_setattr_args /* { 367*55344Spendry struct vnode *a_vp; 368*55344Spendry struct vattr *a_vap; 369*55344Spendry struct ucred *a_cred; 370*55344Spendry struct proc *a_p; 371*55344Spendry } */ *ap; 372*55344Spendry { 373*55344Spendry 374*55344Spendry /* 375*55344Spendry * Silently ignore attribute changes. 376*55344Spendry * This allows for open with truncate to have no 377*55344Spendry * effect until some data is written. I want to 378*55344Spendry * do it this way because all writes are atomic. 379*55344Spendry */ 380*55344Spendry return (0); 381*55344Spendry } 382*55344Spendry 383*55344Spendry static int 384*55344Spendry kernfs_read(ap) 385*55344Spendry struct vop_read_args /* { 386*55344Spendry struct vnode *a_vp; 387*55344Spendry struct uio *a_uio; 388*55344Spendry int a_ioflag; 389*55344Spendry struct ucred *a_cred; 390*55344Spendry } */ *ap; 391*55344Spendry { 392*55344Spendry struct vnode *vp = ap->a_vp; 393*55344Spendry struct uio *uio = ap->a_uio; 394*55344Spendry struct kern_target *kt = VTOKERN(vp)->kf_kt; 395*55344Spendry char strbuf[KSTRING]; 396*55344Spendry int off = uio->uio_offset; 397*55344Spendry int len = 0; 398*55344Spendry char *cp = strbuf; 399*55344Spendry int error; 400*55344Spendry #ifdef KERNFS_DIAGNOSTIC 401*55344Spendry printf("kern_read %s\n", kt->kt_name); 402*55344Spendry #endif 403*55344Spendry 404*55344Spendry error = kernfs_xread(kt, strbuf, sizeof(strbuf), &len); 405*55344Spendry if (error) 406*55344Spendry return (error); 407*55344Spendry cp = strbuf + off; 408*55344Spendry len -= off; 409*55344Spendry return (uiomove(cp, len, uio)); 410*55344Spendry } 411*55344Spendry 412*55344Spendry static int 413*55344Spendry kernfs_write(ap) 414*55344Spendry struct vop_write_args /* { 415*55344Spendry struct vnode *a_vp; 416*55344Spendry struct uio *a_uio; 417*55344Spendry int a_ioflag; 418*55344Spendry struct ucred *a_cred; 419*55344Spendry } */ *ap; 420*55344Spendry { 421*55344Spendry struct vnode *vp = ap->a_vp; 422*55344Spendry struct uio *uio = ap->a_uio; 423*55344Spendry struct kern_target *kt = VTOKERN(vp)->kf_kt; 424*55344Spendry char strbuf[KSTRING]; 425*55344Spendry int len = uio->uio_resid; 426*55344Spendry char *cp = strbuf; 427*55344Spendry int xlen; 428*55344Spendry int error; 429*55344Spendry 430*55344Spendry if (uio->uio_offset != 0) 431*55344Spendry return (EINVAL); 432*55344Spendry 433*55344Spendry xlen = min(uio->uio_resid, KSTRING-1); 434*55344Spendry error = uiomove(strbuf, xlen, uio); 435*55344Spendry if (error) 436*55344Spendry return (error); 437*55344Spendry 438*55344Spendry if (uio->uio_resid != 0) 439*55344Spendry return (EIO); 440*55344Spendry 441*55344Spendry strbuf[xlen] = '\0'; 442*55344Spendry return (kernfs_xwrite(kt, strbuf, xlen)); 443*55344Spendry } 444*55344Spendry 445*55344Spendry 446*55344Spendry kernfs_readdir(ap) 447*55344Spendry struct vop_readdir_args /* { 448*55344Spendry struct vnode *a_vp; 449*55344Spendry struct uio *a_uio; 450*55344Spendry struct ucred *a_cred; 451*55344Spendry } */ *ap; 452*55344Spendry { 453*55344Spendry struct uio *uio = ap->a_uio; 454*55344Spendry int i; 455*55344Spendry int error; 456*55344Spendry 457*55344Spendry i = uio->uio_offset / UIO_MX; 458*55344Spendry error = 0; 459*55344Spendry while (uio->uio_resid > 0 && i < nkern_targets) { 460*55344Spendry struct dirent d; 461*55344Spendry struct dirent *dp = &d; 462*55344Spendry struct kern_target *kt = &kern_targets[i]; 463*55344Spendry #ifdef KERNFS_DIAGNOSTIC 464*55344Spendry printf("kernfs_readdir: i = %d\n", i); 465*55344Spendry #endif 466*55344Spendry 467*55344Spendry bzero((caddr_t) dp, UIO_MX); 468*55344Spendry 469*55344Spendry dp->d_namlen = strlen(kt->kt_name); 470*55344Spendry bcopy(kt->kt_name, dp->d_name, dp->d_namlen+1); 471*55344Spendry 472*55344Spendry #ifdef KERNFS_DIAGNOSTIC 473*55344Spendry printf("kernfs_readdir: name = %s, len = %d\n", 474*55344Spendry dp->d_name, dp->d_namlen); 475*55344Spendry #endif 476*55344Spendry /* 477*55344Spendry * Fill in the remaining fields 478*55344Spendry */ 479*55344Spendry dp->d_reclen = UIO_MX; 480*55344Spendry dp->d_fileno = i + 3; 481*55344Spendry dp->d_type = DT_UNKNOWN; /* XXX */ 482*55344Spendry /* 483*55344Spendry * And ship to userland 484*55344Spendry */ 485*55344Spendry error = uiomove((caddr_t) dp, UIO_MX, uio); 486*55344Spendry if (error) 487*55344Spendry break; 488*55344Spendry i++; 489*55344Spendry } 490*55344Spendry 491*55344Spendry uio->uio_offset = i * UIO_MX; 492*55344Spendry 493*55344Spendry return (error); 494*55344Spendry } 495*55344Spendry 496*55344Spendry kernfs_inactive(ap) 497*55344Spendry struct vop_inactive_args /* { 498*55344Spendry struct vnode *a_vp; 499*55344Spendry } */ *ap; 500*55344Spendry { 501*55344Spendry struct vnode *vp = ap->a_vp; 502*55344Spendry 503*55344Spendry /* 504*55344Spendry * Clear out the v_type field to avoid 505*55344Spendry * nasty things happening in vgone(). 506*55344Spendry */ 507*55344Spendry vp->v_type = VNON; 508*55344Spendry #ifdef KERNFS_DIAGNOSTIC 509*55344Spendry printf("kernfs_inactive(%x)\n", vp); 510*55344Spendry #endif 511*55344Spendry return (0); 512*55344Spendry } 513*55344Spendry 514*55344Spendry kernfs_reclaim(ap) 515*55344Spendry struct vop_reclaim_args /* { 516*55344Spendry struct vnode *a_vp; 517*55344Spendry } */ *ap; 518*55344Spendry { 519*55344Spendry struct vnode *vp = ap->a_vp; 520*55344Spendry printf("kernfs_reclaim(%x)\n", vp); 521*55344Spendry if (vp->v_data) { 522*55344Spendry FREE(vp->v_data, M_TEMP); 523*55344Spendry vp->v_data = 0; 524*55344Spendry } 525*55344Spendry return (0); 526*55344Spendry } 527*55344Spendry 528*55344Spendry /* 529*55344Spendry * Print out the contents of a /dev/fd vnode. 530*55344Spendry */ 531*55344Spendry /* ARGSUSED */ 532*55344Spendry kernfs_print(ap) 533*55344Spendry struct vop_print_args /* { 534*55344Spendry struct vnode *a_vp; 535*55344Spendry } */ *ap; 536*55344Spendry { 537*55344Spendry 538*55344Spendry printf("tag VT_NON, kernfs vnode\n"); 539*55344Spendry return (0); 540*55344Spendry } 541*55344Spendry 542*55344Spendry /*void*/ 543*55344Spendry kernfs_vfree(ap) 544*55344Spendry struct vop_vfree_args /* { 545*55344Spendry struct vnode *a_pvp; 546*55344Spendry ino_t a_ino; 547*55344Spendry int a_mode; 548*55344Spendry } */ *ap; 549*55344Spendry { 550*55344Spendry 551*55344Spendry return (0); 552*55344Spendry } 553*55344Spendry 554*55344Spendry /* 555*55344Spendry * /dev/fd vnode unsupported operation 556*55344Spendry */ 557*55344Spendry kernfs_enotsupp() 558*55344Spendry { 559*55344Spendry 560*55344Spendry return (EOPNOTSUPP); 561*55344Spendry } 562*55344Spendry 563*55344Spendry /* 564*55344Spendry * /dev/fd "should never get here" operation 565*55344Spendry */ 566*55344Spendry kernfs_badop() 567*55344Spendry { 568*55344Spendry 569*55344Spendry panic("kernfs: bad op"); 570*55344Spendry /* NOTREACHED */ 571*55344Spendry } 572*55344Spendry 573*55344Spendry /* 574*55344Spendry * /dev/fd vnode null operation 575*55344Spendry */ 576*55344Spendry kernfs_nullop() 577*55344Spendry { 578*55344Spendry 579*55344Spendry return (0); 580*55344Spendry } 581*55344Spendry 582*55344Spendry #define kernfs_create ((int (*) __P((struct vop_create_args *)))kernfs_enotsupp) 583*55344Spendry #define kernfs_mknod ((int (*) __P((struct vop_mknod_args *)))kernfs_enotsupp) 584*55344Spendry #define kernfs_close ((int (*) __P((struct vop_close_args *)))nullop) 585*55344Spendry #define kernfs_ioctl ((int (*) __P((struct vop_ioctl_args *)))kernfs_enotsupp) 586*55344Spendry #define kernfs_select ((int (*) __P((struct vop_select_args *)))kernfs_enotsupp) 587*55344Spendry #define kernfs_mmap ((int (*) __P((struct vop_mmap_args *)))kernfs_enotsupp) 588*55344Spendry #define kernfs_fsync ((int (*) __P((struct vop_fsync_args *)))nullop) 589*55344Spendry #define kernfs_seek ((int (*) __P((struct vop_seek_args *)))nullop) 590*55344Spendry #define kernfs_remove ((int (*) __P((struct vop_remove_args *)))kernfs_enotsupp) 591*55344Spendry #define kernfs_link ((int (*) __P((struct vop_link_args *)))kernfs_enotsupp) 592*55344Spendry #define kernfs_rename ((int (*) __P((struct vop_rename_args *)))kernfs_enotsupp) 593*55344Spendry #define kernfs_mkdir ((int (*) __P((struct vop_mkdir_args *)))kernfs_enotsupp) 594*55344Spendry #define kernfs_rmdir ((int (*) __P((struct vop_rmdir_args *)))kernfs_enotsupp) 595*55344Spendry #define kernfs_symlink ((int (*) __P((struct vop_symlink_args *)))kernfs_enotsupp) 596*55344Spendry #define kernfs_readlink \ 597*55344Spendry ((int (*) __P((struct vop_readlink_args *)))kernfs_enotsupp) 598*55344Spendry #define kernfs_abortop ((int (*) __P((struct vop_abortop_args *)))nullop) 599*55344Spendry #define kernfs_lock ((int (*) __P((struct vop_lock_args *)))nullop) 600*55344Spendry #define kernfs_unlock ((int (*) __P((struct vop_unlock_args *)))nullop) 601*55344Spendry #define kernfs_bmap ((int (*) __P((struct vop_bmap_args *)))kernfs_badop) 602*55344Spendry #define kernfs_strategy ((int (*) __P((struct vop_strategy_args *)))kernfs_badop) 603*55344Spendry #define kernfs_islocked ((int (*) __P((struct vop_islocked_args *)))nullop) 604*55344Spendry #define kernfs_advlock ((int (*) __P((struct vop_advlock_args *)))kernfs_enotsupp) 605*55344Spendry #define kernfs_blkatoff \ 606*55344Spendry ((int (*) __P((struct vop_blkatoff_args *)))kernfs_enotsupp) 607*55344Spendry #define kernfs_valloc ((int(*) __P(( \ 608*55344Spendry struct vnode *pvp, \ 609*55344Spendry int mode, \ 610*55344Spendry struct ucred *cred, \ 611*55344Spendry struct vnode **vpp))) kernfs_enotsupp) 612*55344Spendry #define kernfs_truncate \ 613*55344Spendry ((int (*) __P((struct vop_truncate_args *)))kernfs_enotsupp) 614*55344Spendry #define kernfs_update ((int (*) __P((struct vop_update_args *)))kernfs_enotsupp) 615*55344Spendry #define kernfs_bwrite ((int (*) __P((struct vop_bwrite_args *)))kernfs_enotsupp) 616*55344Spendry 617*55344Spendry int (**kernfs_vnodeop_p)(); 618*55344Spendry struct vnodeopv_entry_desc kernfs_vnodeop_entries[] = { 619*55344Spendry { &vop_default_desc, vn_default_error }, 620*55344Spendry { &vop_lookup_desc, kernfs_lookup }, /* lookup */ 621*55344Spendry { &vop_create_desc, kernfs_create }, /* create */ 622*55344Spendry { &vop_mknod_desc, kernfs_mknod }, /* mknod */ 623*55344Spendry { &vop_open_desc, kernfs_open }, /* open */ 624*55344Spendry { &vop_close_desc, kernfs_close }, /* close */ 625*55344Spendry { &vop_access_desc, kernfs_access }, /* access */ 626*55344Spendry { &vop_getattr_desc, kernfs_getattr }, /* getattr */ 627*55344Spendry { &vop_setattr_desc, kernfs_setattr }, /* setattr */ 628*55344Spendry { &vop_read_desc, kernfs_read }, /* read */ 629*55344Spendry { &vop_write_desc, kernfs_write }, /* write */ 630*55344Spendry { &vop_ioctl_desc, kernfs_ioctl }, /* ioctl */ 631*55344Spendry { &vop_select_desc, kernfs_select }, /* select */ 632*55344Spendry { &vop_mmap_desc, kernfs_mmap }, /* mmap */ 633*55344Spendry { &vop_fsync_desc, kernfs_fsync }, /* fsync */ 634*55344Spendry { &vop_seek_desc, kernfs_seek }, /* seek */ 635*55344Spendry { &vop_remove_desc, kernfs_remove }, /* remove */ 636*55344Spendry { &vop_link_desc, kernfs_link }, /* link */ 637*55344Spendry { &vop_rename_desc, kernfs_rename }, /* rename */ 638*55344Spendry { &vop_mkdir_desc, kernfs_mkdir }, /* mkdir */ 639*55344Spendry { &vop_rmdir_desc, kernfs_rmdir }, /* rmdir */ 640*55344Spendry { &vop_symlink_desc, kernfs_symlink }, /* symlink */ 641*55344Spendry { &vop_readdir_desc, kernfs_readdir }, /* readdir */ 642*55344Spendry { &vop_readlink_desc, kernfs_readlink }, /* readlink */ 643*55344Spendry { &vop_abortop_desc, kernfs_abortop }, /* abortop */ 644*55344Spendry { &vop_inactive_desc, kernfs_inactive }, /* inactive */ 645*55344Spendry { &vop_reclaim_desc, kernfs_reclaim }, /* reclaim */ 646*55344Spendry { &vop_lock_desc, kernfs_lock }, /* lock */ 647*55344Spendry { &vop_unlock_desc, kernfs_unlock }, /* unlock */ 648*55344Spendry { &vop_bmap_desc, kernfs_bmap }, /* bmap */ 649*55344Spendry { &vop_strategy_desc, kernfs_strategy }, /* strategy */ 650*55344Spendry { &vop_print_desc, kernfs_print }, /* print */ 651*55344Spendry { &vop_islocked_desc, kernfs_islocked }, /* islocked */ 652*55344Spendry { &vop_advlock_desc, kernfs_advlock }, /* advlock */ 653*55344Spendry { &vop_blkatoff_desc, kernfs_blkatoff }, /* blkatoff */ 654*55344Spendry { &vop_valloc_desc, kernfs_valloc }, /* valloc */ 655*55344Spendry { &vop_vfree_desc, kernfs_vfree }, /* vfree */ 656*55344Spendry { &vop_truncate_desc, kernfs_truncate }, /* truncate */ 657*55344Spendry { &vop_update_desc, kernfs_update }, /* update */ 658*55344Spendry { &vop_bwrite_desc, kernfs_bwrite }, /* bwrite */ 659*55344Spendry { (struct vnodeop_desc*)NULL, (int(*)())NULL } 660*55344Spendry }; 661*55344Spendry struct vnodeopv_desc kernfs_vnodeop_opv_desc = 662*55344Spendry { &kernfs_vnodeop_p, kernfs_vnodeop_entries }; 663