xref: /netbsd-src/sys/miscfs/kernfs/kernfs_vnops.c (revision df0caa2637da0538ecdf6b878c4d08e684b43d8f)
1 /*	$NetBSD: kernfs_vnops.c,v 1.109 2005/05/29 21:55:33 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 1992, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software donated to Berkeley by
8  * Jan-Simon Pendry.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *	@(#)kernfs_vnops.c	8.15 (Berkeley) 5/21/95
35  */
36 
37 /*
38  * Kernel parameter filesystem (/kern)
39  */
40 
41 #include <sys/cdefs.h>
42 __KERNEL_RCSID(0, "$NetBSD: kernfs_vnops.c,v 1.109 2005/05/29 21:55:33 christos Exp $");
43 
44 #ifdef _KERNEL_OPT
45 #include "opt_ipsec.h"
46 #endif
47 
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/kernel.h>
51 #include <sys/vmmeter.h>
52 #include <sys/time.h>
53 #include <sys/proc.h>
54 #include <sys/vnode.h>
55 #include <sys/malloc.h>
56 #include <sys/file.h>
57 #include <sys/stat.h>
58 #include <sys/mount.h>
59 #include <sys/namei.h>
60 #include <sys/buf.h>
61 #include <sys/dirent.h>
62 #include <sys/msgbuf.h>
63 
64 #include <miscfs/genfs/genfs.h>
65 #include <miscfs/kernfs/kernfs.h>
66 
67 #ifdef IPSEC
68 #include <sys/mbuf.h>
69 #include <net/route.h>
70 #include <netinet/in.h>
71 #include <netinet6/ipsec.h>
72 #include <netkey/key.h>
73 #endif
74 
75 #include <uvm/uvm_extern.h>
76 
77 #define KSTRING	256		/* Largest I/O available via this filesystem */
78 #define	UIO_MX 32
79 
80 #define	READ_MODE	(S_IRUSR|S_IRGRP|S_IROTH)
81 #define	WRITE_MODE	(S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH)
82 #define	UREAD_MODE	(S_IRUSR)
83 #define	DIR_MODE	(S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
84 #define	UDIR_MODE	(S_IRUSR|S_IXUSR)
85 
86 #define N(s) sizeof(s)-1, s
87 const struct kern_target kern_targets[] = {
88 /* NOTE: The name must be less than UIO_MX-16 chars in length */
89      /*        name            data          tag           type  ro/rw */
90      { DT_DIR, N("."),         0,            KFSkern,        VDIR, DIR_MODE   },
91      { DT_DIR, N(".."),        0,            KFSroot,        VDIR, DIR_MODE   },
92      { DT_REG, N("boottime"),  &boottime.tv_sec, KFSint,     VREG, READ_MODE  },
93 			/* XXXUNCONST */
94      { DT_REG, N("copyright"), __UNCONST(copyright),
95      					     KFSstring,      VREG, READ_MODE  },
96      { DT_REG, N("hostname"),  0,            KFShostname,    VREG, WRITE_MODE },
97      { DT_REG, N("hz"),        &hz,          KFSint,         VREG, READ_MODE  },
98 #ifdef IPSEC
99      { DT_DIR, N("ipsecsa"),   0,	     KFSipsecsadir,  VDIR, UDIR_MODE  },
100      { DT_DIR, N("ipsecsp"),   0,	     KFSipsecspdir,  VDIR, UDIR_MODE  },
101 #endif
102      { DT_REG, N("loadavg"),   0,            KFSavenrun,     VREG, READ_MODE  },
103      { DT_REG, N("msgbuf"),    0,	     KFSmsgbuf,      VREG, READ_MODE  },
104      { DT_REG, N("pagesize"),  &uvmexp.pagesize, KFSint,     VREG, READ_MODE  },
105      { DT_REG, N("physmem"),   &physmem,     KFSint,         VREG, READ_MODE  },
106 #if 0
107      { DT_DIR, N("root"),      0,            KFSnull,        VDIR, DIR_MODE   },
108 #endif
109      { DT_BLK, N("rootdev"),   &rootdev,     KFSdevice,      VBLK, READ_MODE  },
110      { DT_CHR, N("rrootdev"),  &rrootdev,    KFSdevice,      VCHR, READ_MODE  },
111      { DT_REG, N("time"),      0,            KFStime,        VREG, READ_MODE  },
112 			/* XXXUNCONST */
113      { DT_REG, N("version"),   __UNCONST(version),
114      					     KFSstring,      VREG, READ_MODE  },
115 };
116 const struct kern_target subdir_targets[] = {
117 /* NOTE: The name must be less than UIO_MX-16 chars in length */
118      /*        name            data          tag           type  ro/rw */
119      { DT_DIR, N("."),         0,            KFSsubdir,      VDIR, DIR_MODE   },
120      { DT_DIR, N(".."),        0,            KFSkern,        VDIR, DIR_MODE   },
121 };
122 #ifdef IPSEC
123 const struct kern_target ipsecsa_targets[] = {
124 /* NOTE: The name must be less than UIO_MX-16 chars in length */
125      /*        name            data          tag           type  ro/rw */
126      { DT_DIR, N("."),         0,            KFSipsecsadir,  VDIR, DIR_MODE   },
127      { DT_DIR, N(".."),        0,            KFSkern,        VDIR, DIR_MODE   },
128 };
129 const struct kern_target ipsecsp_targets[] = {
130 /* NOTE: The name must be less than UIO_MX-16 chars in length */
131      /*        name            data          tag           type  ro/rw */
132      { DT_DIR, N("."),         0,            KFSipsecspdir,  VDIR, DIR_MODE   },
133      { DT_DIR, N(".."),        0,            KFSkern,        VDIR, DIR_MODE   },
134 };
135 const struct kern_target ipsecsa_kt =
136      { DT_DIR, N(""),          0,            KFSipsecsa,     VREG, UREAD_MODE };
137 const struct kern_target ipsecsp_kt =
138      { DT_DIR, N(""),          0,            KFSipsecsp,     VREG, UREAD_MODE };
139 #endif
140 #undef N
141 SIMPLEQ_HEAD(,dyn_kern_target) dyn_kern_targets =
142 	SIMPLEQ_HEAD_INITIALIZER(dyn_kern_targets);
143 int nkern_targets = sizeof(kern_targets) / sizeof(kern_targets[0]);
144 const int static_nkern_targets = sizeof(kern_targets) / sizeof(kern_targets[0]);
145 #ifdef IPSEC
146 int nipsecsa_targets = sizeof(ipsecsa_targets) / sizeof(ipsecsa_targets[0]);
147 int nipsecsp_targets = sizeof(ipsecsp_targets) / sizeof(ipsecsp_targets[0]);
148 int nkern_dirs = 4; /* 2 extra subdirs */
149 #else
150 int nkern_dirs = 2;
151 #endif
152 
153 int kernfs_try_fileop(kfstype, kfsfileop, void *, int);
154 int kernfs_try_xwrite(kfstype, const struct kernfs_node *, char *,
155     size_t, int);
156 
157 static int kernfs_default_xwrite(void *v);
158 static int kernfs_default_fileop_getattr(void *);
159 
160 /* must include all fileop's */
161 const struct kernfs_fileop kernfs_default_fileops[] = {
162   { .kf_fileop = KERNFS_XWRITE },
163   { .kf_fileop = KERNFS_FILEOP_OPEN },
164   { .kf_fileop = KERNFS_FILEOP_GETATTR,
165     .kf_genop = {kernfs_default_fileop_getattr} },
166   { .kf_fileop = KERNFS_FILEOP_IOCTL },
167   { .kf_fileop = KERNFS_FILEOP_CLOSE },
168   { .kf_fileop = KERNFS_FILEOP_WRITE, .kf_genop = {kernfs_default_xwrite} },
169 };
170 
171 int	kernfs_lookup	__P((void *));
172 #define	kernfs_create	genfs_eopnotsupp
173 #define	kernfs_mknod	genfs_eopnotsupp
174 int	kernfs_open	__P((void *));
175 int	kernfs_close	__P((void *));
176 int	kernfs_access	__P((void *));
177 int	kernfs_getattr	__P((void *));
178 int	kernfs_setattr	__P((void *));
179 int	kernfs_read	__P((void *));
180 int	kernfs_write	__P((void *));
181 #define	kernfs_fcntl	genfs_fcntl
182 int	kernfs_ioctl	__P((void *));
183 #define	kernfs_poll	genfs_poll
184 #define kernfs_revoke	genfs_revoke
185 #define	kernfs_fsync	genfs_nullop
186 #define	kernfs_seek	genfs_nullop
187 #define	kernfs_remove	genfs_eopnotsupp
188 int	kernfs_link	__P((void *));
189 #define	kernfs_rename	genfs_eopnotsupp
190 #define	kernfs_mkdir	genfs_eopnotsupp
191 #define	kernfs_rmdir	genfs_eopnotsupp
192 int	kernfs_symlink	__P((void *));
193 int	kernfs_readdir	__P((void *));
194 #define	kernfs_readlink	genfs_eopnotsupp
195 #define	kernfs_abortop	genfs_abortop
196 int	kernfs_inactive	__P((void *));
197 int	kernfs_reclaim	__P((void *));
198 #define	kernfs_lock	genfs_lock
199 #define	kernfs_unlock	genfs_unlock
200 #define	kernfs_bmap	genfs_badop
201 #define	kernfs_strategy	genfs_badop
202 int	kernfs_print	__P((void *));
203 #define	kernfs_islocked	genfs_islocked
204 int	kernfs_pathconf	__P((void *));
205 #define	kernfs_advlock	genfs_einval
206 #define	kernfs_blkatoff	genfs_eopnotsupp
207 #define	kernfs_valloc	genfs_eopnotsupp
208 #define	kernfs_vfree	genfs_nullop
209 #define	kernfs_truncate	genfs_eopnotsupp
210 #define	kernfs_update	genfs_nullop
211 #define	kernfs_bwrite	genfs_eopnotsupp
212 #define	kernfs_putpages	genfs_putpages
213 
214 static int	kernfs_xread __P((struct kernfs_node *, int, char **, size_t, size_t *));
215 static int	kernfs_xwrite __P((const struct kernfs_node *, char *, size_t));
216 
217 int (**kernfs_vnodeop_p) __P((void *));
218 const struct vnodeopv_entry_desc kernfs_vnodeop_entries[] = {
219 	{ &vop_default_desc, vn_default_error },
220 	{ &vop_lookup_desc, kernfs_lookup },		/* lookup */
221 	{ &vop_create_desc, kernfs_create },		/* create */
222 	{ &vop_mknod_desc, kernfs_mknod },		/* mknod */
223 	{ &vop_open_desc, kernfs_open },		/* open */
224 	{ &vop_close_desc, kernfs_close },		/* close */
225 	{ &vop_access_desc, kernfs_access },		/* access */
226 	{ &vop_getattr_desc, kernfs_getattr },		/* getattr */
227 	{ &vop_setattr_desc, kernfs_setattr },		/* setattr */
228 	{ &vop_read_desc, kernfs_read },		/* read */
229 	{ &vop_write_desc, kernfs_write },		/* write */
230 	{ &vop_fcntl_desc, kernfs_fcntl },		/* fcntl */
231 	{ &vop_ioctl_desc, kernfs_ioctl },		/* ioctl */
232 	{ &vop_poll_desc, kernfs_poll },		/* poll */
233 	{ &vop_revoke_desc, kernfs_revoke },		/* revoke */
234 	{ &vop_fsync_desc, kernfs_fsync },		/* fsync */
235 	{ &vop_seek_desc, kernfs_seek },		/* seek */
236 	{ &vop_remove_desc, kernfs_remove },		/* remove */
237 	{ &vop_link_desc, kernfs_link },		/* link */
238 	{ &vop_rename_desc, kernfs_rename },		/* rename */
239 	{ &vop_mkdir_desc, kernfs_mkdir },		/* mkdir */
240 	{ &vop_rmdir_desc, kernfs_rmdir },		/* rmdir */
241 	{ &vop_symlink_desc, kernfs_symlink },		/* symlink */
242 	{ &vop_readdir_desc, kernfs_readdir },		/* readdir */
243 	{ &vop_readlink_desc, kernfs_readlink },	/* readlink */
244 	{ &vop_abortop_desc, kernfs_abortop },		/* abortop */
245 	{ &vop_inactive_desc, kernfs_inactive },	/* inactive */
246 	{ &vop_reclaim_desc, kernfs_reclaim },		/* reclaim */
247 	{ &vop_lock_desc, kernfs_lock },		/* lock */
248 	{ &vop_unlock_desc, kernfs_unlock },		/* unlock */
249 	{ &vop_bmap_desc, kernfs_bmap },		/* bmap */
250 	{ &vop_strategy_desc, kernfs_strategy },	/* strategy */
251 	{ &vop_print_desc, kernfs_print },		/* print */
252 	{ &vop_islocked_desc, kernfs_islocked },	/* islocked */
253 	{ &vop_pathconf_desc, kernfs_pathconf },	/* pathconf */
254 	{ &vop_advlock_desc, kernfs_advlock },		/* advlock */
255 	{ &vop_blkatoff_desc, kernfs_blkatoff },	/* blkatoff */
256 	{ &vop_valloc_desc, kernfs_valloc },		/* valloc */
257 	{ &vop_vfree_desc, kernfs_vfree },		/* vfree */
258 	{ &vop_truncate_desc, kernfs_truncate },	/* truncate */
259 	{ &vop_update_desc, kernfs_update },		/* update */
260 	{ &vop_bwrite_desc, kernfs_bwrite },		/* bwrite */
261 	{ &vop_putpages_desc, kernfs_putpages },	/* putpages */
262 	{ NULL, NULL }
263 };
264 const struct vnodeopv_desc kernfs_vnodeop_opv_desc =
265 	{ &kernfs_vnodeop_p, kernfs_vnodeop_entries };
266 
267 static __inline int
268 kernfs_fileop_compare(struct kernfs_fileop *a, struct kernfs_fileop *b)
269 {
270 	if (a->kf_type < b->kf_type)
271 		return -1;
272 	if (a->kf_type > b->kf_type)
273 		return 1;
274 	if (a->kf_fileop < b->kf_fileop)
275 		return -1;
276 	if (a->kf_fileop > b->kf_fileop)
277 		return 1;
278 	return (0);
279 }
280 
281 SPLAY_HEAD(kfsfileoptree, kernfs_fileop) kfsfileoptree =
282 	SPLAY_INITIALIZER(kfsfileoptree);
283 SPLAY_PROTOTYPE(kfsfileoptree, kernfs_fileop, kf_node, kernfs_fileop_compare);
284 SPLAY_GENERATE(kfsfileoptree, kernfs_fileop, kf_node, kernfs_fileop_compare);
285 
286 kfstype
287 kernfs_alloctype(int nkf, const struct kernfs_fileop *kf)
288 {
289 	static u_char nextfreetype = KFSlasttype;
290 	struct kernfs_fileop *dkf, *fkf, skf;
291 	int i;
292 
293 	/* XXX need to keep track of dkf's memory if we support
294            deallocating types */
295 	dkf = malloc(sizeof(kernfs_default_fileops), M_TEMP, M_WAITOK);
296 	memcpy(dkf, kernfs_default_fileops, sizeof(kernfs_default_fileops));
297 
298 	for (i = 0; i < sizeof(kernfs_default_fileops) /
299 		     sizeof(kernfs_default_fileops[0]); i++) {
300 		dkf[i].kf_type = nextfreetype;
301 		SPLAY_INSERT(kfsfileoptree, &kfsfileoptree, &dkf[i]);
302 	}
303 
304 	for (i = 0; i < nkf; i++) {
305 		skf.kf_type = nextfreetype;
306 		skf.kf_fileop = kf[i].kf_fileop;
307 		if ((fkf = SPLAY_FIND(kfsfileoptree, &kfsfileoptree, &skf)))
308 			fkf->kf_genop = kf[i].kf_genop;
309 	}
310 
311 	return nextfreetype++;
312 }
313 
314 int
315 kernfs_try_fileop(kfstype type, kfsfileop fileop, void *v, int error)
316 {
317 	struct kernfs_fileop *kf, skf;
318 
319 	skf.kf_type = type;
320 	skf.kf_fileop = fileop;
321 	if ((kf = SPLAY_FIND(kfsfileoptree, &kfsfileoptree, &skf)))
322 		if (kf->kf_vop)
323 			return kf->kf_vop(v);
324 	return error;
325 }
326 
327 int
328 kernfs_try_xwrite(kfstype type, const struct kernfs_node *kfs, char *bf,
329     size_t len, int error)
330 {
331 	struct kernfs_fileop *kf, skf;
332 
333 	skf.kf_type = type;
334 	skf.kf_fileop = KERNFS_XWRITE;
335 	if ((kf = SPLAY_FIND(kfsfileoptree, &kfsfileoptree, &skf)))
336 		if (kf->kf_xwrite)
337 			return kf->kf_xwrite(kfs, bf, len);
338 	return error;
339 }
340 
341 int
342 kernfs_addentry(kernfs_parentdir_t *pkt, kernfs_entry_t *dkt)
343 {
344 	struct kernfs_subdir *ks, *parent;
345 
346 	if (pkt == NULL) {
347 		SIMPLEQ_INSERT_TAIL(&dyn_kern_targets, dkt, dkt_queue);
348 		nkern_targets++;
349 		if (dkt->dkt_kt.kt_vtype == VDIR)
350 			nkern_dirs++;
351 	} else {
352 		parent = (struct kernfs_subdir *)pkt->kt_data;
353 		SIMPLEQ_INSERT_TAIL(&parent->ks_entries, dkt, dkt_queue);
354 		parent->ks_nentries++;
355 		if (dkt->dkt_kt.kt_vtype == VDIR)
356 			parent->ks_dirs++;
357 	}
358 	if (dkt->dkt_kt.kt_vtype == VDIR && dkt->dkt_kt.kt_data == NULL) {
359 		ks = malloc(sizeof(struct kernfs_subdir),
360 		    M_TEMP, M_WAITOK);
361 		SIMPLEQ_INIT(&ks->ks_entries);
362 		ks->ks_nentries = 2; /* . and .. */
363 		ks->ks_dirs = 2;
364 		ks->ks_parent = pkt ? pkt : &kern_targets[0];
365 		dkt->dkt_kt.kt_data = ks;
366 	}
367 	return 0;
368 }
369 
370 static int
371 kernfs_xread(kfs, off, bufp, len, wrlen)
372 	struct kernfs_node *kfs;
373 	int off;
374 	char **bufp;
375 	size_t len;
376 	size_t *wrlen;
377 {
378 	const struct kern_target *kt;
379 #ifdef IPSEC
380 	struct mbuf *m;
381 #endif
382 
383 	kt = kfs->kfs_kt;
384 
385 	switch (kfs->kfs_type) {
386 	case KFStime: {
387 		struct timeval tv;
388 
389 		microtime(&tv);
390 		snprintf(*bufp, len, "%ld %ld\n", tv.tv_sec, tv.tv_usec);
391 		break;
392 	}
393 
394 	case KFSint: {
395 		int *ip = kt->kt_data;
396 
397 		snprintf(*bufp, len, "%d\n", *ip);
398 		break;
399 	}
400 
401 	case KFSstring: {
402 		char *cp = kt->kt_data;
403 
404 		*bufp = cp;
405 		break;
406 	}
407 
408 	case KFSmsgbuf: {
409 		long n;
410 
411 		/*
412 		 * deal with cases where the message buffer has
413 		 * become corrupted.
414 		 */
415 		if (!msgbufenabled || msgbufp->msg_magic != MSG_MAGIC) {
416 			msgbufenabled = 0;
417 			return (ENXIO);
418 		}
419 
420 		/*
421 		 * Note that reads of /kern/msgbuf won't necessarily yield
422 		 * consistent results, if the message buffer is modified
423 		 * while the read is in progress.  The worst that can happen
424 		 * is that incorrect data will be read.  There's no way
425 		 * that this can crash the system unless the values in the
426 		 * message buffer header are corrupted, but that'll cause
427 		 * the system to die anyway.
428 		 */
429 		if (off >= msgbufp->msg_bufs) {
430 			*wrlen = 0;
431 			return (0);
432 		}
433 		n = msgbufp->msg_bufx + off;
434 		if (n >= msgbufp->msg_bufs)
435 			n -= msgbufp->msg_bufs;
436 		len = min(msgbufp->msg_bufs - n, msgbufp->msg_bufs - off);
437 		*bufp = msgbufp->msg_bufc + n;
438 		*wrlen = len;
439 		return (0);
440 	}
441 
442 	case KFShostname: {
443 		char *cp = hostname;
444 		int xlen = hostnamelen;
445 
446 		if (xlen >= (len - 2))
447 			return (EINVAL);
448 
449 		memcpy(*bufp, cp, xlen);
450 		(*bufp)[xlen] = '\n';
451 		(*bufp)[xlen+1] = '\0';
452 		len = strlen(*bufp);
453 		break;
454 	}
455 
456 	case KFSavenrun:
457 		averunnable.fscale = FSCALE;
458 		snprintf(*bufp, len, "%d %d %d %ld\n",
459 		    averunnable.ldavg[0], averunnable.ldavg[1],
460 		    averunnable.ldavg[2], averunnable.fscale);
461 		break;
462 
463 #ifdef IPSEC
464 	case KFSipsecsa:
465 		/*
466 		 * Note that SA configuration could be changed during the
467 		 * read operation, resulting in garbled output.
468 		 */
469 		m = key_setdumpsa_spi(htonl(kfs->kfs_value));
470 		if (!m)
471 			return (ENOBUFS);
472 		if (off >= m->m_pkthdr.len) {
473 			*wrlen = 0;
474 			m_freem(m);
475 			return (0);
476 		}
477 		if (len > m->m_pkthdr.len - off)
478 			len = m->m_pkthdr.len - off;
479 		m_copydata(m, off, len, *bufp);
480 		*wrlen = len;
481 		m_freem(m);
482 		return (0);
483 
484 	case KFSipsecsp:
485 		/*
486 		 * Note that SP configuration could be changed during the
487 		 * read operation, resulting in garbled output.
488 		 */
489 		if (!kfs->kfs_v) {
490 			struct secpolicy *sp;
491 
492 			sp = key_getspbyid(kfs->kfs_value);
493 			if (sp)
494 				kfs->kfs_v = sp;
495 			else
496 				return (ENOENT);
497 		}
498 		m = key_setdumpsp((struct secpolicy *)kfs->kfs_v,
499 		    SADB_X_SPDGET, 0, 0);
500 		if (!m)
501 			return (ENOBUFS);
502 		if (off >= m->m_pkthdr.len) {
503 			*wrlen = 0;
504 			m_freem(m);
505 			return (0);
506 		}
507 		if (len > m->m_pkthdr.len - off)
508 			len = m->m_pkthdr.len - off;
509 		m_copydata(m, off, len, *bufp);
510 		*wrlen = len;
511 		m_freem(m);
512 		return (0);
513 #endif
514 
515 	default:
516 		*wrlen = 0;
517 		return (0);
518 	}
519 
520 	len = strlen(*bufp);
521 	if (len <= off)
522 		*wrlen = 0;
523 	else {
524 		*bufp += off;
525 		*wrlen = len - off;
526 	}
527 	return (0);
528 }
529 
530 static int
531 kernfs_xwrite(kfs, bf, len)
532 	const struct kernfs_node *kfs;
533 	char *bf;
534 	size_t len;
535 {
536 
537 	switch (kfs->kfs_type) {
538 	case KFShostname:
539 		if (bf[len-1] == '\n')
540 			--len;
541 		memcpy(hostname, bf, len);
542 		hostname[len] = '\0';
543 		hostnamelen = (size_t) len;
544 		return (0);
545 
546 	default:
547 		return kernfs_try_xwrite(kfs->kfs_type, kfs, bf, len, EIO);
548 	}
549 }
550 
551 
552 /*
553  * vp is the current namei directory
554  * ndp is the name to locate in that directory...
555  */
556 int
557 kernfs_lookup(v)
558 	void *v;
559 {
560 	struct vop_lookup_args /* {
561 		struct vnode * a_dvp;
562 		struct vnode ** a_vpp;
563 		struct componentname * a_cnp;
564 	} */ *ap = v;
565 	struct componentname *cnp = ap->a_cnp;
566 	struct vnode **vpp = ap->a_vpp;
567 	struct vnode *dvp = ap->a_dvp;
568 	const char *pname = cnp->cn_nameptr;
569 	const struct kernfs_node *kfs;
570 	const struct kern_target *kt;
571 	const struct dyn_kern_target *dkt;
572 	const struct kernfs_subdir *ks;
573 	int error, i, wantpunlock;
574 #ifdef IPSEC
575 	char *ep;
576 	u_int32_t id;
577 #endif
578 
579 	*vpp = NULLVP;
580 	cnp->cn_flags &= ~PDIRUNLOCK;
581 
582 	if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)
583 		return (EROFS);
584 
585 	if (cnp->cn_namelen == 1 && *pname == '.') {
586 		*vpp = dvp;
587 		VREF(dvp);
588 		return (0);
589 	}
590 
591 	wantpunlock = (~cnp->cn_flags & (LOCKPARENT | ISLASTCN));
592 	kfs = VTOKERN(dvp);
593 	switch (kfs->kfs_type) {
594 	case KFSkern:
595 		/*
596 		 * Shouldn't get here with .. in the root node.
597 		 */
598 		if (cnp->cn_flags & ISDOTDOT)
599 			return (EIO);
600 
601 		for (i = 0; i < static_nkern_targets; i++) {
602 			kt = &kern_targets[i];
603 			if (cnp->cn_namelen == kt->kt_namlen &&
604 			    memcmp(kt->kt_name, pname, cnp->cn_namelen) == 0)
605 				goto found;
606 		}
607 		SIMPLEQ_FOREACH(dkt, &dyn_kern_targets, dkt_queue) {
608 			if (cnp->cn_namelen == dkt->dkt_kt.kt_namlen &&
609 			    memcmp(dkt->dkt_kt.kt_name, pname, cnp->cn_namelen) == 0) {
610 				kt = &dkt->dkt_kt;
611 				goto found;
612 			}
613 		}
614 		break;
615 
616 	found:
617 		error = kernfs_allocvp(dvp->v_mount, vpp, kt->kt_tag, kt, 0);
618 		if ((error == 0) && wantpunlock) {
619 			VOP_UNLOCK(dvp, 0);
620 			cnp->cn_flags |= PDIRUNLOCK;
621 		}
622 		return (error);
623 
624 	case KFSsubdir:
625 		ks = (struct kernfs_subdir *)kfs->kfs_kt->kt_data;
626 		if (cnp->cn_flags & ISDOTDOT) {
627 			kt = ks->ks_parent;
628 			goto found;
629 		}
630 
631 		SIMPLEQ_FOREACH(dkt, &ks->ks_entries, dkt_queue) {
632 			if (cnp->cn_namelen == dkt->dkt_kt.kt_namlen &&
633 			    memcmp(dkt->dkt_kt.kt_name, pname, cnp->cn_namelen) == 0) {
634 				kt = &dkt->dkt_kt;
635 				goto found;
636 			}
637 		}
638 		break;
639 
640 #ifdef IPSEC
641 	case KFSipsecsadir:
642 		if (cnp->cn_flags & ISDOTDOT) {
643 			kt = &kern_targets[0];
644 			goto found;
645 		}
646 
647 		for (i = 2; i < nipsecsa_targets; i++) {
648 			kt = &ipsecsa_targets[i];
649 			if (cnp->cn_namelen == kt->kt_namlen &&
650 			    memcmp(kt->kt_name, pname, cnp->cn_namelen) == 0)
651 				goto found;
652 		}
653 
654 		ep = NULL;
655 		id = strtoul(pname, &ep, 10);
656 		if (!ep || *ep || ep == pname)
657 			break;
658 
659 		error = kernfs_allocvp(dvp->v_mount, vpp, KFSipsecsa, &ipsecsa_kt, id);
660 		if ((error == 0) && wantpunlock) {
661 			VOP_UNLOCK(dvp, 0);
662 			cnp->cn_flags |= PDIRUNLOCK;
663 		}
664 		return (error);
665 
666 	case KFSipsecspdir:
667 		if (cnp->cn_flags & ISDOTDOT) {
668 			kt = &kern_targets[0];
669 			goto found;
670 		}
671 
672 		for (i = 2; i < nipsecsp_targets; i++) {
673 			kt = &ipsecsp_targets[i];
674 			if (cnp->cn_namelen == kt->kt_namlen &&
675 			    memcmp(kt->kt_name, pname, cnp->cn_namelen) == 0)
676 				goto found;
677 		}
678 
679 		ep = NULL;
680 		id = strtoul(pname, &ep, 10);
681 		if (!ep || *ep || ep == pname)
682 			break;
683 
684 		error = kernfs_allocvp(dvp->v_mount, vpp, KFSipsecsp, &ipsecsp_kt, id);
685 		if ((error == 0) && wantpunlock) {
686 			VOP_UNLOCK(dvp, 0);
687 			cnp->cn_flags |= PDIRUNLOCK;
688 		}
689 		return (error);
690 #endif
691 
692 	default:
693 		return (ENOTDIR);
694 	}
695 
696 	return (cnp->cn_nameiop == LOOKUP ? ENOENT : EROFS);
697 }
698 
699 int
700 kernfs_open(v)
701 	void *v;
702 {
703 	struct vop_open_args /* {
704 		struct vnode *a_vp;
705 		int a_mode;
706 		struct ucred *a_cred;
707 		struct proc *a_p;
708 	} */ *ap = v;
709 	struct kernfs_node *kfs = VTOKERN(ap->a_vp);
710 #ifdef IPSEC
711 	struct mbuf *m;
712 	struct secpolicy *sp;
713 #endif
714 
715 	switch (kfs->kfs_type) {
716 #ifdef IPSEC
717 	case KFSipsecsa:
718 		m = key_setdumpsa_spi(htonl(kfs->kfs_value));
719 		if (m) {
720 			m_freem(m);
721 			return (0);
722 		} else
723 			return (ENOENT);
724 
725 	case KFSipsecsp:
726 		sp = key_getspbyid(kfs->kfs_value);
727 		if (sp) {
728 			kfs->kfs_v = sp;
729 			return (0);
730 		} else
731 			return (ENOENT);
732 #endif
733 
734 	default:
735 		return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_OPEN,
736 		    v, 0);
737 	}
738 }
739 
740 int
741 kernfs_close(v)
742 	void *v;
743 {
744 	struct vop_close_args /* {
745 		struct vnode *a_vp;
746 		int a_fflag;
747 		struct ucred *a_cred;
748 		struct proc *a_p;
749 	} */ *ap = v;
750 	struct kernfs_node *kfs = VTOKERN(ap->a_vp);
751 
752 	switch (kfs->kfs_type) {
753 #ifdef IPSEC
754 	case KFSipsecsp:
755 		key_freesp((struct secpolicy *)kfs->kfs_v);
756 		break;
757 #endif
758 
759 	default:
760 		return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_CLOSE,
761 		    v, 0);
762 	}
763 
764 	return (0);
765 }
766 
767 int
768 kernfs_access(v)
769 	void *v;
770 {
771 	struct vop_access_args /* {
772 		struct vnode *a_vp;
773 		int a_mode;
774 		struct ucred *a_cred;
775 		struct proc *a_p;
776 	} */ *ap = v;
777 	struct vattr va;
778 	int error;
779 
780 	if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred, ap->a_p)) != 0)
781 		return (error);
782 
783 	return (vaccess(va.va_type, va.va_mode, va.va_uid, va.va_gid,
784 	    ap->a_mode, ap->a_cred));
785 }
786 
787 static int
788 kernfs_default_fileop_getattr(v)
789 	void *v;
790 {
791 	struct vop_getattr_args /* {
792 		struct vnode *a_vp;
793 		struct vattr *a_vap;
794 		struct ucred *a_cred;
795 		struct proc *a_p;
796 	} */ *ap = v;
797 	struct vattr *vap = ap->a_vap;
798 
799 	vap->va_nlink = 1;
800 	vap->va_bytes = vap->va_size = 0;
801 
802 	return 0;
803 }
804 
805 int
806 kernfs_getattr(v)
807 	void *v;
808 {
809 	struct vop_getattr_args /* {
810 		struct vnode *a_vp;
811 		struct vattr *a_vap;
812 		struct ucred *a_cred;
813 		struct proc *a_p;
814 	} */ *ap = v;
815 	struct kernfs_node *kfs = VTOKERN(ap->a_vp);
816 	struct kernfs_subdir *ks;
817 	struct vattr *vap = ap->a_vap;
818 	int error = 0;
819 	char strbuf[KSTRING], *bf;
820 	size_t nread, total;
821 
822 	VATTR_NULL(vap);
823 	vap->va_type = ap->a_vp->v_type;
824 	vap->va_uid = 0;
825 	vap->va_gid = 0;
826 	vap->va_mode = kfs->kfs_mode;
827 	vap->va_fileid = kfs->kfs_fileno;
828 	vap->va_flags = 0;
829 	vap->va_size = 0;
830 	vap->va_blocksize = DEV_BSIZE;
831 	/*
832 	 * Make all times be current TOD, except for the "boottime" node.
833 	 * Avoid microtime(9), it's slow.
834 	 * We don't guard the read from time(9) with splclock(9) since we
835 	 * don't actually need to be THAT sure the access is atomic.
836 	 */
837 	if (kfs->kfs_kt && kfs->kfs_kt->kt_namlen == 8 &&
838 	    !memcmp(kfs->kfs_kt->kt_name, "boottime", 8)) {
839 		TIMEVAL_TO_TIMESPEC(&boottime, &vap->va_ctime);
840 	} else {
841 		TIMEVAL_TO_TIMESPEC(&time, &vap->va_ctime);
842 	}
843 	vap->va_atime = vap->va_mtime = vap->va_ctime;
844 	vap->va_gen = 0;
845 	vap->va_flags = 0;
846 	vap->va_rdev = 0;
847 	vap->va_bytes = 0;
848 
849 	switch (kfs->kfs_type) {
850 	case KFSkern:
851 		vap->va_nlink = nkern_dirs;
852 		vap->va_bytes = vap->va_size = DEV_BSIZE;
853 		break;
854 
855 	case KFSroot:
856 		vap->va_nlink = 1;
857 		vap->va_bytes = vap->va_size = DEV_BSIZE;
858 		break;
859 
860 	case KFSsubdir:
861 		ks = (struct kernfs_subdir *)kfs->kfs_kt->kt_data;
862 		vap->va_nlink = ks->ks_dirs;
863 		vap->va_bytes = vap->va_size = DEV_BSIZE;
864 		break;
865 
866 	case KFSnull:
867 	case KFStime:
868 	case KFSint:
869 	case KFSstring:
870 	case KFShostname:
871 	case KFSavenrun:
872 	case KFSdevice:
873 	case KFSmsgbuf:
874 #ifdef IPSEC
875 	case KFSipsecsa:
876 	case KFSipsecsp:
877 #endif
878 		vap->va_nlink = 1;
879 		total = 0;
880 		do {
881 			bf = strbuf;
882 			error = kernfs_xread(kfs, total, &bf,
883 			    sizeof(strbuf), &nread);
884 			total += nread;
885 		} while (error == 0 && nread != 0);
886 		vap->va_bytes = vap->va_size = total;
887 		break;
888 
889 #ifdef IPSEC
890 	case KFSipsecsadir:
891 	case KFSipsecspdir:
892 		vap->va_nlink = 2;
893 		vap->va_bytes = vap->va_size = DEV_BSIZE;
894 		break;
895 #endif
896 
897 	default:
898 		error = kernfs_try_fileop(kfs->kfs_type,
899 		    KERNFS_FILEOP_GETATTR, v, EINVAL);
900 		break;
901 	}
902 
903 	return (error);
904 }
905 
906 /*ARGSUSED*/
907 int
908 kernfs_setattr(v)
909 	void *v;
910 {
911 
912 	/*
913 	 * Silently ignore attribute changes.
914 	 * This allows for open with truncate to have no
915 	 * effect until some data is written.  I want to
916 	 * do it this way because all writes are atomic.
917 	 */
918 	return (0);
919 }
920 
921 int
922 kernfs_read(v)
923 	void *v;
924 {
925 	struct vop_read_args /* {
926 		struct vnode *a_vp;
927 		struct uio *a_uio;
928 		int  a_ioflag;
929 		struct ucred *a_cred;
930 	} */ *ap = v;
931 	struct uio *uio = ap->a_uio;
932 	struct kernfs_node *kfs = VTOKERN(ap->a_vp);
933 	char strbuf[KSTRING], *bf;
934 	off_t off;
935 	size_t len;
936 	int error;
937 
938 	if (ap->a_vp->v_type == VDIR)
939 		return (EOPNOTSUPP);
940 
941 	off = uio->uio_offset;
942 	bf = strbuf;
943 	if ((error = kernfs_xread(kfs, off, &bf, sizeof(strbuf), &len)) == 0)
944 		error = uiomove(bf, len, uio);
945 	return (error);
946 }
947 
948 static int
949 kernfs_default_xwrite(v)
950 	void *v;
951 {
952 	struct vop_write_args /* {
953 		struct vnode *a_vp;
954 		struct uio *a_uio;
955 		int  a_ioflag;
956 		struct ucred *a_cred;
957 	} */ *ap = v;
958 	struct kernfs_node *kfs = VTOKERN(ap->a_vp);
959 	struct uio *uio = ap->a_uio;
960 	int error, xlen;
961 	char strbuf[KSTRING];
962 
963 	if (uio->uio_offset != 0)
964 		return (EINVAL);
965 
966 	xlen = min(uio->uio_resid, KSTRING-1);
967 	if ((error = uiomove(strbuf, xlen, uio)) != 0)
968 		return (error);
969 
970 	if (uio->uio_resid != 0)
971 		return (EIO);
972 
973 	strbuf[xlen] = '\0';
974 	xlen = strlen(strbuf);
975 	return (kernfs_xwrite(kfs, strbuf, xlen));
976 }
977 
978 int
979 kernfs_write(v)
980 	void *v;
981 {
982 	struct vop_write_args /* {
983 		struct vnode *a_vp;
984 		struct uio *a_uio;
985 		int  a_ioflag;
986 		struct ucred *a_cred;
987 	} */ *ap = v;
988 	struct kernfs_node *kfs = VTOKERN(ap->a_vp);
989 
990 	return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_WRITE, v, 0);
991 }
992 
993 int
994 kernfs_ioctl(v)
995 	void *v;
996 {
997 	struct vop_ioctl_args /* {
998 		const struct vnodeop_desc *a_desc;
999 		struct vnode *a_vp;
1000 		u_long a_command;
1001 		void *a_data;
1002 		int a_fflag;
1003 		struct ucred *a_cred;
1004 		struct proc *a_p;
1005 	} */ *ap = v;
1006 	struct kernfs_node *kfs = VTOKERN(ap->a_vp);
1007 
1008 	return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_IOCTL, v,
1009 	    EPASSTHROUGH);
1010 }
1011 
1012 static int
1013 kernfs_setdirentfileno_kt(struct dirent *d, const struct kern_target *kt,
1014     u_int32_t value, struct vop_readdir_args *ap)
1015 {
1016 	struct kernfs_node *kfs;
1017 	struct vnode *vp;
1018 	int error;
1019 
1020 	if ((error = kernfs_allocvp(ap->a_vp->v_mount, &vp, kt->kt_tag, kt,
1021 	    value)) != 0)
1022 		return error;
1023 	if (kt->kt_tag == KFSdevice) {
1024 		struct vattr va;
1025 		if ((error = VOP_GETATTR(vp, &va, ap->a_cred,
1026 		    ap->a_uio->uio_segflg == UIO_USERSPACE ?
1027 		    ap->a_uio->uio_procp : &proc0)) != 0)
1028 			return (error);
1029 		d->d_fileno = va.va_fileid;
1030 	} else {
1031 		kfs = VTOKERN(vp);
1032 		d->d_fileno = kfs->kfs_fileno;
1033 	}
1034 	vput(vp);
1035 	return 0;
1036 }
1037 
1038 static int
1039 kernfs_setdirentfileno(struct dirent *d, off_t entry,
1040     struct kernfs_node *thisdir_kfs, const struct kern_target *parent_kt,
1041     const struct kern_target *kt, struct vop_readdir_args *ap)
1042 {
1043 	const struct kern_target *ikt;
1044 	int error;
1045 
1046 	switch (entry) {
1047 	case 0:
1048 		d->d_fileno = thisdir_kfs->kfs_fileno;
1049 		return 0;
1050 	case 1:
1051 		ikt = parent_kt;
1052 		break;
1053 	default:
1054 		ikt = kt;
1055 		break;
1056 	}
1057 	if (ikt != thisdir_kfs->kfs_kt) {
1058 		if ((error = kernfs_setdirentfileno_kt(d, ikt, 0, ap)) != 0)
1059 			return error;
1060 	} else
1061 		d->d_fileno = thisdir_kfs->kfs_fileno;
1062 	return 0;
1063 }
1064 
1065 int
1066 kernfs_readdir(v)
1067 	void *v;
1068 {
1069 	struct vop_readdir_args /* {
1070 		struct vnode *a_vp;
1071 		struct uio *a_uio;
1072 		struct ucred *a_cred;
1073 		int *a_eofflag;
1074 		off_t **a_cookies;
1075 		int a_*ncookies;
1076 	} */ *ap = v;
1077 	struct uio *uio = ap->a_uio;
1078 	struct dirent d;
1079 	struct kernfs_node *kfs = VTOKERN(ap->a_vp);
1080 	const struct kern_target *kt;
1081 	const struct dyn_kern_target *dkt = NULL;
1082 	const struct kernfs_subdir *ks;
1083 	off_t i, j;
1084 	int error;
1085 	off_t *cookies = NULL;
1086 	int ncookies = 0, n;
1087 #ifdef IPSEC
1088 	struct secasvar *sav, *sav2;
1089 	struct secpolicy *sp;
1090 #endif
1091 
1092 	if (uio->uio_resid < UIO_MX)
1093 		return (EINVAL);
1094 	if (uio->uio_offset < 0)
1095 		return (EINVAL);
1096 
1097 	error = 0;
1098 	i = uio->uio_offset;
1099 	memset(&d, 0, sizeof(d));
1100 	d.d_reclen = UIO_MX;
1101 	ncookies = uio->uio_resid / UIO_MX;
1102 
1103 	switch (kfs->kfs_type) {
1104 	case KFSkern:
1105 		if (i >= nkern_targets)
1106 			return (0);
1107 
1108 		if (ap->a_ncookies) {
1109 			ncookies = min(ncookies, (nkern_targets - i));
1110 			cookies = malloc(ncookies * sizeof(off_t), M_TEMP,
1111 			    M_WAITOK);
1112 			*ap->a_cookies = cookies;
1113 		}
1114 
1115 		n = 0;
1116 		for (; i < nkern_targets && uio->uio_resid >= UIO_MX; i++) {
1117 			if (i < static_nkern_targets)
1118 				kt = &kern_targets[i];
1119 			else {
1120 				if (dkt == NULL) {
1121 					dkt = SIMPLEQ_FIRST(&dyn_kern_targets);
1122 					for (j = static_nkern_targets; j < i &&
1123 						     dkt != NULL; j++)
1124 						dkt = SIMPLEQ_NEXT(dkt, dkt_queue);
1125 					if (j != i)
1126 						break;
1127 				} else {
1128 					dkt = SIMPLEQ_NEXT(dkt, dkt_queue);
1129 					if (dkt == NULL)
1130 						break;
1131 				}
1132 				kt = &dkt->dkt_kt;
1133 			}
1134 			if (kt->kt_tag == KFSdevice) {
1135 				dev_t *dp = kt->kt_data;
1136 				struct vnode *fvp;
1137 
1138 				if (*dp == NODEV ||
1139 				    !vfinddev(*dp, kt->kt_vtype, &fvp))
1140 					continue;
1141 			}
1142 			d.d_namlen = kt->kt_namlen;
1143 			if ((error = kernfs_setdirentfileno(&d, i, kfs,
1144 			    &kern_targets[0], kt, ap)) != 0)
1145 				break;
1146 			memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1);
1147 			d.d_type = kt->kt_type;
1148 			if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1149 				break;
1150 			if (cookies)
1151 				*cookies++ = i + 1;
1152 			n++;
1153 		}
1154 		ncookies = n;
1155 		break;
1156 
1157 	case KFSroot:
1158 		if (i >= 2)
1159 			return 0;
1160 
1161 		if (ap->a_ncookies) {
1162 			ncookies = min(ncookies, (2 - i));
1163 			cookies = malloc(ncookies * sizeof(off_t), M_TEMP,
1164 			    M_WAITOK);
1165 			*ap->a_cookies = cookies;
1166 		}
1167 
1168 		n = 0;
1169 		for (; i < 2 && uio->uio_resid >= UIO_MX; i++) {
1170 			kt = &kern_targets[i];
1171 			d.d_namlen = kt->kt_namlen;
1172 			d.d_fileno = KERNFS_FILENO(kt, kt->kt_tag, 0);
1173 			memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1);
1174 			d.d_type = kt->kt_type;
1175 			if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1176 				break;
1177 			if (cookies)
1178 				*cookies++ = i + 1;
1179 			n++;
1180 		}
1181 		ncookies = n;
1182 		break;
1183 
1184 	case KFSsubdir:
1185 		ks = (struct kernfs_subdir *)kfs->kfs_kt->kt_data;
1186 		if (i >= ks->ks_nentries)
1187 			return (0);
1188 
1189 		if (ap->a_ncookies) {
1190 			ncookies = min(ncookies, (ks->ks_nentries - i));
1191 			cookies = malloc(ncookies * sizeof(off_t), M_TEMP,
1192 			    M_WAITOK);
1193 			*ap->a_cookies = cookies;
1194 		}
1195 
1196 		dkt = SIMPLEQ_FIRST(&ks->ks_entries);
1197 		for (j = 0; j < i && dkt != NULL; j++)
1198 			dkt = SIMPLEQ_NEXT(dkt, dkt_queue);
1199 		n = 0;
1200 		for (; i < ks->ks_nentries && uio->uio_resid >= UIO_MX; i++) {
1201 			if (i < 2)
1202 				kt = &subdir_targets[i];
1203 			else {
1204 				/* check if ks_nentries lied to us */
1205 				if (dkt == NULL)
1206 					break;
1207 				kt = &dkt->dkt_kt;
1208 				dkt = SIMPLEQ_NEXT(dkt, dkt_queue);
1209 			}
1210 			if (kt->kt_tag == KFSdevice) {
1211 				dev_t *dp = kt->kt_data;
1212 				struct vnode *fvp;
1213 
1214 				if (*dp == NODEV ||
1215 				    !vfinddev(*dp, kt->kt_vtype, &fvp))
1216 					continue;
1217 			}
1218 			d.d_namlen = kt->kt_namlen;
1219 			if ((error = kernfs_setdirentfileno(&d, i, kfs,
1220 			    ks->ks_parent, kt, ap)) != 0)
1221 				break;
1222 			memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1);
1223 			d.d_type = kt->kt_type;
1224 			if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1225 				break;
1226 			if (cookies)
1227 				*cookies++ = i + 1;
1228 			n++;
1229 		}
1230 		ncookies = n;
1231 		break;
1232 
1233 #ifdef IPSEC
1234 	case KFSipsecsadir:
1235 		/* count SA in the system */
1236 		n = 0;
1237 		TAILQ_FOREACH(sav, &satailq, tailq) {
1238 			for (sav2 = TAILQ_FIRST(&satailq);
1239 			    sav2 != sav;
1240 			    sav2 = TAILQ_NEXT(sav2, tailq)) {
1241 				if (sav->spi == sav2->spi) {
1242 					/* multiple SA with same SPI */
1243 					break;
1244 				}
1245 			}
1246 			if (sav == sav2 || sav->spi != sav2->spi)
1247 				n++;
1248 		}
1249 
1250 		if (i >= nipsecsa_targets + n)
1251 			return (0);
1252 
1253 		if (ap->a_ncookies) {
1254 			ncookies = min(ncookies, (n - i));
1255 			cookies = malloc(ncookies * sizeof(off_t), M_TEMP,
1256 			    M_WAITOK);
1257 			*ap->a_cookies = cookies;
1258 		}
1259 
1260 		n = 0;
1261 		for (; i < nipsecsa_targets && uio->uio_resid >= UIO_MX; i++) {
1262 			kt = &ipsecsa_targets[i];
1263 			d.d_namlen = kt->kt_namlen;
1264 			if ((error = kernfs_setdirentfileno(&d, i, kfs,
1265 			    &kern_targets[0], kt, ap)) != 0)
1266 				break;
1267 			memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1);
1268 			d.d_type = kt->kt_type;
1269 			if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1270 				break;
1271 			if (cookies)
1272 				*cookies++ = i + 1;
1273 			n++;
1274 		}
1275 		if (error) {
1276 			ncookies = n;
1277 			break;
1278 		}
1279 
1280 		TAILQ_FOREACH(sav, &satailq, tailq) {
1281 			for (sav2 = TAILQ_FIRST(&satailq);
1282 			    sav2 != sav;
1283 			    sav2 = TAILQ_NEXT(sav2, tailq)) {
1284 				if (sav->spi == sav2->spi) {
1285 					/* multiple SA with same SPI */
1286 					break;
1287 				}
1288 			}
1289 			if (sav != sav2 && sav->spi == sav2->spi)
1290 				continue;
1291 			if (uio->uio_resid < UIO_MX)
1292 				break;
1293 			if ((error = kernfs_setdirentfileno_kt(&d, &ipsecsa_kt,
1294 			    sav->spi, ap)) != 0)
1295 				break;
1296 			d.d_namlen = snprintf(d.d_name, sizeof(d.d_name),
1297 			    "%u", ntohl(sav->spi));
1298 			d.d_type = DT_REG;
1299 			if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1300 				break;
1301 			if (cookies)
1302 				*cookies++ = i + 1;
1303 			n++;
1304 			i++;
1305 		}
1306 		ncookies = n;
1307 		break;
1308 
1309 	case KFSipsecspdir:
1310 		/* count SP in the system */
1311 		n = 0;
1312 		TAILQ_FOREACH(sp, &sptailq, tailq)
1313 			n++;
1314 
1315 		if (i >= nipsecsp_targets + n)
1316 			return (0);
1317 
1318 		if (ap->a_ncookies) {
1319 			ncookies = min(ncookies, (n - i));
1320 			cookies = malloc(ncookies * sizeof(off_t), M_TEMP,
1321 			    M_WAITOK);
1322 			*ap->a_cookies = cookies;
1323 		}
1324 
1325 		n = 0;
1326 		for (; i < nipsecsp_targets && uio->uio_resid >= UIO_MX; i++) {
1327 			kt = &ipsecsp_targets[i];
1328 			d.d_namlen = kt->kt_namlen;
1329 			if ((error = kernfs_setdirentfileno(&d, i, kfs,
1330 			    &kern_targets[0], kt, ap)) != 0)
1331 				break;
1332 			memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1);
1333 			d.d_type = kt->kt_type;
1334 			if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1335 				break;
1336 			if (cookies)
1337 				*cookies++ = i + 1;
1338 			n++;
1339 		}
1340 		if (error) {
1341 			ncookies = n;
1342 			break;
1343 		}
1344 
1345 		TAILQ_FOREACH(sp, &sptailq, tailq) {
1346 			if (uio->uio_resid < UIO_MX)
1347 				break;
1348 			if ((error = kernfs_setdirentfileno_kt(&d, &ipsecsp_kt,
1349 			    sp->id, ap)) != 0)
1350 				break;
1351 			d.d_namlen = snprintf(d.d_name, sizeof(d.d_name),
1352 			    "%u", sp->id);
1353 			d.d_type = DT_REG;
1354 			if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1355 				break;
1356 			if (cookies)
1357 				*cookies++ = i + 1;
1358 			n++;
1359 			i++;
1360 		}
1361 		ncookies = n;
1362 		break;
1363 #endif
1364 
1365 	default:
1366 		error = ENOTDIR;
1367 		break;
1368 	}
1369 
1370 	if (ap->a_ncookies) {
1371 		if (error) {
1372 			if (cookies)
1373 				free(*ap->a_cookies, M_TEMP);
1374 			*ap->a_ncookies = 0;
1375 			*ap->a_cookies = NULL;
1376 		} else
1377 			*ap->a_ncookies = ncookies;
1378 	}
1379 
1380 	uio->uio_offset = i;
1381 	return (error);
1382 }
1383 
1384 int
1385 kernfs_inactive(v)
1386 	void *v;
1387 {
1388 	struct vop_inactive_args /* {
1389 		struct vnode *a_vp;
1390 		struct proc *a_p;
1391 	} */ *ap = v;
1392 	struct vnode *vp = ap->a_vp;
1393 	const struct kernfs_node *kfs = VTOKERN(ap->a_vp);
1394 #ifdef IPSEC
1395 	struct mbuf *m;
1396 	struct secpolicy *sp;
1397 #endif
1398 
1399 	VOP_UNLOCK(vp, 0);
1400 	switch (kfs->kfs_type) {
1401 #ifdef IPSEC
1402 	case KFSipsecsa:
1403 		m = key_setdumpsa_spi(htonl(kfs->kfs_value));
1404 		if (m)
1405 			m_freem(m);
1406 		else
1407 			vgone(vp);
1408 		break;
1409 	case KFSipsecsp:
1410 		sp = key_getspbyid(kfs->kfs_value);
1411 		if (sp)
1412 			key_freesp(sp);
1413 		else {
1414 			/* should never happen as we hold a refcnt */
1415 			vgone(vp);
1416 		}
1417 		break;
1418 #endif
1419 	default:
1420 		break;
1421 	}
1422 	return (0);
1423 }
1424 
1425 int
1426 kernfs_reclaim(v)
1427 	void *v;
1428 {
1429 	struct vop_reclaim_args /* {
1430 		struct vnode *a_vp;
1431 	} */ *ap = v;
1432 
1433 	return (kernfs_freevp(ap->a_vp));
1434 }
1435 
1436 /*
1437  * Return POSIX pathconf information applicable to special devices.
1438  */
1439 int
1440 kernfs_pathconf(v)
1441 	void *v;
1442 {
1443 	struct vop_pathconf_args /* {
1444 		struct vnode *a_vp;
1445 		int a_name;
1446 		register_t *a_retval;
1447 	} */ *ap = v;
1448 
1449 	switch (ap->a_name) {
1450 	case _PC_LINK_MAX:
1451 		*ap->a_retval = LINK_MAX;
1452 		return (0);
1453 	case _PC_MAX_CANON:
1454 		*ap->a_retval = MAX_CANON;
1455 		return (0);
1456 	case _PC_MAX_INPUT:
1457 		*ap->a_retval = MAX_INPUT;
1458 		return (0);
1459 	case _PC_PIPE_BUF:
1460 		*ap->a_retval = PIPE_BUF;
1461 		return (0);
1462 	case _PC_CHOWN_RESTRICTED:
1463 		*ap->a_retval = 1;
1464 		return (0);
1465 	case _PC_VDISABLE:
1466 		*ap->a_retval = _POSIX_VDISABLE;
1467 		return (0);
1468 	case _PC_SYNC_IO:
1469 		*ap->a_retval = 1;
1470 		return (0);
1471 	default:
1472 		return (EINVAL);
1473 	}
1474 	/* NOTREACHED */
1475 }
1476 
1477 /*
1478  * Print out the contents of a /dev/fd vnode.
1479  */
1480 /* ARGSUSED */
1481 int
1482 kernfs_print(v)
1483 	void *v;
1484 {
1485 
1486 	printf("tag VT_KERNFS, kernfs vnode\n");
1487 	return (0);
1488 }
1489 
1490 int
1491 kernfs_link(v)
1492 	void *v;
1493 {
1494 	struct vop_link_args /* {
1495 		struct vnode *a_dvp;
1496 		struct vnode *a_vp;
1497 		struct componentname *a_cnp;
1498 	} */ *ap = v;
1499 
1500 	VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
1501 	vput(ap->a_dvp);
1502 	return (EROFS);
1503 }
1504 
1505 int
1506 kernfs_symlink(v)
1507 	void *v;
1508 {
1509 	struct vop_symlink_args /* {
1510 		struct vnode *a_dvp;
1511 		struct vnode **a_vpp;
1512 		struct componentname *a_cnp;
1513 		struct vattr *a_vap;
1514 		char *a_target;
1515 	} */ *ap = v;
1516 
1517 	VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
1518 	vput(ap->a_dvp);
1519 	return (EROFS);
1520 }
1521