version 1.101, 2004/05/07 15:06:15 |
version 1.102, 2004/05/07 15:33:17 |
Line 80 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 80 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#define READ_MODE (S_IRUSR|S_IRGRP|S_IROTH) |
#define READ_MODE (S_IRUSR|S_IRGRP|S_IROTH) |
#define WRITE_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH) |
#define WRITE_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH) |
#define UREAD_MODE (S_IRUSR) |
#define UREAD_MODE (S_IRUSR) |
#define DIR_MODE (S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) |
#define DIR_MODE (S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) |
#define UDIR_MODE (S_IRUSR|S_IXUSR) |
#define UDIR_MODE (S_IRUSR|S_IXUSR) |
|
|
#define N(s) sizeof(s)-1, s |
#define N(s) sizeof(s)-1, s |
const struct kern_target kern_targets[] = { |
const struct kern_target kern_targets[] = { |
Line 113 const struct kern_target kern_targets[] |
|
Line 113 const struct kern_target kern_targets[] |
|
{ DT_REG, N("version"), (void *)version, |
{ DT_REG, N("version"), (void *)version, |
KFSstring, VREG, READ_MODE }, |
KFSstring, VREG, READ_MODE }, |
}; |
}; |
|
const struct kern_target subdir_targets[] = { |
|
/* NOTE: The name must be less than UIO_MX-16 chars in length */ |
|
/* name data tag type ro/rw */ |
|
{ DT_DIR, N("."), 0, KFSsubdir, VDIR, DIR_MODE }, |
|
{ DT_DIR, N(".."), 0, KFSkern, VDIR, DIR_MODE }, |
|
}; |
#ifdef IPSEC |
#ifdef IPSEC |
const struct kern_target ipsecsa_targets[] = { |
const struct kern_target ipsecsa_targets[] = { |
/* NOTE: The name must be less than UIO_MX-16 chars in length */ |
/* NOTE: The name must be less than UIO_MX-16 chars in length */ |
Line 132 const struct kern_target ipsecsp_kt = |
|
Line 138 const struct kern_target ipsecsp_kt = |
|
{ DT_DIR, N(""), 0, KFSipsecsp, VREG, UREAD_MODE }; |
{ DT_DIR, N(""), 0, KFSipsecsp, VREG, UREAD_MODE }; |
#endif |
#endif |
#undef N |
#undef N |
|
SIMPLEQ_HEAD(,dyn_kern_target) dyn_kern_targets = |
|
SIMPLEQ_HEAD_INITIALIZER(dyn_kern_targets); |
int nkern_targets = sizeof(kern_targets) / sizeof(kern_targets[0]); |
int nkern_targets = sizeof(kern_targets) / sizeof(kern_targets[0]); |
|
const int static_nkern_targets = sizeof(kern_targets) / sizeof(kern_targets[0]); |
#ifdef IPSEC |
#ifdef IPSEC |
int nipsecsa_targets = sizeof(ipsecsa_targets) / sizeof(ipsecsa_targets[0]); |
int nipsecsa_targets = sizeof(ipsecsa_targets) / sizeof(ipsecsa_targets[0]); |
int nipsecsp_targets = sizeof(ipsecsp_targets) / sizeof(ipsecsp_targets[0]); |
int nipsecsp_targets = sizeof(ipsecsp_targets) / sizeof(ipsecsp_targets[0]); |
|
int nkern_dirs = 4; /* 2 extra subdirs */ |
|
#else |
|
int nkern_dirs = 2; |
#endif |
#endif |
|
|
|
int kernfs_try_fileop(kfstype, kfsfileop, void *, int); |
|
int kernfs_try_xwrite(kfstype, const struct kernfs_node *, char *, |
|
size_t, int); |
|
|
|
static int kernfs_default_xwrite(void *v); |
|
static int kernfs_default_fileop_getattr(void *); |
|
|
|
/* must include all fileop's */ |
|
const struct kernfs_fileop kernfs_default_fileops[] = { |
|
{ .kf_fileop = KERNFS_XWRITE }, |
|
{ .kf_fileop = KERNFS_FILEOP_OPEN }, |
|
{ .kf_fileop = KERNFS_FILEOP_GETATTR, |
|
.kf_vop = kernfs_default_fileop_getattr }, |
|
{ .kf_fileop = KERNFS_FILEOP_IOCTL }, |
|
{ .kf_fileop = KERNFS_FILEOP_MMAP }, |
|
{ .kf_fileop = KERNFS_FILEOP_CLOSE }, |
|
{ .kf_fileop = KERNFS_FILEOP_WRITE, .kf_vop = kernfs_default_xwrite }, |
|
}; |
|
|
int kernfs_lookup __P((void *)); |
int kernfs_lookup __P((void *)); |
#define kernfs_create genfs_eopnotsupp |
#define kernfs_create genfs_eopnotsupp |
Line 150 int kernfs_setattr __P((void *)); |
|
Line 180 int kernfs_setattr __P((void *)); |
|
int kernfs_read __P((void *)); |
int kernfs_read __P((void *)); |
int kernfs_write __P((void *)); |
int kernfs_write __P((void *)); |
#define kernfs_fcntl genfs_fcntl |
#define kernfs_fcntl genfs_fcntl |
#define kernfs_ioctl genfs_enoioctl |
int kernfs_ioctl __P((void *)); |
#define kernfs_poll genfs_poll |
#define kernfs_poll genfs_poll |
#define kernfs_revoke genfs_revoke |
#define kernfs_revoke genfs_revoke |
|
int kernfs_mmap __P((void *)); |
#define kernfs_fsync genfs_nullop |
#define kernfs_fsync genfs_nullop |
#define kernfs_seek genfs_nullop |
#define kernfs_seek genfs_nullop |
#define kernfs_remove genfs_eopnotsupp |
#define kernfs_remove genfs_eopnotsupp |
Line 202 const struct vnodeopv_entry_desc kernfs_ |
|
Line 233 const struct vnodeopv_entry_desc kernfs_ |
|
{ &vop_ioctl_desc, kernfs_ioctl }, /* ioctl */ |
{ &vop_ioctl_desc, kernfs_ioctl }, /* ioctl */ |
{ &vop_poll_desc, kernfs_poll }, /* poll */ |
{ &vop_poll_desc, kernfs_poll }, /* poll */ |
{ &vop_revoke_desc, kernfs_revoke }, /* revoke */ |
{ &vop_revoke_desc, kernfs_revoke }, /* revoke */ |
|
{ &vop_mmap_desc, kernfs_mmap }, /* mmap */ |
{ &vop_fsync_desc, kernfs_fsync }, /* fsync */ |
{ &vop_fsync_desc, kernfs_fsync }, /* fsync */ |
{ &vop_seek_desc, kernfs_seek }, /* seek */ |
{ &vop_seek_desc, kernfs_seek }, /* seek */ |
{ &vop_remove_desc, kernfs_remove }, /* remove */ |
{ &vop_remove_desc, kernfs_remove }, /* remove */ |
Line 235 const struct vnodeopv_entry_desc kernfs_ |
|
Line 267 const struct vnodeopv_entry_desc kernfs_ |
|
const struct vnodeopv_desc kernfs_vnodeop_opv_desc = |
const struct vnodeopv_desc kernfs_vnodeop_opv_desc = |
{ &kernfs_vnodeop_p, kernfs_vnodeop_entries }; |
{ &kernfs_vnodeop_p, kernfs_vnodeop_entries }; |
|
|
|
static __inline int |
|
kernfs_fileop_compare(struct kernfs_fileop *a, struct kernfs_fileop *b) |
|
{ |
|
if (a->kf_type < b->kf_type) |
|
return -1; |
|
if (a->kf_type > b->kf_type) |
|
return 1; |
|
if (a->kf_fileop < b->kf_fileop) |
|
return -1; |
|
if (a->kf_fileop > b->kf_fileop) |
|
return 1; |
|
return (0); |
|
} |
|
|
|
SPLAY_HEAD(kfsfileoptree, kernfs_fileop) kfsfileoptree = |
|
SPLAY_INITIALIZER(kfsfileoptree); |
|
SPLAY_PROTOTYPE(kfsfileoptree, kernfs_fileop, kf_node, kernfs_fileop_compare); |
|
SPLAY_GENERATE(kfsfileoptree, kernfs_fileop, kf_node, kernfs_fileop_compare); |
|
|
|
kfstype |
|
kernfs_alloctype(int nkf, const struct kernfs_fileop *kf) |
|
{ |
|
static u_char nextfreetype = KFSlasttype; |
|
struct kernfs_fileop *dkf, *fkf, skf; |
|
int i; |
|
|
|
/* XXX need to keep track of dkf's memory if we support |
|
deallocating types */ |
|
dkf = malloc(sizeof(kernfs_default_fileops), M_TEMP, M_WAITOK); |
|
memcpy(dkf, kernfs_default_fileops, sizeof(kernfs_default_fileops)); |
|
|
|
for (i = 0; i < sizeof(kernfs_default_fileops) / |
|
sizeof(kernfs_default_fileops[0]); i++) { |
|
dkf[i].kf_type = nextfreetype; |
|
SPLAY_INSERT(kfsfileoptree, &kfsfileoptree, &dkf[i]); |
|
} |
|
|
|
for (i = 0; i < nkf; i++) { |
|
skf.kf_type = nextfreetype; |
|
skf.kf_fileop = kf[i].kf_fileop; |
|
if ((fkf = SPLAY_FIND(kfsfileoptree, &kfsfileoptree, &skf))) |
|
fkf->kf_genop = kf[i].kf_genop; |
|
} |
|
|
|
return nextfreetype++; |
|
} |
|
|
|
int |
|
kernfs_try_fileop(kfstype type, kfsfileop fileop, void *v, int error) |
|
{ |
|
struct kernfs_fileop *kf, skf; |
|
|
|
skf.kf_type = type; |
|
skf.kf_fileop = fileop; |
|
if ((kf = SPLAY_FIND(kfsfileoptree, &kfsfileoptree, &skf))) |
|
if (kf->kf_vop) |
|
return kf->kf_vop(v); |
|
return error; |
|
} |
|
|
|
int |
|
kernfs_try_xwrite(kfstype type, const struct kernfs_node *kfs, char *buf, |
|
size_t len, int error) |
|
{ |
|
struct kernfs_fileop *kf, skf; |
|
|
|
skf.kf_type = type; |
|
skf.kf_fileop = KERNFS_XWRITE; |
|
if ((kf = SPLAY_FIND(kfsfileoptree, &kfsfileoptree, &skf))) |
|
if (kf->kf_xwrite) |
|
return kf->kf_xwrite(kfs, buf, len); |
|
return error; |
|
} |
|
|
|
int |
|
kernfs_addentry(kernfs_parentdir_t *pkt, kernfs_entry_t *dkt) |
|
{ |
|
struct kernfs_subdir *ks, *parent; |
|
|
|
if (pkt == NULL) { |
|
SIMPLEQ_INSERT_TAIL(&dyn_kern_targets, dkt, dkt_queue); |
|
nkern_targets++; |
|
if (dkt->dkt_kt.kt_vtype == VDIR) |
|
nkern_dirs++; |
|
} else { |
|
parent = (struct kernfs_subdir *)pkt->kt_data; |
|
SIMPLEQ_INSERT_TAIL(&parent->ks_entries, dkt, dkt_queue); |
|
parent->ks_nentries++; |
|
if (dkt->dkt_kt.kt_vtype == VDIR) |
|
parent->ks_dirs++; |
|
} |
|
if (dkt->dkt_kt.kt_vtype == VDIR && dkt->dkt_kt.kt_data == NULL) { |
|
ks = malloc(sizeof(struct kernfs_subdir), |
|
M_TEMP, M_WAITOK); |
|
SIMPLEQ_INIT(&ks->ks_entries); |
|
ks->ks_nentries = 2; /* . and .. */ |
|
ks->ks_dirs = 2; |
|
ks->ks_parent = pkt ? pkt : &kern_targets[0]; |
|
dkt->dkt_kt.kt_data = ks; |
|
} |
|
return 0; |
|
} |
|
|
static int |
static int |
kernfs_xread(kfs, off, bufp, len, wrlen) |
kernfs_xread(kfs, off, bufp, len, wrlen) |
struct kernfs_node *kfs; |
struct kernfs_node *kfs; |
Line 412 kernfs_xwrite(kfs, buf, len) |
|
Line 547 kernfs_xwrite(kfs, buf, len) |
|
return (0); |
return (0); |
|
|
default: |
default: |
return (EIO); |
return kernfs_try_xwrite(kfs->kfs_type, kfs, buf, len, EIO); |
} |
} |
} |
} |
|
|
Line 436 kernfs_lookup(v) |
|
Line 571 kernfs_lookup(v) |
|
const char *pname = cnp->cn_nameptr; |
const char *pname = cnp->cn_nameptr; |
const struct kernfs_node *kfs; |
const struct kernfs_node *kfs; |
const struct kern_target *kt; |
const struct kern_target *kt; |
|
const struct dyn_kern_target *dkt; |
|
const struct kernfs_subdir *ks; |
int error, i, wantpunlock; |
int error, i, wantpunlock; |
#ifdef IPSEC |
#ifdef IPSEC |
char *ep; |
char *ep; |
Line 464 kernfs_lookup(v) |
|
Line 601 kernfs_lookup(v) |
|
if (cnp->cn_flags & ISDOTDOT) |
if (cnp->cn_flags & ISDOTDOT) |
return (EIO); |
return (EIO); |
|
|
for (i = 0; i < nkern_targets; i++) { |
for (i = 0; i < static_nkern_targets; i++) { |
kt = &kern_targets[i]; |
kt = &kern_targets[i]; |
if (cnp->cn_namelen == kt->kt_namlen && |
if (cnp->cn_namelen == kt->kt_namlen && |
memcmp(kt->kt_name, pname, cnp->cn_namelen) == 0) |
memcmp(kt->kt_name, pname, cnp->cn_namelen) == 0) |
goto found; |
goto found; |
} |
} |
|
SIMPLEQ_FOREACH(dkt, &dyn_kern_targets, dkt_queue) { |
|
if (cnp->cn_namelen == dkt->dkt_kt.kt_namlen && |
|
memcmp(dkt->dkt_kt.kt_name, pname, cnp->cn_namelen) == 0) { |
|
kt = &dkt->dkt_kt; |
|
goto found; |
|
} |
|
} |
break; |
break; |
|
|
found: |
found: |
Line 480 kernfs_lookup(v) |
|
Line 624 kernfs_lookup(v) |
|
} |
} |
return (error); |
return (error); |
|
|
|
case KFSsubdir: |
|
ks = (struct kernfs_subdir *)kfs->kfs_kt->kt_data; |
|
if (cnp->cn_flags & ISDOTDOT) { |
|
kt = ks->ks_parent; |
|
goto found; |
|
} |
|
|
|
SIMPLEQ_FOREACH(dkt, &ks->ks_entries, dkt_queue) { |
|
if (cnp->cn_namelen == dkt->dkt_kt.kt_namlen && |
|
memcmp(dkt->dkt_kt.kt_name, pname, cnp->cn_namelen) == 0) { |
|
kt = &dkt->dkt_kt; |
|
goto found; |
|
} |
|
} |
|
break; |
|
|
#ifdef IPSEC |
#ifdef IPSEC |
case KFSipsecsadir: |
case KFSipsecsadir: |
if (cnp->cn_flags & ISDOTDOT) { |
if (cnp->cn_flags & ISDOTDOT) { |
|
|
#endif |
#endif |
|
|
default: |
default: |
return (0); |
return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_OPEN, |
|
v, 0); |
} |
} |
} |
} |
|
|
|
|
#endif |
#endif |
|
|
default: |
default: |
break; |
return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_CLOSE, |
|
v, 0); |
} |
} |
|
|
return (0); |
return (0); |
Line 625 kernfs_access(v) |
|
Line 787 kernfs_access(v) |
|
ap->a_mode, ap->a_cred)); |
ap->a_mode, ap->a_cred)); |
} |
} |
|
|
|
static int |
|
kernfs_default_fileop_getattr(v) |
|
void *v; |
|
{ |
|
struct vop_getattr_args /* { |
|
struct vnode *a_vp; |
|
struct vattr *a_vap; |
|
struct ucred *a_cred; |
|
struct proc *a_p; |
|
} */ *ap = v; |
|
struct vattr *vap = ap->a_vap; |
|
|
|
vap->va_nlink = 1; |
|
vap->va_bytes = vap->va_size = 0; |
|
|
|
return 0; |
|
} |
|
|
int |
int |
kernfs_getattr(v) |
kernfs_getattr(v) |
void *v; |
void *v; |
Line 636 kernfs_getattr(v) |
|
Line 816 kernfs_getattr(v) |
|
struct proc *a_p; |
struct proc *a_p; |
} */ *ap = v; |
} */ *ap = v; |
struct kernfs_node *kfs = VTOKERN(ap->a_vp); |
struct kernfs_node *kfs = VTOKERN(ap->a_vp); |
|
struct kernfs_subdir *ks; |
struct vattr *vap = ap->a_vap; |
struct vattr *vap = ap->a_vap; |
int error = 0; |
int error = 0; |
char strbuf[KSTRING], *buf; |
char strbuf[KSTRING], *buf; |
Line 670 kernfs_getattr(v) |
|
Line 851 kernfs_getattr(v) |
|
|
|
switch (kfs->kfs_type) { |
switch (kfs->kfs_type) { |
case KFSkern: |
case KFSkern: |
#ifdef IPSEC |
vap->va_nlink = nkern_dirs; |
vap->va_nlink = 4; /* 2 extra subdirs */ |
|
#else |
|
vap->va_nlink = 2; |
|
#endif |
|
vap->va_bytes = vap->va_size = DEV_BSIZE; |
vap->va_bytes = vap->va_size = DEV_BSIZE; |
break; |
break; |
|
|
Line 683 kernfs_getattr(v) |
|
Line 860 kernfs_getattr(v) |
|
vap->va_bytes = vap->va_size = DEV_BSIZE; |
vap->va_bytes = vap->va_size = DEV_BSIZE; |
break; |
break; |
|
|
|
case KFSsubdir: |
|
ks = (struct kernfs_subdir *)kfs->kfs_kt->kt_data; |
|
vap->va_nlink = ks->ks_dirs; |
|
vap->va_bytes = vap->va_size = DEV_BSIZE; |
|
break; |
|
|
case KFSnull: |
case KFSnull: |
case KFStime: |
case KFStime: |
case KFSint: |
case KFSint: |
Line 715 kernfs_getattr(v) |
|
Line 898 kernfs_getattr(v) |
|
#endif |
#endif |
|
|
default: |
default: |
error = EINVAL; |
error = kernfs_try_fileop(kfs->kfs_type, |
|
KERNFS_FILEOP_GETATTR, v, EINVAL); |
break; |
break; |
} |
} |
|
|
|
|
return (error); |
return (error); |
} |
} |
|
|
int |
static int |
kernfs_write(v) |
kernfs_default_xwrite(v) |
void *v; |
void *v; |
{ |
{ |
struct vop_write_args /* { |
struct vop_write_args /* { |
|
|
return (kernfs_xwrite(kfs, strbuf, xlen)); |
return (kernfs_xwrite(kfs, strbuf, xlen)); |
} |
} |
|
|
|
int |
|
kernfs_write(v) |
|
void *v; |
|
{ |
|
struct vop_write_args /* { |
|
struct vnode *a_vp; |
|
struct uio *a_uio; |
|
int a_ioflag; |
|
struct ucred *a_cred; |
|
} */ *ap = v; |
|
struct kernfs_node *kfs = VTOKERN(ap->a_vp); |
|
|
|
return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_WRITE, v, 0); |
|
} |
|
|
|
int |
|
kernfs_ioctl(v) |
|
void *v; |
|
{ |
|
struct vop_ioctl_args /* { |
|
const struct vnodeop_desc *a_desc; |
|
struct vnode *a_vp; |
|
u_long a_command; |
|
void *a_data; |
|
int a_fflag; |
|
struct ucred *a_cred; |
|
struct proc *a_p; |
|
} */ *ap = v; |
|
struct kernfs_node *kfs = VTOKERN(ap->a_vp); |
|
|
|
return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_IOCTL, v, |
|
EPASSTHROUGH); |
|
} |
|
|
|
int |
|
kernfs_mmap(v) |
|
void *v; |
|
{ |
|
struct vop_mmap_args /* { |
|
const struct vnodeop_desc *a_desc; |
|
struct vnode *a_vp; |
|
int a_fflags; |
|
struct ucred *a_cred; |
|
struct proc *a_p; |
|
} */ *ap = v; |
|
struct kernfs_node *kfs = VTOKERN(ap->a_vp); |
|
|
|
return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_MMAP, v, 0); |
|
} |
|
|
static int |
static int |
kernfs_setdirentfileno_kt(struct dirent *d, const struct kern_target *kt, |
kernfs_setdirentfileno_kt(struct dirent *d, const struct kern_target *kt, |
u_int32_t value, struct vop_readdir_args *ap) |
u_int32_t value, struct vop_readdir_args *ap) |
Line 863 kernfs_readdir(v) |
|
Line 1097 kernfs_readdir(v) |
|
struct dirent d; |
struct dirent d; |
struct kernfs_node *kfs = VTOKERN(ap->a_vp); |
struct kernfs_node *kfs = VTOKERN(ap->a_vp); |
const struct kern_target *kt; |
const struct kern_target *kt; |
off_t i; |
const struct dyn_kern_target *dkt = NULL; |
|
const struct kernfs_subdir *ks; |
|
off_t i, j; |
int error; |
int error; |
off_t *cookies = NULL; |
off_t *cookies = NULL; |
int ncookies = 0, n; |
int ncookies = 0, n; |
Line 897 kernfs_readdir(v) |
|
Line 1133 kernfs_readdir(v) |
|
|
|
n = 0; |
n = 0; |
for (; i < nkern_targets && uio->uio_resid >= UIO_MX; i++) { |
for (; i < nkern_targets && uio->uio_resid >= UIO_MX; i++) { |
kt = &kern_targets[i]; |
if (i < static_nkern_targets) |
|
kt = &kern_targets[i]; |
|
else { |
|
if (dkt == NULL) { |
|
dkt = SIMPLEQ_FIRST(&dyn_kern_targets); |
|
for (j = static_nkern_targets; j < i && |
|
dkt != NULL; j++) |
|
dkt = SIMPLEQ_NEXT(dkt, dkt_queue); |
|
if (j != i) |
|
break; |
|
} else { |
|
dkt = SIMPLEQ_NEXT(dkt, dkt_queue); |
|
if (dkt == NULL) |
|
break; |
|
} |
|
kt = &dkt->dkt_kt; |
|
} |
if (kt->kt_tag == KFSdevice) { |
if (kt->kt_tag == KFSdevice) { |
dev_t *dp = kt->kt_data; |
dev_t *dp = kt->kt_data; |
struct vnode *fvp; |
struct vnode *fvp; |
Line 948 kernfs_readdir(v) |
|
Line 1200 kernfs_readdir(v) |
|
ncookies = n; |
ncookies = n; |
break; |
break; |
|
|
|
case KFSsubdir: |
|
ks = (struct kernfs_subdir *)kfs->kfs_kt->kt_data; |
|
if (i >= ks->ks_nentries) |
|
return (0); |
|
|
|
if (ap->a_ncookies) { |
|
ncookies = min(ncookies, (ks->ks_nentries - i)); |
|
cookies = malloc(ncookies * sizeof(off_t), M_TEMP, |
|
M_WAITOK); |
|
*ap->a_cookies = cookies; |
|
} |
|
|
|
dkt = SIMPLEQ_FIRST(&ks->ks_entries); |
|
for (j = 0; j < i && dkt != NULL; j++) |
|
dkt = SIMPLEQ_NEXT(dkt, dkt_queue); |
|
n = 0; |
|
for (; i < ks->ks_nentries && uio->uio_resid >= UIO_MX; i++) { |
|
if (i < 2) |
|
kt = &subdir_targets[i]; |
|
else { |
|
/* check if ks_nentries lied to us */ |
|
if (dkt == NULL) |
|
break; |
|
kt = &dkt->dkt_kt; |
|
dkt = SIMPLEQ_NEXT(dkt, dkt_queue); |
|
} |
|
if (kt->kt_tag == KFSdevice) { |
|
dev_t *dp = kt->kt_data; |
|
struct vnode *fvp; |
|
|
|
if (*dp == NODEV || |
|
!vfinddev(*dp, kt->kt_vtype, &fvp)) |
|
continue; |
|
} |
|
d.d_namlen = kt->kt_namlen; |
|
if ((error = kernfs_setdirentfileno(&d, i, kfs, |
|
ks->ks_parent, kt, ap)) != 0) |
|
break; |
|
memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1); |
|
d.d_type = kt->kt_type; |
|
if ((error = uiomove((caddr_t)&d, UIO_MX, uio)) != 0) |
|
break; |
|
if (cookies) |
|
*cookies++ = i + 1; |
|
n++; |
|
} |
|
ncookies = n; |
|
break; |
|
|
#ifdef IPSEC |
#ifdef IPSEC |
case KFSipsecsadir: |
case KFSipsecsadir: |
/* count SA in the system */ |
/* count SA in the system */ |
Line 1030 kernfs_readdir(v) |
|
Line 1331 kernfs_readdir(v) |
|
TAILQ_FOREACH(sp, &sptailq, tailq) |
TAILQ_FOREACH(sp, &sptailq, tailq) |
n++; |
n++; |
|
|
if (i >= 2 + n) |
if (i >= nipsecsp_targets + n) |
return (0); |
return (0); |
|
|
if (ap->a_ncookies) { |
if (ap->a_ncookies) { |