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