Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/miscfs/kernfs/kernfs_vnops.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/miscfs/kernfs/kernfs_vnops.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.128 retrieving revision 1.138 diff -u -p -r1.128 -r1.138 --- src/sys/miscfs/kernfs/kernfs_vnops.c 2006/11/16 01:33:38 1.128 +++ src/sys/miscfs/kernfs/kernfs_vnops.c 2009/07/03 21:17:41 1.138 @@ -1,4 +1,4 @@ -/* $NetBSD: kernfs_vnops.c,v 1.128 2006/11/16 01:33:38 christos Exp $ */ +/* $NetBSD: kernfs_vnops.c,v 1.138 2009/07/03 21:17:41 elad Exp $ */ /* * Copyright (c) 1992, 1993 @@ -39,7 +39,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kernfs_vnops.c,v 1.128 2006/11/16 01:33:38 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kernfs_vnops.c,v 1.138 2009/07/03 21:17:41 elad Exp $"); #ifdef _KERNEL_OPT #include "opt_ipsec.h" @@ -380,12 +380,7 @@ kernfs_addentry(kernfs_parentdir_t *pkt, } static int -kernfs_xread(kfs, off, bufp, len, wrlen) - struct kernfs_node *kfs; - int off; - char **bufp; - size_t len; - size_t *wrlen; +kernfs_xread(struct kernfs_node *kfs, int off, char **bufp, size_t len, size_t *wrlen) { const struct kern_target *kt; #ifdef IPSEC @@ -400,7 +395,8 @@ kernfs_xread(kfs, off, bufp, len, wrlen) struct timeval tv; microtime(&tv); - snprintf(*bufp, len, "%ld %ld\n", tv.tv_sec, tv.tv_usec); + snprintf(*bufp, len, "%lld %ld\n", (long long)tv.tv_sec, + (long)tv.tv_usec); break; } @@ -475,6 +471,8 @@ kernfs_xread(kfs, off, bufp, len, wrlen) #ifdef IPSEC case KFSipsecsa: + if (key_setdumpsa_spi == NULL) + return 0; /* * Note that SA configuration could be changed during the * read operation, resulting in garbled output. @@ -499,6 +497,8 @@ kernfs_xread(kfs, off, bufp, len, wrlen) * Note that SP configuration could be changed during the * read operation, resulting in garbled output. */ + if (key_getspbyid == NULL) + return 0; if (!kfs->kfs_v) { struct secpolicy *sp; @@ -543,10 +543,7 @@ kernfs_xread(kfs, off, bufp, len, wrlen) } static int -kernfs_xwrite(kfs, bf, len) - const struct kernfs_node *kfs; - char *bf; - size_t len; +kernfs_xwrite(const struct kernfs_node *kfs, char *bf, size_t len) { switch (kfs->kfs_type) { @@ -569,8 +566,7 @@ kernfs_xwrite(kfs, bf, len) * ndp is the name to locate in that directory... */ int -kernfs_lookup(v) - void *v; +kernfs_lookup(void *v) { struct vop_lookup_args /* { struct vnode * a_dvp; @@ -585,14 +581,13 @@ kernfs_lookup(v) const struct kern_target *kt; const struct dyn_kern_target *dkt; const struct kernfs_subdir *ks; - int error, i, wantpunlock; + int error, i; #ifdef IPSEC char *ep; u_int32_t id; #endif *vpp = NULLVP; - cnp->cn_flags &= ~PDIRUNLOCK; if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME) return (EROFS); @@ -603,7 +598,6 @@ kernfs_lookup(v) return (0); } - wantpunlock = (~cnp->cn_flags & (LOCKPARENT | ISLASTCN)); kfs = VTOKERN(dvp); switch (kfs->kfs_type) { case KFSkern: @@ -630,10 +624,6 @@ kernfs_lookup(v) found: error = kernfs_allocvp(dvp->v_mount, vpp, kt->kt_tag, kt, 0); - if ((error == 0) && wantpunlock) { - VOP_UNLOCK(dvp, 0); - cnp->cn_flags |= PDIRUNLOCK; - } return (error); case KFSsubdir: @@ -672,10 +662,6 @@ kernfs_lookup(v) break; error = kernfs_allocvp(dvp->v_mount, vpp, KFSipsecsa, &ipsecsa_kt, id); - if ((error == 0) && wantpunlock) { - VOP_UNLOCK(dvp, 0); - cnp->cn_flags |= PDIRUNLOCK; - } return (error); case KFSipsecspdir: @@ -697,10 +683,6 @@ kernfs_lookup(v) break; error = kernfs_allocvp(dvp->v_mount, vpp, KFSipsecsp, &ipsecsp_kt, id); - if ((error == 0) && wantpunlock) { - VOP_UNLOCK(dvp, 0); - cnp->cn_flags |= PDIRUNLOCK; - } return (error); #endif @@ -712,14 +694,12 @@ kernfs_lookup(v) } int -kernfs_open(v) - void *v; +kernfs_open(void *v) { struct vop_open_args /* { struct vnode *a_vp; int a_mode; kauth_cred_t a_cred; - struct lwp *a_l; } */ *ap = v; struct kernfs_node *kfs = VTOKERN(ap->a_vp); #ifdef IPSEC @@ -730,6 +710,8 @@ kernfs_open(v) switch (kfs->kfs_type) { #ifdef IPSEC case KFSipsecsa: + if (key_setdumpsa_spi == NULL) + return 0; m = key_setdumpsa_spi(htonl(kfs->kfs_value)); if (m) { m_freem(m); @@ -738,6 +720,8 @@ kernfs_open(v) return (ENOENT); case KFSipsecsp: + if (key_getspbyid == NULL) + return 0; sp = key_getspbyid(kfs->kfs_value); if (sp) { kfs->kfs_v = sp; @@ -753,20 +737,20 @@ kernfs_open(v) } int -kernfs_close(v) - void *v; +kernfs_close(void *v) { struct vop_close_args /* { struct vnode *a_vp; int a_fflag; kauth_cred_t a_cred; - struct lwp *a_l; } */ *ap = v; struct kernfs_node *kfs = VTOKERN(ap->a_vp); switch (kfs->kfs_type) { #ifdef IPSEC case KFSipsecsp: + if (key_freesp == NULL) + return 0; key_freesp((struct secpolicy *)kfs->kfs_v); break; #endif @@ -779,35 +763,51 @@ kernfs_close(v) return (0); } +static int +kernfs_check_possible(struct vnode *vp, mode_t mode) +{ + + return 0; +} + +static int +kernfs_check_permitted(struct vattr *va, mode_t mode, kauth_cred_t cred) +{ + + return genfs_can_access(va->va_type, va->va_mode, va->va_uid, va->va_gid, + mode, cred); +} + int -kernfs_access(v) - void *v; +kernfs_access(void *v) { struct vop_access_args /* { struct vnode *a_vp; int a_mode; kauth_cred_t a_cred; - struct lwp *a_l; } */ *ap = v; struct vattr va; int error; - if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred, ap->a_l)) != 0) + if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred)) != 0) return (error); - return (vaccess(va.va_type, va.va_mode, va.va_uid, va.va_gid, - ap->a_mode, ap->a_cred)); + error = kernfs_check_possible(ap->a_vp, ap->a_mode); + if (error) + return error; + + error = kernfs_check_permitted(&va, ap->a_mode, ap->a_cred); + + return error; } static int -kernfs_default_fileop_getattr(v) - void *v; +kernfs_default_fileop_getattr(void *v) { struct vop_getattr_args /* { struct vnode *a_vp; struct vattr *a_vap; kauth_cred_t a_cred; - struct lwp *a_l; } */ *ap = v; struct vattr *vap = ap->a_vap; @@ -818,14 +818,12 @@ kernfs_default_fileop_getattr(v) } int -kernfs_getattr(v) - void *v; +kernfs_getattr(void *v) { struct vop_getattr_args /* { struct vnode *a_vp; struct vattr *a_vap; kauth_cred_t a_cred; - struct lwp *a_l; } */ *ap = v; struct kernfs_node *kfs = VTOKERN(ap->a_vp); struct kernfs_subdir *ks; @@ -844,9 +842,9 @@ kernfs_getattr(v) vap->va_size = 0; vap->va_blocksize = DEV_BSIZE; /* Make all times be current TOD, except for the "boottime" node. */ - if (kfs->kfs_kt && kfs->kfs_kt->kt_namlen == 8 && + if (kfs->kfs_kt->kt_namlen == 8 && !memcmp(kfs->kfs_kt->kt_name, "boottime", 8)) { - TIMEVAL_TO_TIMESPEC(&boottime, &vap->va_ctime); + vap->va_ctime = boottime; } else { getnanotime(&vap->va_ctime); } @@ -928,8 +926,7 @@ kernfs_setattr(void *v) } int -kernfs_default_xread(v) - void *v; +kernfs_default_xread(void *v) { struct vop_read_args /* { struct vnode *a_vp; @@ -959,8 +956,7 @@ kernfs_default_xread(v) } int -kernfs_read(v) - void *v; +kernfs_read(void *v) { struct vop_read_args /* { struct vnode *a_vp; @@ -979,8 +975,7 @@ kernfs_read(v) } static int -kernfs_default_xwrite(v) - void *v; +kernfs_default_xwrite(void *v) { struct vop_write_args /* { struct vnode *a_vp; @@ -1010,8 +1005,7 @@ kernfs_default_xwrite(v) } int -kernfs_write(v) - void *v; +kernfs_write(void *v) { struct vop_write_args /* { struct vnode *a_vp; @@ -1030,8 +1024,7 @@ kernfs_write(v) } int -kernfs_ioctl(v) - void *v; +kernfs_ioctl(void *v) { struct vop_ioctl_args /* { const struct vnodeop_desc *a_desc; @@ -1040,7 +1033,6 @@ kernfs_ioctl(v) void *a_data; int a_fflag; kauth_cred_t a_cred; - struct lwp *a_l; } */ *ap = v; struct kernfs_node *kfs = VTOKERN(ap->a_vp); @@ -1062,7 +1054,7 @@ kernfs_setdirentfileno_kt(struct dirent if (kt->kt_tag == KFSdevice) { struct vattr va; - error = VOP_GETATTR(vp, &va, ap->a_cred, curlwp); + error = VOP_GETATTR(vp, &va, ap->a_cred); if (error != 0) { return error; } @@ -1103,8 +1095,7 @@ kernfs_setdirentfileno(struct dirent *d, } int -kernfs_readdir(v) - void *v; +kernfs_readdir(void *v) { struct vop_readdir_args /* { struct vnode *a_vp; @@ -1274,6 +1265,8 @@ kernfs_readdir(v) case KFSipsecsadir: /* count SA in the system */ n = 0; + if (&satailq == NULL) + return 0; TAILQ_FOREACH(sav, &satailq, tailq) { for (sav2 = TAILQ_FIRST(&satailq); sav2 != sav; @@ -1348,6 +1341,9 @@ kernfs_readdir(v) case KFSipsecspdir: /* count SP in the system */ + if (&sptailq == NULL) + return 0; + n = 0; TAILQ_FOREACH(sp, &sptailq, tailq) n++; @@ -1422,12 +1418,11 @@ kernfs_readdir(v) } int -kernfs_inactive(v) - void *v; +kernfs_inactive(void *v) { struct vop_inactive_args /* { struct vnode *a_vp; - struct lwp *a_l; + bool *a_recycle; } */ *ap = v; struct vnode *vp = ap->a_vp; const struct kernfs_node *kfs = VTOKERN(ap->a_vp); @@ -1436,35 +1431,38 @@ kernfs_inactive(v) struct secpolicy *sp; #endif - VOP_UNLOCK(vp, 0); + *ap->a_recycle = false; switch (kfs->kfs_type) { #ifdef IPSEC case KFSipsecsa: + if (key_setdumpsa_spi == NULL) + return 0; m = key_setdumpsa_spi(htonl(kfs->kfs_value)); if (m) m_freem(m); else - vgone(vp); + *ap->a_recycle = true; break; case KFSipsecsp: + if (key_getspbyid == NULL) + return 0; sp = key_getspbyid(kfs->kfs_value); if (sp) key_freesp(sp); else { - /* should never happen as we hold a refcnt */ - vgone(vp); + *ap->a_recycle = true; } break; #endif default: break; } + VOP_UNLOCK(vp, 0); return (0); } int -kernfs_reclaim(v) - void *v; +kernfs_reclaim(void *v) { struct vop_reclaim_args /* { struct vnode *a_vp; @@ -1477,8 +1475,7 @@ kernfs_reclaim(v) * Return POSIX pathconf information applicable to special devices. */ int -kernfs_pathconf(v) - void *v; +kernfs_pathconf(void *v) { struct vop_pathconf_args /* { struct vnode *a_vp; @@ -1527,8 +1524,7 @@ kernfs_print(void *v) } int -kernfs_link(v) - void *v; +kernfs_link(void *v) { struct vop_link_args /* { struct vnode *a_dvp; @@ -1542,8 +1538,7 @@ kernfs_link(v) } int -kernfs_symlink(v) - void *v; +kernfs_symlink(void *v) { struct vop_symlink_args /* { struct vnode *a_dvp;