[BACK]Return to kernfs_vnops.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / miscfs / kernfs

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/miscfs/kernfs/kernfs_vnops.c between version 1.128 and 1.147

version 1.128, 2006/11/16 01:33:38 version 1.147, 2013/03/18 19:35:44
Line 41 
Line 41 
 #include <sys/cdefs.h>  #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD$");  __KERNEL_RCSID(0, "$NetBSD$");
   
 #ifdef _KERNEL_OPT  
 #include "opt_ipsec.h"  
 #endif  
   
 #include <sys/param.h>  #include <sys/param.h>
 #include <sys/systm.h>  #include <sys/systm.h>
 #include <sys/kernel.h>  #include <sys/kernel.h>
Line 64  __KERNEL_RCSID(0, "$NetBSD$");
Line 60  __KERNEL_RCSID(0, "$NetBSD$");
 #include <miscfs/genfs/genfs.h>  #include <miscfs/genfs/genfs.h>
 #include <miscfs/kernfs/kernfs.h>  #include <miscfs/kernfs/kernfs.h>
   
 #ifdef IPSEC  
 #include <sys/mbuf.h>  
 #include <net/route.h>  
 #include <netinet/in.h>  
 #include <netinet6/ipsec.h>  
 #include <netkey/key.h>  
 #endif  
   
 #include <uvm/uvm_extern.h>  #include <uvm/uvm_extern.h>
   
 #define KSTRING 256             /* Largest I/O available via this filesystem */  #define KSTRING 256             /* Largest I/O available via this filesystem */
Line 95  const struct kern_target kern_targets[] 
Line 83  const struct kern_target kern_targets[] 
                                              KFSstring,      VREG, READ_MODE  },                                               KFSstring,      VREG, READ_MODE  },
      { DT_REG, N("hostname"),  0,            KFShostname,    VREG, WRITE_MODE },       { DT_REG, N("hostname"),  0,            KFShostname,    VREG, WRITE_MODE },
      { DT_REG, N("hz"),        &hz,          KFSint,         VREG, READ_MODE  },       { DT_REG, N("hz"),        &hz,          KFSint,         VREG, READ_MODE  },
 #ifdef IPSEC  
      { DT_DIR, N("ipsecsa"),   0,            KFSipsecsadir,  VDIR, UDIR_MODE  },  
      { DT_DIR, N("ipsecsp"),   0,            KFSipsecspdir,  VDIR, UDIR_MODE  },  
 #endif  
      { DT_REG, N("loadavg"),   0,            KFSavenrun,     VREG, READ_MODE  },       { DT_REG, N("loadavg"),   0,            KFSavenrun,     VREG, READ_MODE  },
      { DT_REG, N("msgbuf"),    0,            KFSmsgbuf,      VREG, READ_MODE  },       { DT_REG, N("msgbuf"),    0,            KFSmsgbuf,      VREG, READ_MODE  },
      { DT_REG, N("pagesize"),  &uvmexp.pagesize, KFSint,     VREG, READ_MODE  },       { DT_REG, N("pagesize"),  &uvmexp.pagesize, KFSint,     VREG, READ_MODE  },
Line 119  const struct kern_target subdir_targets[
Line 103  const struct kern_target subdir_targets[
      { DT_DIR, N("."),         0,            KFSsubdir,      VDIR, DIR_MODE   },       { DT_DIR, N("."),         0,            KFSsubdir,      VDIR, DIR_MODE   },
      { DT_DIR, N(".."),        0,            KFSkern,        VDIR, DIR_MODE   },       { DT_DIR, N(".."),        0,            KFSkern,        VDIR, DIR_MODE   },
 };  };
 #ifdef IPSEC  
 const struct kern_target ipsecsa_targets[] = {  
 /* NOTE: The name must be less than UIO_MX-16 chars in length */  
      /*        name            data          tag           type  ro/rw */  
      { DT_DIR, N("."),         0,            KFSipsecsadir,  VDIR, DIR_MODE   },  
      { DT_DIR, N(".."),        0,            KFSkern,        VDIR, DIR_MODE   },  
 };  
 const struct kern_target ipsecsp_targets[] = {  
 /* NOTE: The name must be less than UIO_MX-16 chars in length */  
      /*        name            data          tag           type  ro/rw */  
      { DT_DIR, N("."),         0,            KFSipsecspdir,  VDIR, DIR_MODE   },  
      { DT_DIR, N(".."),        0,            KFSkern,        VDIR, DIR_MODE   },  
 };  
 const struct kern_target ipsecsa_kt =  
      { DT_DIR, N(""),          0,            KFSipsecsa,     VREG, UREAD_MODE };  
 const struct kern_target ipsecsp_kt =  
      { DT_DIR, N(""),          0,            KFSipsecsp,     VREG, UREAD_MODE };  
 #endif  
 #undef N  #undef N
 SIMPLEQ_HEAD(,dyn_kern_target) dyn_kern_targets =  SIMPLEQ_HEAD(,dyn_kern_target) dyn_kern_targets =
         SIMPLEQ_HEAD_INITIALIZER(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]);  const int static_nkern_targets = sizeof(kern_targets) / sizeof(kern_targets[0]);
 #ifdef IPSEC  
 int nipsecsa_targets = sizeof(ipsecsa_targets) / sizeof(ipsecsa_targets[0]);  
 int nipsecsp_targets = sizeof(ipsecsp_targets) / sizeof(ipsecsp_targets[0]);  
 int nkern_dirs = 4; /* 2 extra subdirs */  
 #else  
 int nkern_dirs = 2;  int nkern_dirs = 2;
 #endif  
   
 int kernfs_try_fileop(kfstype, kfsfileop, void *, int);  int kernfs_try_fileop(kfstype, kfsfileop, void *, int);
 int kernfs_try_xread(kfstype, const struct kernfs_node *, char **,  int kernfs_try_xread(kfstype, const struct kernfs_node *, char **,
Line 380  kernfs_addentry(kernfs_parentdir_t *pkt,
Line 340  kernfs_addentry(kernfs_parentdir_t *pkt,
 }  }
   
 static int  static int
 kernfs_xread(kfs, off, bufp, len, wrlen)  kernfs_xread(struct kernfs_node *kfs, int off, char **bufp, size_t len, size_t *wrlen)
         struct kernfs_node *kfs;  
         int off;  
         char **bufp;  
         size_t len;  
         size_t *wrlen;  
 {  {
         const struct kern_target *kt;          const struct kern_target *kt;
 #ifdef IPSEC  
         struct mbuf *m;  
 #endif  
         int err;          int err;
   
         kt = kfs->kfs_kt;          kt = kfs->kfs_kt;
Line 400  kernfs_xread(kfs, off, bufp, len, wrlen)
Line 352  kernfs_xread(kfs, off, bufp, len, wrlen)
                 struct timeval tv;                  struct timeval tv;
   
                 microtime(&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;                  break;
         }          }
   
Line 462  kernfs_xread(kfs, off, bufp, len, wrlen)
Line 415  kernfs_xread(kfs, off, bufp, len, wrlen)
                 memcpy(*bufp, cp, xlen);                  memcpy(*bufp, cp, xlen);
                 (*bufp)[xlen] = '\n';                  (*bufp)[xlen] = '\n';
                 (*bufp)[xlen+1] = '\0';                  (*bufp)[xlen+1] = '\0';
                 len = strlen(*bufp);  
                 break;                  break;
         }          }
   
Line 473  kernfs_xread(kfs, off, bufp, len, wrlen)
Line 425  kernfs_xread(kfs, off, bufp, len, wrlen)
                     averunnable.ldavg[2], averunnable.fscale);                      averunnable.ldavg[2], averunnable.fscale);
                 break;                  break;
   
 #ifdef IPSEC  
         case KFSipsecsa:  
                 /*  
                  * Note that SA configuration could be changed during the  
                  * read operation, resulting in garbled output.  
                  */  
                 m = key_setdumpsa_spi(htonl(kfs->kfs_value));  
                 if (!m)  
                         return (ENOBUFS);  
                 if (off >= m->m_pkthdr.len) {  
                         *wrlen = 0;  
                         m_freem(m);  
                         return (0);  
                 }  
                 if (len > m->m_pkthdr.len - off)  
                         len = m->m_pkthdr.len - off;  
                 m_copydata(m, off, len, *bufp);  
                 *wrlen = len;  
                 m_freem(m);  
                 return (0);  
   
         case KFSipsecsp:  
                 /*  
                  * Note that SP configuration could be changed during the  
                  * read operation, resulting in garbled output.  
                  */  
                 if (!kfs->kfs_v) {  
                         struct secpolicy *sp;  
   
                         sp = key_getspbyid(kfs->kfs_value);  
                         if (sp)  
                                 kfs->kfs_v = sp;  
                         else  
                                 return (ENOENT);  
                 }  
                 m = key_setdumpsp((struct secpolicy *)kfs->kfs_v,  
                     SADB_X_SPDGET, 0, 0);  
                 if (!m)  
                         return (ENOBUFS);  
                 if (off >= m->m_pkthdr.len) {  
                         *wrlen = 0;  
                         m_freem(m);  
                         return (0);  
                 }  
                 if (len > m->m_pkthdr.len - off)  
                         len = m->m_pkthdr.len - off;  
                 m_copydata(m, off, len, *bufp);  
                 *wrlen = len;  
                 m_freem(m);  
                 return (0);  
 #endif  
   
         default:          default:
                 err = kernfs_try_xread(kfs->kfs_type, kfs, bufp, len,                  err = kernfs_try_xread(kfs->kfs_type, kfs, bufp, len,
                     EOPNOTSUPP);                      EOPNOTSUPP);
Line 543  kernfs_xread(kfs, off, bufp, len, wrlen)
Line 443  kernfs_xread(kfs, off, bufp, len, wrlen)
 }  }
   
 static int  static int
 kernfs_xwrite(kfs, bf, len)  kernfs_xwrite(const struct kernfs_node *kfs, char *bf, size_t len)
         const struct kernfs_node *kfs;  
         char *bf;  
         size_t len;  
 {  {
   
         switch (kfs->kfs_type) {          switch (kfs->kfs_type) {
Line 569  kernfs_xwrite(kfs, bf, len)
Line 466  kernfs_xwrite(kfs, bf, len)
  * ndp is the name to locate in that directory...   * ndp is the name to locate in that directory...
  */   */
 int  int
 kernfs_lookup(v)  kernfs_lookup(void *v)
         void *v;  
 {  {
         struct vop_lookup_args /* {          struct vop_lookup_args /* {
                 struct vnode * a_dvp;                  struct vnode * a_dvp;
Line 585  kernfs_lookup(v)
Line 481  kernfs_lookup(v)
         const struct kern_target *kt;          const struct kern_target *kt;
         const struct dyn_kern_target *dkt;          const struct dyn_kern_target *dkt;
         const struct kernfs_subdir *ks;          const struct kernfs_subdir *ks;
         int error, i, wantpunlock;          int error, i;
 #ifdef IPSEC  
         char *ep;  
         u_int32_t id;  
 #endif  
   
         *vpp = NULLVP;          *vpp = NULLVP;
         cnp->cn_flags &= ~PDIRUNLOCK;  
   
         if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)          if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)
                 return (EROFS);                  return (EROFS);
   
         if (cnp->cn_namelen == 1 && *pname == '.') {          if (cnp->cn_namelen == 1 && *pname == '.') {
                 *vpp = dvp;                  *vpp = dvp;
                 VREF(dvp);                  vref(dvp);
                 return (0);                  return (0);
         }          }
   
         wantpunlock = (~cnp->cn_flags & (LOCKPARENT | ISLASTCN));  
         kfs = VTOKERN(dvp);          kfs = VTOKERN(dvp);
         switch (kfs->kfs_type) {          switch (kfs->kfs_type) {
         case KFSkern:          case KFSkern:
Line 630  kernfs_lookup(v)
Line 520  kernfs_lookup(v)
   
         found:          found:
                 error = kernfs_allocvp(dvp->v_mount, vpp, kt->kt_tag, kt, 0);                  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);                  return (error);
   
         case KFSsubdir:          case KFSsubdir:
Line 652  kernfs_lookup(v)
Line 538  kernfs_lookup(v)
                 }                  }
                 break;                  break;
   
 #ifdef IPSEC  
         case KFSipsecsadir:  
                 if (cnp->cn_flags & ISDOTDOT) {  
                         kt = &kern_targets[0];  
                         goto found;  
                 }  
   
                 for (i = 2; i < nipsecsa_targets; i++) {  
                         kt = &ipsecsa_targets[i];  
                         if (cnp->cn_namelen == kt->kt_namlen &&  
                             memcmp(kt->kt_name, pname, cnp->cn_namelen) == 0)  
                                 goto found;  
                 }  
   
                 ep = NULL;  
                 id = strtoul(pname, &ep, 10);  
                 if (!ep || *ep || ep == pname)  
                         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:  
                 if (cnp->cn_flags & ISDOTDOT) {  
                         kt = &kern_targets[0];  
                         goto found;  
                 }  
   
                 for (i = 2; i < nipsecsp_targets; i++) {  
                         kt = &ipsecsp_targets[i];  
                         if (cnp->cn_namelen == kt->kt_namlen &&  
                             memcmp(kt->kt_name, pname, cnp->cn_namelen) == 0)  
                                 goto found;  
                 }  
   
                 ep = NULL;  
                 id = strtoul(pname, &ep, 10);  
                 if (!ep || *ep || ep == pname)  
                         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  
   
         default:          default:
                 return (ENOTDIR);                  return (ENOTDIR);
         }          }
Line 712  kernfs_lookup(v)
Line 546  kernfs_lookup(v)
 }  }
   
 int  int
 kernfs_open(v)  kernfs_open(void *v)
         void *v;  
 {  {
         struct vop_open_args /* {          struct vop_open_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
                 int a_mode;                  int a_mode;
                 kauth_cred_t a_cred;                  kauth_cred_t a_cred;
                 struct lwp *a_l;  
         } */ *ap = v;          } */ *ap = v;
         struct kernfs_node *kfs = VTOKERN(ap->a_vp);          struct kernfs_node *kfs = VTOKERN(ap->a_vp);
 #ifdef IPSEC  
         struct mbuf *m;  
         struct secpolicy *sp;  
 #endif  
   
         switch (kfs->kfs_type) {          return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_OPEN, v, 0);
 #ifdef IPSEC  
         case KFSipsecsa:  
                 m = key_setdumpsa_spi(htonl(kfs->kfs_value));  
                 if (m) {  
                         m_freem(m);  
                         return (0);  
                 } else  
                         return (ENOENT);  
   
         case KFSipsecsp:  
                 sp = key_getspbyid(kfs->kfs_value);  
                 if (sp) {  
                         kfs->kfs_v = sp;  
                         return (0);  
                 } else  
                         return (ENOENT);  
 #endif  
   
         default:  
                 return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_OPEN,  
                     v, 0);  
         }  
 }  }
   
 int  int
 kernfs_close(v)  kernfs_close(void *v)
         void *v;  
 {  {
         struct vop_close_args /* {          struct vop_close_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
                 int a_fflag;                  int a_fflag;
                 kauth_cred_t a_cred;                  kauth_cred_t a_cred;
                 struct lwp *a_l;  
         } */ *ap = v;          } */ *ap = v;
         struct kernfs_node *kfs = VTOKERN(ap->a_vp);          struct kernfs_node *kfs = VTOKERN(ap->a_vp);
   
         switch (kfs->kfs_type) {          return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_CLOSE, v, 0);
 #ifdef IPSEC  
         case KFSipsecsp:  
                 key_freesp((struct secpolicy *)kfs->kfs_v);  
                 break;  
 #endif  
   
         default:  
                 return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_CLOSE,  
                     v, 0);  
         }  
   
         return (0);  
 }  }
   
 int  int
 kernfs_access(v)  kernfs_access(void *v)
         void *v;  
 {  {
         struct vop_access_args /* {          struct vop_access_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
                 int a_mode;                  int a_mode;
                 kauth_cred_t a_cred;                  kauth_cred_t a_cred;
                 struct lwp *a_l;  
         } */ *ap = v;          } */ *ap = v;
         struct vattr va;          struct vattr va;
         int error;          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 (error);
   
         return (vaccess(va.va_type, va.va_mode, va.va_uid, va.va_gid,          return kauth_authorize_vnode(ap->a_cred,
             ap->a_mode, ap->a_cred));              KAUTH_ACCESS_ACTION(ap->a_mode, ap->a_vp->v_type, va.va_mode),
               ap->a_vp, NULL, genfs_can_access(va.va_type, va.va_mode,
               va.va_uid, va.va_gid, ap->a_mode, ap->a_cred));
 }  }
   
 static int  static int
 kernfs_default_fileop_getattr(v)  kernfs_default_fileop_getattr(void *v)
         void *v;  
 {  {
         struct vop_getattr_args /* {          struct vop_getattr_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
                 struct vattr *a_vap;                  struct vattr *a_vap;
                 kauth_cred_t a_cred;                  kauth_cred_t a_cred;
                 struct lwp *a_l;  
         } */ *ap = v;          } */ *ap = v;
         struct vattr *vap = ap->a_vap;          struct vattr *vap = ap->a_vap;
   
Line 818  kernfs_default_fileop_getattr(v)
Line 608  kernfs_default_fileop_getattr(v)
 }  }
   
 int  int
 kernfs_getattr(v)  kernfs_getattr(void *v)
         void *v;  
 {  {
         struct vop_getattr_args /* {          struct vop_getattr_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
                 struct vattr *a_vap;                  struct vattr *a_vap;
                 kauth_cred_t a_cred;                  kauth_cred_t a_cred;
                 struct lwp *a_l;  
         } */ *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 kernfs_subdir *ks;
Line 834  kernfs_getattr(v)
Line 622  kernfs_getattr(v)
         char strbuf[KSTRING], *bf;          char strbuf[KSTRING], *bf;
         size_t nread, total;          size_t nread, total;
   
         VATTR_NULL(vap);          vattr_null(vap);
         vap->va_type = ap->a_vp->v_type;          vap->va_type = ap->a_vp->v_type;
         vap->va_uid = 0;          vap->va_uid = 0;
         vap->va_gid = 0;          vap->va_gid = 0;
Line 844  kernfs_getattr(v)
Line 632  kernfs_getattr(v)
         vap->va_size = 0;          vap->va_size = 0;
         vap->va_blocksize = DEV_BSIZE;          vap->va_blocksize = DEV_BSIZE;
         /* Make all times be current TOD, except for the "boottime" node. */          /* 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)) {              !memcmp(kfs->kfs_kt->kt_name, "boottime", 8)) {
                 TIMEVAL_TO_TIMESPEC(&boottime, &vap->va_ctime);                  vap->va_ctime = boottime;
         } else {          } else {
                 getnanotime(&vap->va_ctime);                  getnanotime(&vap->va_ctime);
         }          }
Line 881  kernfs_getattr(v)
Line 669  kernfs_getattr(v)
         case KFSavenrun:          case KFSavenrun:
         case KFSdevice:          case KFSdevice:
         case KFSmsgbuf:          case KFSmsgbuf:
 #ifdef IPSEC  
         case KFSipsecsa:  
         case KFSipsecsp:  
 #endif  
                 vap->va_nlink = 1;                  vap->va_nlink = 1;
                 total = 0;                  total = 0;
                 do {                  do {
Line 896  kernfs_getattr(v)
Line 680  kernfs_getattr(v)
                 vap->va_bytes = vap->va_size = total;                  vap->va_bytes = vap->va_size = total;
                 break;                  break;
   
 #ifdef IPSEC  
         case KFSipsecsadir:  
         case KFSipsecspdir:  
                 vap->va_nlink = 2;  
                 vap->va_bytes = vap->va_size = DEV_BSIZE;  
                 break;  
 #endif  
   
         default:          default:
                 error = kernfs_try_fileop(kfs->kfs_type,                  error = kernfs_try_fileop(kfs->kfs_type,
                     KERNFS_FILEOP_GETATTR, v, EINVAL);                      KERNFS_FILEOP_GETATTR, v, EINVAL);
Line 928  kernfs_setattr(void *v)
Line 704  kernfs_setattr(void *v)
 }  }
   
 int  int
 kernfs_default_xread(v)  kernfs_default_xread(void *v)
         void *v;  
 {  {
         struct vop_read_args /* {          struct vop_read_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
Line 945  kernfs_default_xread(v)
Line 720  kernfs_default_xread(v)
         int error;          int error;
   
         if (ap->a_vp->v_type == VDIR)          if (ap->a_vp->v_type == VDIR)
                 return (EOPNOTSUPP);                  return EISDIR;
   
         off = (int)uio->uio_offset;          off = (int)uio->uio_offset;
         /* Don't allow negative offsets */          /* Don't allow negative offsets */
Line 959  kernfs_default_xread(v)
Line 734  kernfs_default_xread(v)
 }  }
   
 int  int
 kernfs_read(v)  kernfs_read(void *v)
         void *v;  
 {  {
         struct vop_read_args /* {          struct vop_read_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
Line 979  kernfs_read(v)
Line 753  kernfs_read(v)
 }  }
   
 static int  static int
 kernfs_default_xwrite(v)  kernfs_default_xwrite(void *v)
         void *v;  
 {  {
         struct vop_write_args /* {          struct vop_write_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
Line 1010  kernfs_default_xwrite(v)
Line 783  kernfs_default_xwrite(v)
 }  }
   
 int  int
 kernfs_write(v)  kernfs_write(void *v)
         void *v;  
 {  {
         struct vop_write_args /* {          struct vop_write_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
Line 1030  kernfs_write(v)
Line 802  kernfs_write(v)
 }  }
   
 int  int
 kernfs_ioctl(v)  kernfs_ioctl(void *v)
         void *v;  
 {  {
         struct vop_ioctl_args /* {          struct vop_ioctl_args /* {
                 const struct vnodeop_desc *a_desc;                  const struct vnodeop_desc *a_desc;
Line 1040  kernfs_ioctl(v)
Line 811  kernfs_ioctl(v)
                 void *a_data;                  void *a_data;
                 int a_fflag;                  int a_fflag;
                 kauth_cred_t a_cred;                  kauth_cred_t a_cred;
                 struct lwp *a_l;  
         } */ *ap = v;          } */ *ap = v;
         struct kernfs_node *kfs = VTOKERN(ap->a_vp);          struct kernfs_node *kfs = VTOKERN(ap->a_vp);
   
Line 1062  kernfs_setdirentfileno_kt(struct dirent 
Line 832  kernfs_setdirentfileno_kt(struct dirent 
         if (kt->kt_tag == KFSdevice) {          if (kt->kt_tag == KFSdevice) {
                 struct vattr va;                  struct vattr va;
   
                 error = VOP_GETATTR(vp, &va, ap->a_cred, curlwp);                  error = VOP_GETATTR(vp, &va, ap->a_cred);
                 if (error != 0) {                  if (error != 0) {
                         return error;                          return error;
                 }                  }
Line 1103  kernfs_setdirentfileno(struct dirent *d,
Line 873  kernfs_setdirentfileno(struct dirent *d,
 }  }
   
 int  int
 kernfs_readdir(v)  kernfs_readdir(void *v)
         void *v;  
 {  {
         struct vop_readdir_args /* {          struct vop_readdir_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
Line 1124  kernfs_readdir(v)
Line 893  kernfs_readdir(v)
         int error;          int error;
         off_t *cookies = NULL;          off_t *cookies = NULL;
         int ncookies = 0, n;          int ncookies = 0, n;
 #ifdef IPSEC  
         struct secasvar *sav, *sav2;  
         struct secpolicy *sp;  
 #endif  
   
         if (uio->uio_resid < UIO_MX)          if (uio->uio_resid < UIO_MX)
                 return (EINVAL);                  return (EINVAL);
Line 1178  kernfs_readdir(v)
Line 943  kernfs_readdir(v)
                                 if (*dp == NODEV ||                                  if (*dp == NODEV ||
                                     !vfinddev(*dp, kt->kt_vtype, &fvp))                                      !vfinddev(*dp, kt->kt_vtype, &fvp))
                                         continue;                                          continue;
                                   vrele(fvp);
                           }
                           if (kt->kt_tag == KFSmsgbuf) {
                                   if (!msgbufenabled
                                       || msgbufp->msg_magic != MSG_MAGIC) {
                                           continue;
                                   }
                         }                          }
                         d.d_namlen = kt->kt_namlen;                          d.d_namlen = kt->kt_namlen;
                         if ((error = kernfs_setdirentfileno(&d, i, kfs,                          if ((error = kernfs_setdirentfileno(&d, i, kfs,
Line 1254  kernfs_readdir(v)
Line 1026  kernfs_readdir(v)
                                 if (*dp == NODEV ||                                  if (*dp == NODEV ||
                                     !vfinddev(*dp, kt->kt_vtype, &fvp))                                      !vfinddev(*dp, kt->kt_vtype, &fvp))
                                         continue;                                          continue;
                                   vrele(fvp);
                         }                          }
                         d.d_namlen = kt->kt_namlen;                          d.d_namlen = kt->kt_namlen;
                         if ((error = kernfs_setdirentfileno(&d, i, kfs,                          if ((error = kernfs_setdirentfileno(&d, i, kfs,
Line 1270  kernfs_readdir(v)
Line 1043  kernfs_readdir(v)
                 ncookies = n;                  ncookies = n;
                 break;                  break;
   
 #ifdef IPSEC  
         case KFSipsecsadir:  
                 /* count SA in the system */  
                 n = 0;  
                 TAILQ_FOREACH(sav, &satailq, tailq) {  
                         for (sav2 = TAILQ_FIRST(&satailq);  
                             sav2 != sav;  
                             sav2 = TAILQ_NEXT(sav2, tailq)) {  
                                 if (sav->spi == sav2->spi) {  
                                         /* multiple SA with same SPI */  
                                         break;  
                                 }  
                         }  
                         if (sav == sav2 || sav->spi != sav2->spi)  
                                 n++;  
                 }  
   
                 if (i >= nipsecsa_targets + n)  
                         return (0);  
   
                 if (ap->a_ncookies) {  
                         ncookies = min(ncookies, (n - i));  
                         cookies = malloc(ncookies * sizeof(off_t), M_TEMP,  
                             M_WAITOK);  
                         *ap->a_cookies = cookies;  
                 }  
   
                 n = 0;  
                 for (; i < nipsecsa_targets && uio->uio_resid >= UIO_MX; i++) {  
                         kt = &ipsecsa_targets[i];  
                         d.d_namlen = kt->kt_namlen;  
                         if ((error = kernfs_setdirentfileno(&d, i, kfs,  
                             &kern_targets[0], kt, ap)) != 0)  
                                 break;  
                         memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1);  
                         d.d_type = kt->kt_type;  
                         if ((error = uiomove(&d, UIO_MX, uio)) != 0)  
                                 break;  
                         if (cookies)  
                                 *cookies++ = i + 1;  
                         n++;  
                 }  
                 if (error) {  
                         ncookies = n;  
                         break;  
                 }  
   
                 TAILQ_FOREACH(sav, &satailq, tailq) {  
                         for (sav2 = TAILQ_FIRST(&satailq);  
                             sav2 != sav;  
                             sav2 = TAILQ_NEXT(sav2, tailq)) {  
                                 if (sav->spi == sav2->spi) {  
                                         /* multiple SA with same SPI */  
                                         break;  
                                 }  
                         }  
                         if (sav != sav2 && sav->spi == sav2->spi)  
                                 continue;  
                         if (uio->uio_resid < UIO_MX)  
                                 break;  
                         if ((error = kernfs_setdirentfileno_kt(&d, &ipsecsa_kt,  
                             sav->spi, ap)) != 0)  
                                 break;  
                         d.d_namlen = snprintf(d.d_name, sizeof(d.d_name),  
                             "%u", ntohl(sav->spi));  
                         d.d_type = DT_REG;  
                         if ((error = uiomove(&d, UIO_MX, uio)) != 0)  
                                 break;  
                         if (cookies)  
                                 *cookies++ = i + 1;  
                         n++;  
                         i++;  
                 }  
                 ncookies = n;  
                 break;  
   
         case KFSipsecspdir:  
                 /* count SP in the system */  
                 n = 0;  
                 TAILQ_FOREACH(sp, &sptailq, tailq)  
                         n++;  
   
                 if (i >= nipsecsp_targets + n)  
                         return (0);  
   
                 if (ap->a_ncookies) {  
                         ncookies = min(ncookies, (n - i));  
                         cookies = malloc(ncookies * sizeof(off_t), M_TEMP,  
                             M_WAITOK);  
                         *ap->a_cookies = cookies;  
                 }  
   
                 n = 0;  
                 for (; i < nipsecsp_targets && uio->uio_resid >= UIO_MX; i++) {  
                         kt = &ipsecsp_targets[i];  
                         d.d_namlen = kt->kt_namlen;  
                         if ((error = kernfs_setdirentfileno(&d, i, kfs,  
                             &kern_targets[0], kt, ap)) != 0)  
                                 break;  
                         memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1);  
                         d.d_type = kt->kt_type;  
                         if ((error = uiomove(&d, UIO_MX, uio)) != 0)  
                                 break;  
                         if (cookies)  
                                 *cookies++ = i + 1;  
                         n++;  
                 }  
                 if (error) {  
                         ncookies = n;  
                         break;  
                 }  
   
                 TAILQ_FOREACH(sp, &sptailq, tailq) {  
                         if (uio->uio_resid < UIO_MX)  
                                 break;  
                         if ((error = kernfs_setdirentfileno_kt(&d, &ipsecsp_kt,  
                             sp->id, ap)) != 0)  
                                 break;  
                         d.d_namlen = snprintf(d.d_name, sizeof(d.d_name),  
                             "%u", sp->id);  
                         d.d_type = DT_REG;  
                         if ((error = uiomove(&d, UIO_MX, uio)) != 0)  
                                 break;  
                         if (cookies)  
                                 *cookies++ = i + 1;  
                         n++;  
                         i++;  
                 }  
                 ncookies = n;  
                 break;  
 #endif  
   
         default:          default:
                 error = ENOTDIR;                  error = ENOTDIR;
                 break;                  break;
Line 1422  kernfs_readdir(v)
Line 1063  kernfs_readdir(v)
 }  }
   
 int  int
 kernfs_inactive(v)  kernfs_inactive(void *v)
         void *v;  
 {  {
         struct vop_inactive_args /* {          struct vop_inactive_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
                 struct lwp *a_l;                  bool *a_recycle;
         } */ *ap = v;          } */ *ap = v;
         struct vnode *vp = ap->a_vp;          struct vnode *vp = ap->a_vp;
         const struct kernfs_node *kfs = VTOKERN(ap->a_vp);  
 #ifdef IPSEC  
         struct mbuf *m;  
         struct secpolicy *sp;  
 #endif  
   
         VOP_UNLOCK(vp, 0);          *ap->a_recycle = false;
         switch (kfs->kfs_type) {          VOP_UNLOCK(vp);
 #ifdef IPSEC  
         case KFSipsecsa:  
                 m = key_setdumpsa_spi(htonl(kfs->kfs_value));  
                 if (m)  
                         m_freem(m);  
                 else  
                         vgone(vp);  
                 break;  
         case KFSipsecsp:  
                 sp = key_getspbyid(kfs->kfs_value);  
                 if (sp)  
                         key_freesp(sp);  
                 else {  
                         /* should never happen as we hold a refcnt */  
                         vgone(vp);  
                 }  
                 break;  
 #endif  
         default:  
                 break;  
         }  
         return (0);          return (0);
 }  }
   
 int  int
 kernfs_reclaim(v)  kernfs_reclaim(void *v)
         void *v;  
 {  {
         struct vop_reclaim_args /* {          struct vop_reclaim_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
Line 1477  kernfs_reclaim(v)
Line 1090  kernfs_reclaim(v)
  * Return POSIX pathconf information applicable to special devices.   * Return POSIX pathconf information applicable to special devices.
  */   */
 int  int
 kernfs_pathconf(v)  kernfs_pathconf(void *v)
         void *v;  
 {  {
         struct vop_pathconf_args /* {          struct vop_pathconf_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
Line 1527  kernfs_print(void *v)
Line 1139  kernfs_print(void *v)
 }  }
   
 int  int
 kernfs_link(v)  kernfs_link(void *v)
         void *v;  
 {  {
         struct vop_link_args /* {          struct vop_link_args /* {
                 struct vnode *a_dvp;                  struct vnode *a_dvp;
Line 1542  kernfs_link(v)
Line 1153  kernfs_link(v)
 }  }
   
 int  int
 kernfs_symlink(v)  kernfs_symlink(void *v)
         void *v;  
 {  {
         struct vop_symlink_args /* {          struct vop_symlink_args /* {
                 struct vnode *a_dvp;                  struct vnode *a_dvp;

Legend:
Removed from v.1.128  
changed lines
  Added in v.1.147

CVSweb <webmaster@jp.NetBSD.org>