[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.142 and 1.154

version 1.142, 2010/06/24 13:03:16 version 1.154, 2014/07/25 08:20:52
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 63  __KERNEL_RCSID(0, "$NetBSD$");
Line 59  __KERNEL_RCSID(0, "$NetBSD$");
   
 #include <miscfs/genfs/genfs.h>  #include <miscfs/genfs/genfs.h>
 #include <miscfs/kernfs/kernfs.h>  #include <miscfs/kernfs/kernfs.h>
   #include <miscfs/specfs/specdev.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>
   
Line 95  const struct kern_target kern_targets[] 
Line 84  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 104  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 230  const struct vnodeopv_entry_desc kernfs_
Line 191  const struct vnodeopv_entry_desc kernfs_
         { &vop_setattr_desc, kernfs_setattr },          /* setattr */          { &vop_setattr_desc, kernfs_setattr },          /* setattr */
         { &vop_read_desc, kernfs_read },                /* read */          { &vop_read_desc, kernfs_read },                /* read */
         { &vop_write_desc, kernfs_write },              /* write */          { &vop_write_desc, kernfs_write },              /* write */
           { &vop_fallocate_desc, genfs_eopnotsupp },      /* fallocate */
           { &vop_fdiscard_desc, genfs_eopnotsupp },       /* fdiscard */
         { &vop_fcntl_desc, kernfs_fcntl },              /* fcntl */          { &vop_fcntl_desc, kernfs_fcntl },              /* fcntl */
         { &vop_ioctl_desc, kernfs_ioctl },              /* ioctl */          { &vop_ioctl_desc, kernfs_ioctl },              /* ioctl */
         { &vop_poll_desc, kernfs_poll },                /* poll */          { &vop_poll_desc, kernfs_poll },                /* poll */
Line 383  static int
Line 346  static int
 kernfs_xread(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;          const struct kern_target *kt;
 #ifdef IPSEC  
         struct mbuf *m;  
 #endif  
         int err;          int err;
   
         kt = kfs->kfs_kt;          kt = kfs->kfs_kt;
Line 468  kernfs_xread(struct kernfs_node *kfs, in
Line 428  kernfs_xread(struct kernfs_node *kfs, in
                     averunnable.ldavg[2], averunnable.fscale);                      averunnable.ldavg[2], averunnable.fscale);
                 break;                  break;
   
 #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.  
                  */  
                 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 (key_getspbyid == NULL)  
                         return 0;  
                 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 567  kernfs_xwrite(const struct kernfs_node *
Line 471  kernfs_xwrite(const struct kernfs_node *
 int  int
 kernfs_lookup(void *v)  kernfs_lookup(void *v)
 {  {
         struct vop_lookup_args /* {          struct vop_lookup_v2_args /* {
                 struct vnode * a_dvp;                  struct vnode * a_dvp;
                 struct vnode ** a_vpp;                  struct vnode ** a_vpp;
                 struct componentname * a_cnp;                  struct componentname * a_cnp;
Line 581  kernfs_lookup(void *v)
Line 485  kernfs_lookup(void *v)
         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;          int error, i;
 #ifdef IPSEC  
         char *ep;  
         u_int32_t id;  
 #endif  
   
         *vpp = NULLVP;          *vpp = NULLVP;
   
Line 622  kernfs_lookup(void *v)
Line 522  kernfs_lookup(void *v)
                 break;                  break;
   
         found:          found:
                 error = kernfs_allocvp(dvp->v_mount, vpp, kt->kt_tag, kt, 0);                  error = vcache_get(dvp->v_mount, &kt, sizeof(kt), vpp);
                 return (error);                  return error;
   
         case KFSsubdir:          case KFSsubdir:
                 ks = (struct kernfs_subdir *)kfs->kfs_kt->kt_data;                  ks = (struct kernfs_subdir *)kfs->kfs_kt->kt_data;
Line 641  kernfs_lookup(void *v)
Line 541  kernfs_lookup(void *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);  
                 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);  
                 return (error);  
 #endif  
   
         default:          default:
                 return (ENOTDIR);                  return (ENOTDIR);
         }          }
Line 701  kernfs_open(void *v)
Line 557  kernfs_open(void *v)
                 kauth_cred_t a_cred;                  kauth_cred_t a_cred;
         } */ *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) {  
 #ifdef IPSEC  
         case KFSipsecsa:  
                 if (key_setdumpsa_spi == NULL)  
                         return 0;  
                 m = key_setdumpsa_spi(htonl(kfs->kfs_value));  
                 if (m) {  
                         m_freem(m);  
                         return (0);  
                 } else  
                         return (ENOENT);  
   
         case KFSipsecsp:  
                 if (key_getspbyid == NULL)  
                         return 0;  
                 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);
                 return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_OPEN,  
                     v, 0);  
         }  
 }  }
   
 int  int
Line 745  kernfs_close(void *v)
Line 571  kernfs_close(void *v)
         } */ *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:  
                 if (key_freesp == NULL)  
                         return 0;  
                 key_freesp((struct secpolicy *)kfs->kfs_v);  
                 break;  
 #endif  
   
         default:  
                 return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_CLOSE,  
                     v, 0);  
         }  
   
         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  int
Line 791  kernfs_access(void *v)
Line 588  kernfs_access(void *v)
         if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred)) != 0)          if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred)) != 0)
                 return (error);                  return (error);
   
         error = kernfs_check_possible(ap->a_vp, ap->a_mode);          return kauth_authorize_vnode(ap->a_cred,
         if (error)              KAUTH_ACCESS_ACTION(ap->a_mode, ap->a_vp->v_type, va.va_mode),
                 return error;              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));
         error = kernfs_check_permitted(&va, ap->a_mode, ap->a_cred);  
   
         return error;  
 }  }
   
 static int  static int
Line 859  kernfs_getattr(void *v)
Line 653  kernfs_getattr(void *v)
                 vap->va_bytes = vap->va_size = DEV_BSIZE;                  vap->va_bytes = vap->va_size = DEV_BSIZE;
                 break;                  break;
   
           case KFSdevice:
                   vap->va_nlink = 1;
                   vap->va_rdev = ap->a_vp->v_rdev;
                   break;
   
         case KFSroot:          case KFSroot:
                 vap->va_nlink = 1;                  vap->va_nlink = 1;
                 vap->va_bytes = vap->va_size = DEV_BSIZE;                  vap->va_bytes = vap->va_size = DEV_BSIZE;
Line 876  kernfs_getattr(void *v)
Line 675  kernfs_getattr(void *v)
         case KFSstring:          case KFSstring:
         case KFShostname:          case KFShostname:
         case KFSavenrun:          case KFSavenrun:
         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 893  kernfs_getattr(void *v)
Line 687  kernfs_getattr(void *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 941  kernfs_default_xread(void *v)
Line 727  kernfs_default_xread(void *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 1041  kernfs_ioctl(void *v)
Line 827  kernfs_ioctl(void *v)
   
 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)      struct vop_readdir_args *ap)
 {  {
         struct kernfs_node *kfs;          struct kernfs_node *kfs;
         struct vnode *vp;          struct vnode *vp;
         int error;          int error;
   
         if ((error = kernfs_allocvp(ap->a_vp->v_mount, &vp, kt->kt_tag, kt,          if ((error = vcache_get(ap->a_vp->v_mount, &kt, sizeof(kt), &vp)) != 0)
             value)) != 0)  
                 return error;                  return error;
         if (kt->kt_tag == KFSdevice) {          kfs = VTOKERN(vp);
                 struct vattr va;          d->d_fileno = kfs->kfs_fileno;
           vrele(vp);
                 error = VOP_GETATTR(vp, &va, ap->a_cred);  
                 if (error != 0) {  
                         return error;  
                 }  
                 d->d_fileno = va.va_fileid;  
         } else {  
                 kfs = VTOKERN(vp);  
                 d->d_fileno = kfs->kfs_fileno;  
         }  
         vput(vp);  
         return 0;          return 0;
 }  }
   
Line 1086  kernfs_setdirentfileno(struct dirent *d,
Line 861  kernfs_setdirentfileno(struct dirent *d,
                 break;                  break;
         }          }
         if (ikt != thisdir_kfs->kfs_kt) {          if (ikt != thisdir_kfs->kfs_kt) {
                 if ((error = kernfs_setdirentfileno_kt(d, ikt, 0, ap)) != 0)                  if ((error = kernfs_setdirentfileno_kt(d, ikt, ap)) != 0)
                         return error;                          return error;
         } else          } else
                 d->d_fileno = thisdir_kfs->kfs_fileno;                  d->d_fileno = thisdir_kfs->kfs_fileno;
Line 1114  kernfs_readdir(void *v)
Line 889  kernfs_readdir(void *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 1168  kernfs_readdir(void *v)
Line 939  kernfs_readdir(void *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 (kt->kt_tag == KFSmsgbuf) {
                                 if (!msgbufenabled                                  if (!msgbufenabled
Line 1250  kernfs_readdir(void *v)
Line 1022  kernfs_readdir(void *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 1266  kernfs_readdir(void *v)
Line 1039  kernfs_readdir(void *v)
                 ncookies = n;                  ncookies = n;
                 break;                  break;
   
 #ifdef IPSEC  
         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;  
                             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 */  
                 if (&sptailq == NULL)  
                         return 0;  
   
                 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 1430  kernfs_inactive(void *v)
Line 1066  kernfs_inactive(void *v)
                 bool *a_recycle;                  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  
   
         *ap->a_recycle = false;          *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  
                         *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 {  
                         *ap->a_recycle = true;  
                 }  
                 break;  
 #endif  
         default:  
                 break;  
         }  
         VOP_UNLOCK(vp);          VOP_UNLOCK(vp);
         return (0);          return (0);
 }  }
Line 1472  kernfs_reclaim(void *v)
Line 1078  kernfs_reclaim(void *v)
         struct vop_reclaim_args /* {          struct vop_reclaim_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
         } */ *ap = v;          } */ *ap = v;
           struct vnode *vp = ap->a_vp;
           struct kernfs_node *kfs = VTOKERN(vp);
   
         return (kernfs_freevp(ap->a_vp));          vp->v_data = NULL;
           vcache_remove(vp->v_mount, &kfs->kfs_kt, sizeof(kfs->kfs_kt));
           mutex_enter(&kfs_lock);
           TAILQ_REMOVE(&VFSTOKERNFS(vp->v_mount)->nodelist, kfs, kfs_list);
           mutex_exit(&kfs_lock);
           kmem_free(kfs, sizeof(struct kernfs_node));
   
           return 0;
 }  }
   
 /*  /*
Line 1545  kernfs_link(void *v)
Line 1160  kernfs_link(void *v)
 int  int
 kernfs_symlink(void *v)  kernfs_symlink(void *v)
 {  {
         struct vop_symlink_args /* {          struct vop_symlink_v3_args /* {
                 struct vnode *a_dvp;                  struct vnode *a_dvp;
                 struct vnode **a_vpp;                  struct vnode **a_vpp;
                 struct componentname *a_cnp;                  struct componentname *a_cnp;
Line 1554  kernfs_symlink(void *v)
Line 1169  kernfs_symlink(void *v)
         } */ *ap = v;          } */ *ap = v;
   
         VOP_ABORTOP(ap->a_dvp, ap->a_cnp);          VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
         vput(ap->a_dvp);  
         return (EROFS);          return (EROFS);
 }  }

Legend:
Removed from v.1.142  
changed lines
  Added in v.1.154

CVSweb <webmaster@jp.NetBSD.org>