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