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