[BACK]Return to puffs_vnops.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / fs / puffs

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

Diff for /src/sys/fs/puffs/puffs_vnops.c between version 1.52.4.2 and 1.52.4.3

version 1.52.4.2, 2007/04/09 22:10:01 version 1.52.4.3, 2007/04/10 13:26:36
Line 83  int puffs_advlock(void *);
Line 83  int puffs_advlock(void *);
 int     puffs_strategy(void *);  int     puffs_strategy(void *);
 int     puffs_bmap(void *);  int     puffs_bmap(void *);
 int     puffs_mmap(void *);  int     puffs_mmap(void *);
   int     puffs_getpages(void *);
   
 int     puffs_spec_read(void *);  int     puffs_spec_read(void *);
 int     puffs_spec_write(void *);  int     puffs_spec_write(void *);
Line 286  const struct vnodeopv_entry_desc puffs_m
Line 287  const struct vnodeopv_entry_desc puffs_m
         { &vop_write_desc, puffs_write },               /* write */          { &vop_write_desc, puffs_write },               /* write */
         { &vop_fcntl_desc, puffs_fcntl },               /* fcntl */          { &vop_fcntl_desc, puffs_fcntl },               /* fcntl */
         { &vop_ioctl_desc, puffs_ioctl },               /* ioctl */          { &vop_ioctl_desc, puffs_ioctl },               /* ioctl */
         { &vop_fsync_desc, puffs_fsync },               /* fsync */  
         { &vop_seek_desc, puffs_seek },                 /* seek */          { &vop_seek_desc, puffs_seek },                 /* seek */
         { &vop_remove_desc, puffs_remove },             /* remove */          { &vop_remove_desc, puffs_remove },             /* remove */
         { &vop_link_desc, puffs_link },                 /* link */          { &vop_link_desc, puffs_link },                 /* link */
Line 300  const struct vnodeopv_entry_desc puffs_m
Line 300  const struct vnodeopv_entry_desc puffs_m
         { &vop_islocked_desc, puffs_islocked },         /* islocked */          { &vop_islocked_desc, puffs_islocked },         /* islocked */
         { &vop_pathconf_desc, puffs_pathconf },         /* pathconf */          { &vop_pathconf_desc, puffs_pathconf },         /* pathconf */
         { &vop_advlock_desc, puffs_advlock },           /* advlock */          { &vop_advlock_desc, puffs_advlock },           /* advlock */
         { &vop_getpages_desc, genfs_getpages },         /* getpages */          { &vop_getpages_desc, puffs_getpages },         /* getpages */
         { NULL, NULL }          { NULL, NULL }
 };  };
 const struct vnodeopv_desc puffs_msgop_opv_desc =  const struct vnodeopv_desc puffs_msgop_opv_desc =
Line 457  puffs_lookup(void *v)
Line 457  puffs_lookup(void *v)
                 VOP_UNLOCK(dvp, 0);                  VOP_UNLOCK(dvp, 0);
   
         error = puffs_vntouser(pmp, PUFFS_VN_LOOKUP,          error = puffs_vntouser(pmp, PUFFS_VN_LOOKUP,
             &lookup_arg, sizeof(lookup_arg), VPTOPNC(dvp), LOCKEDVP(dvp), NULL);              &lookup_arg, sizeof(lookup_arg), 0, VPTOPNC(dvp),
               LOCKEDVP(dvp), NULL);
         DPRINTF(("puffs_lookup: return of the userspace, part %d\n", error));          DPRINTF(("puffs_lookup: return of the userspace, part %d\n", error));
   
         /*          /*
Line 540  puffs_create(void *v)
Line 541  puffs_create(void *v)
         create_arg.pvnr_va = *ap->a_vap;          create_arg.pvnr_va = *ap->a_vap;
   
         error = puffs_vntouser(MPTOPUFFSMP(ap->a_dvp->v_mount), PUFFS_VN_CREATE,          error = puffs_vntouser(MPTOPUFFSMP(ap->a_dvp->v_mount), PUFFS_VN_CREATE,
             &create_arg, sizeof(create_arg), VPTOPNC(ap->a_dvp),              &create_arg, sizeof(create_arg), 0, VPTOPNC(ap->a_dvp),
             ap->a_dvp, NULL);              ap->a_dvp, NULL);
         if (error)          if (error)
                 goto out;                  goto out;
Line 576  puffs_mknod(void *v)
Line 577  puffs_mknod(void *v)
         mknod_arg.pvnr_va = *ap->a_vap;          mknod_arg.pvnr_va = *ap->a_vap;
   
         error = puffs_vntouser(MPTOPUFFSMP(ap->a_dvp->v_mount), PUFFS_VN_MKNOD,          error = puffs_vntouser(MPTOPUFFSMP(ap->a_dvp->v_mount), PUFFS_VN_MKNOD,
             &mknod_arg, sizeof(mknod_arg), VPTOPNC(ap->a_dvp), ap->a_dvp, NULL);              &mknod_arg, sizeof(mknod_arg), 0, VPTOPNC(ap->a_dvp),
               ap->a_dvp, NULL);
         if (error)          if (error)
                 goto out;                  goto out;
   
Line 624  puffs_open(void *v)
Line 626  puffs_open(void *v)
         open_arg.pvnr_pid = puffs_lwp2pid(ap->a_l);          open_arg.pvnr_pid = puffs_lwp2pid(ap->a_l);
   
         rv = puffs_vntouser(MPTOPUFFSMP(vp->v_mount), PUFFS_VN_OPEN,          rv = puffs_vntouser(MPTOPUFFSMP(vp->v_mount), PUFFS_VN_OPEN,
             &open_arg, sizeof(open_arg), VPTOPNC(vp), vp, NULL);              &open_arg, sizeof(open_arg), 0, VPTOPNC(vp), vp, NULL);
   
  out:   out:
         DPRINTF(("puffs_open: returning %d\n", rv));          DPRINTF(("puffs_open: returning %d\n", rv));
Line 649  puffs_close(void *v)
Line 651  puffs_close(void *v)
         close_arg.pvnr_pid = puffs_lwp2pid(ap->a_l);          close_arg.pvnr_pid = puffs_lwp2pid(ap->a_l);
   
         return puffs_vntouser(MPTOPUFFSMP(ap->a_vp->v_mount), PUFFS_VN_CLOSE,          return puffs_vntouser(MPTOPUFFSMP(ap->a_vp->v_mount), PUFFS_VN_CLOSE,
             &close_arg, sizeof(close_arg), VPTOPNC(ap->a_vp), ap->a_vp, NULL);              &close_arg, sizeof(close_arg), 0, VPTOPNC(ap->a_vp),
               ap->a_vp, NULL);
 }  }
   
 int  int
Line 679  puffs_access(void *v)
Line 682  puffs_access(void *v)
         puffs_credcvt(&access_arg.pvnr_cred, ap->a_cred);          puffs_credcvt(&access_arg.pvnr_cred, ap->a_cred);
   
         return puffs_vntouser(MPTOPUFFSMP(vp->v_mount), PUFFS_VN_ACCESS,          return puffs_vntouser(MPTOPUFFSMP(vp->v_mount), PUFFS_VN_ACCESS,
             &access_arg, sizeof(access_arg), VPTOPNC(vp), vp, NULL);              &access_arg, sizeof(access_arg), 0, VPTOPNC(vp), vp, NULL);
 }  }
   
 int  int
Line 693  puffs_getattr(void *v)
Line 696  puffs_getattr(void *v)
                 struct lwp *a_l;                  struct lwp *a_l;
         } */ *ap = v;          } */ *ap = v;
         struct mount *mp;          struct mount *mp;
           struct vnode *vp;
           struct vattr *vap;
           struct puffs_node *pn;
         int error;          int error;
   
         PUFFS_VNREQ(getattr);          PUFFS_VNREQ(getattr);
   
         mp = ap->a_vp->v_mount;          vp = ap->a_vp;
           mp = vp->v_mount;
           vap = ap->a_vap;
   
         vattr_null(&getattr_arg.pvnr_va);          vattr_null(&getattr_arg.pvnr_va);
         puffs_credcvt(&getattr_arg.pvnr_cred, ap->a_cred);          puffs_credcvt(&getattr_arg.pvnr_cred, ap->a_cred);
Line 709  puffs_getattr(void *v)
Line 717  puffs_getattr(void *v)
          * around with VXLOCK and therefore breaks vn_lock().  Proper           * around with VXLOCK and therefore breaks vn_lock().  Proper
          * fix pending.           * fix pending.
          */           */
         error = puffs_vntouser(MPTOPUFFSMP(ap->a_vp->v_mount), PUFFS_VN_GETATTR,          error = puffs_vntouser(MPTOPUFFSMP(vp->v_mount), PUFFS_VN_GETATTR,
             &getattr_arg, sizeof(getattr_arg), VPTOPNC(ap->a_vp),              &getattr_arg, sizeof(getattr_arg), 0, VPTOPNC(vp),
             NULL /* XXXseeabove: should be LOCKEDVP(ap->a_vp) */, NULL);              NULL /* XXXseeabove: should be LOCKEDVP(vp) */, NULL);
         if (error)          if (error)
                 return error;                  return error;
   
         (void)memcpy(ap->a_vap, &getattr_arg.pvnr_va, sizeof(struct vattr));          (void) memcpy(vap, &getattr_arg.pvnr_va, sizeof(struct vattr));
           vap->va_fsid = mp->mnt_stat.f_fsidx.__fsid_val[0];
   
         /*          pn = VPTOPP(vp);
          * fill in information userspace does not have          if (pn->pn_stat & PNODE_METACACHE_ATIME)
          * XXX: but would it be better to do fsid at the generic level?                  vap->va_atime = pn->pn_mc_atime;
          */          if (pn->pn_stat & PNODE_METACACHE_CTIME)
         ap->a_vap->va_fsid = mp->mnt_stat.f_fsidx.__fsid_val[0];                  vap->va_ctime = pn->pn_mc_ctime;
           if (pn->pn_stat & PNODE_METACACHE_MTIME)
                   vap->va_mtime = pn->pn_mc_mtime;
           if (pn->pn_stat & PNODE_METACACHE_SIZE) {
                   vap->va_size = pn->pn_mc_size;
           } else {
                   if (getattr_arg.pvnr_va.va_size != VNOVAL)
                           uvm_vnp_setsize(vp, getattr_arg.pvnr_va.va_size);
           }
   
         return 0;          return 0;
 }  }
Line 745  puffs_setattr(void *v)
Line 762  puffs_setattr(void *v)
         setattr_arg.pvnr_pid = puffs_lwp2pid(ap->a_l);          setattr_arg.pvnr_pid = puffs_lwp2pid(ap->a_l);
   
         error = puffs_vntouser(MPTOPUFFSMP(ap->a_vp->v_mount), PUFFS_VN_SETATTR,          error = puffs_vntouser(MPTOPUFFSMP(ap->a_vp->v_mount), PUFFS_VN_SETATTR,
             &setattr_arg, sizeof(setattr_arg), VPTOPNC(ap->a_vp),              &setattr_arg, sizeof(setattr_arg), 0, VPTOPNC(ap->a_vp),
             ap->a_vp, NULL);              ap->a_vp, NULL);
         if (error)          if (error)
                 return error;                  return error;
Line 782  puffs_inactive(void *v)
Line 799  puffs_inactive(void *v)
   
         if (EXISTSOP(pmp, INACTIVE))          if (EXISTSOP(pmp, INACTIVE))
                 rv = puffs_vntouser(pmp, PUFFS_VN_INACTIVE,                  rv = puffs_vntouser(pmp, PUFFS_VN_INACTIVE,
                     &inactive_arg, sizeof(inactive_arg), VPTOPNC(ap->a_vp),                      &inactive_arg, sizeof(inactive_arg), 0, VPTOPNC(ap->a_vp),
                     ap->a_vp, NULL);                      ap->a_vp, NULL);
         else          else
                 rv = 1; /* see below */                  rv = 1; /* see below */
Line 831  puffs_reclaim(void *v)
Line 848  puffs_reclaim(void *v)
          * puffs_root(), since there is only one of us.           * puffs_root(), since there is only one of us.
          */           */
         if (ap->a_vp->v_flag & VROOT) {          if (ap->a_vp->v_flag & VROOT) {
                 simple_lock(&pmp->pmp_lock);                  mutex_enter(&pmp->pmp_lock);
                 KASSERT(pmp->pmp_root != NULL);                  KASSERT(pmp->pmp_root != NULL);
                 pmp->pmp_root = NULL;                  pmp->pmp_root = NULL;
                 simple_unlock(&pmp->pmp_lock);                  mutex_exit(&pmp->pmp_lock);
                 goto out;                  goto out;
         }          }
   
Line 879  puffs_readdir(void *v)
Line 896  puffs_readdir(void *v)
         if (!(ap->a_cookies == NULL && ap->a_ncookies == NULL))          if (!(ap->a_cookies == NULL && ap->a_ncookies == NULL))
                 return EOPNOTSUPP;                  return EOPNOTSUPP;
   
         argsize = sizeof(struct puffs_vnreq_readdir);          argsize = sizeof(struct puffs_vnreq_readdir) + uio->uio_resid;
         readdir_argp = malloc(argsize, M_PUFFS, M_ZERO | M_WAITOK);          readdir_argp = malloc(argsize, M_PUFFS, M_ZERO | M_WAITOK);
   
         puffs_credcvt(&readdir_argp->pvnr_cred, ap->a_cred);          puffs_credcvt(&readdir_argp->pvnr_cred, ap->a_cred);
         readdir_argp->pvnr_offset = uio->uio_offset;          readdir_argp->pvnr_offset = uio->uio_offset;
         readdir_argp->pvnr_resid = uio->uio_resid;          readdir_argp->pvnr_resid = uio->uio_resid;
   
         error = puffs_vntouser_adjbuf(MPTOPUFFSMP(ap->a_vp->v_mount),          error = puffs_vntouser(MPTOPUFFSMP(ap->a_vp->v_mount),
             PUFFS_VN_READDIR, (void **)&readdir_argp, &argsize,              PUFFS_VN_READDIR, readdir_argp, argsize,
             readdir_argp->pvnr_resid, VPTOPNC(ap->a_vp), ap->a_vp, NULL);              uio->uio_resid, VPTOPNC(ap->a_vp), ap->a_vp, NULL);
         if (error)          if (error)
                 goto out;                  goto out;
   
Line 931  puffs_poll(void *v)
Line 948  puffs_poll(void *v)
         poll_arg.pvnr_pid = puffs_lwp2pid(ap->a_l);          poll_arg.pvnr_pid = puffs_lwp2pid(ap->a_l);
   
         return puffs_vntouser(MPTOPUFFSMP(ap->a_vp->v_mount), PUFFS_VN_POLL,          return puffs_vntouser(MPTOPUFFSMP(ap->a_vp->v_mount), PUFFS_VN_POLL,
             &poll_arg, sizeof(poll_arg), VPTOPNC(ap->a_vp), NULL, NULL);              &poll_arg, sizeof(poll_arg), 0, VPTOPNC(ap->a_vp), NULL, NULL);
 }  }
   
 int  int
Line 946  puffs_fsync(void *v)
Line 963  puffs_fsync(void *v)
                 off_t a_offhi;                  off_t a_offhi;
                 struct lwp *a_l;                  struct lwp *a_l;
         } */ *ap = v;          } */ *ap = v;
           struct vattr va;
         struct puffs_mount *pmp;          struct puffs_mount *pmp;
         struct puffs_vnreq_fsync *fsync_argp;          struct puffs_vnreq_fsync *fsync_argp;
         struct vnode *vp;          struct vnode *vp;
Line 958  puffs_fsync(void *v)
Line 976  puffs_fsync(void *v)
         pn = VPTOPP(vp);          pn = VPTOPP(vp);
         pmp = MPTOPUFFSMP(vp->v_mount);          pmp = MPTOPUFFSMP(vp->v_mount);
   
         pflags = PGO_CLEANIT;          /* flush out information from our metacache */
         if (ap->a_flags & FSYNC_WAIT)          if (pn->pn_stat & PNODE_METACACHE_MASK) {
                 pflags |= PGO_SYNCIO;                  vattr_null(&va);
                   if (pn->pn_stat & PNODE_METACACHE_ATIME)
                           va.va_atime = pn->pn_mc_atime;
                   if (pn->pn_stat & PNODE_METACACHE_CTIME)
                           va.va_ctime = pn->pn_mc_ctime;
                   if (pn->pn_stat & PNODE_METACACHE_MTIME)
                           va.va_mtime = pn->pn_mc_ctime;
                   if (pn->pn_stat & PNODE_METACACHE_SIZE)
                           va.va_size = pn->pn_mc_size;
   
                   error = VOP_SETATTR(vp, &va, FSCRED, NULL);
                   if (error)
                           return error;
   
                   pn->pn_stat &= ~PNODE_METACACHE_MASK;
           }
   
         /*          /*
          * flush pages to avoid being overly dirty           * flush pages to avoid being overly dirty
          */           */
           pflags = PGO_CLEANIT;
           if (ap->a_flags & FSYNC_WAIT)
                   pflags |= PGO_SYNCIO;
         mutex_enter(&vp->v_interlock);          mutex_enter(&vp->v_interlock);
         error = VOP_PUTPAGES(vp, trunc_page(ap->a_offlo),          error = VOP_PUTPAGES(vp, trunc_page(ap->a_offlo),
             round_page(ap->a_offhi), pflags);              round_page(ap->a_offhi), pflags);
Line 1018  puffs_fsync(void *v)
Line 1054  puffs_fsync(void *v)
          */           */
         if (dofaf == 0) {          if (dofaf == 0) {
                 error =  puffs_vntouser(MPTOPUFFSMP(vp->v_mount),                  error =  puffs_vntouser(MPTOPUFFSMP(vp->v_mount),
                     PUFFS_VN_FSYNC, fsync_argp, sizeof(*fsync_argp),                      PUFFS_VN_FSYNC, fsync_argp, sizeof(*fsync_argp), 0,
                     VPTOPNC(vp), NULL /* XXXshouldbe: vp */, NULL);                      VPTOPNC(vp), NULL /* XXXshouldbe: vp */, NULL);
         } else {          } else {
                 /* FAF is always "succesful" */                  /* FAF is always "succesful" */
Line 1053  puffs_seek(void *v)
Line 1089  puffs_seek(void *v)
          * it can't hurt to play safe           * it can't hurt to play safe
          */           */
         return puffs_vntouser(MPTOPUFFSMP(ap->a_vp->v_mount), PUFFS_VN_SEEK,          return puffs_vntouser(MPTOPUFFSMP(ap->a_vp->v_mount), PUFFS_VN_SEEK,
             &seek_arg, sizeof(seek_arg), VPTOPNC(ap->a_vp),              &seek_arg, sizeof(seek_arg), 0, VPTOPNC(ap->a_vp),
             LOCKEDVP(ap->a_vp), NULL);              LOCKEDVP(ap->a_vp), NULL);
 }  }
   
Line 1074  puffs_remove(void *v)
Line 1110  puffs_remove(void *v)
         puffs_makecn(&remove_arg.pvnr_cn, ap->a_cnp);          puffs_makecn(&remove_arg.pvnr_cn, ap->a_cnp);
   
         error = puffs_vntouser(MPTOPUFFSMP(ap->a_vp->v_mount), PUFFS_VN_REMOVE,          error = puffs_vntouser(MPTOPUFFSMP(ap->a_vp->v_mount), PUFFS_VN_REMOVE,
             &remove_arg, sizeof(remove_arg), VPTOPNC(ap->a_dvp),              &remove_arg, sizeof(remove_arg), 0, VPTOPNC(ap->a_dvp),
             ap->a_dvp, ap->a_vp);              ap->a_dvp, ap->a_vp);
   
         vput(ap->a_vp);          vput(ap->a_vp);
Line 1105  puffs_mkdir(void *v)
Line 1141  puffs_mkdir(void *v)
   
         /* XXX: wouldn't need to relock dvp, but that's life */          /* XXX: wouldn't need to relock dvp, but that's life */
         error = puffs_vntouser(MPTOPUFFSMP(ap->a_dvp->v_mount), PUFFS_VN_MKDIR,          error = puffs_vntouser(MPTOPUFFSMP(ap->a_dvp->v_mount), PUFFS_VN_MKDIR,
             &mkdir_arg, sizeof(mkdir_arg), VPTOPNC(ap->a_dvp), ap->a_dvp, NULL);              &mkdir_arg, sizeof(mkdir_arg), 0, VPTOPNC(ap->a_dvp),
               ap->a_dvp, NULL);
         if (error)          if (error)
                 goto out;                  goto out;
   
Line 1136  puffs_rmdir(void *v)
Line 1173  puffs_rmdir(void *v)
         puffs_makecn(&rmdir_arg.pvnr_cn, ap->a_cnp);          puffs_makecn(&rmdir_arg.pvnr_cn, ap->a_cnp);
   
         error = puffs_vntouser(MPTOPUFFSMP(ap->a_dvp->v_mount), PUFFS_VN_RMDIR,          error = puffs_vntouser(MPTOPUFFSMP(ap->a_dvp->v_mount), PUFFS_VN_RMDIR,
             &rmdir_arg, sizeof(rmdir_arg), VPTOPNC(ap->a_dvp),              &rmdir_arg, sizeof(rmdir_arg), 0, VPTOPNC(ap->a_dvp),
             ap->a_dvp, ap->a_vp);              ap->a_dvp, ap->a_vp);
   
         /* XXX: some call cache_purge() *for both vnodes* here, investigate */          /* XXX: some call cache_purge() *for both vnodes* here, investigate */
Line 1164  puffs_link(void *v)
Line 1201  puffs_link(void *v)
         puffs_makecn(&link_arg.pvnr_cn, ap->a_cnp);          puffs_makecn(&link_arg.pvnr_cn, ap->a_cnp);
   
         error = puffs_vntouser(MPTOPUFFSMP(ap->a_dvp->v_mount), PUFFS_VN_LINK,          error = puffs_vntouser(MPTOPUFFSMP(ap->a_dvp->v_mount), PUFFS_VN_LINK,
             &link_arg, sizeof(link_arg), VPTOPNC(ap->a_dvp), ap->a_dvp, NULL);              &link_arg, sizeof(link_arg), 0, VPTOPNC(ap->a_dvp),
               ap->a_dvp, NULL);
   
           /*
            * XXX: stay in touch with the cache.  I don't like this, but
            * don't have a better solution either.  See also puffs_rename().
            */
           if (error == 0)
                   puffs_updatenode(ap->a_vp, PUFFS_UPDATECTIME);
   
         vput(ap->a_dvp);          vput(ap->a_dvp);
   
Line 1195  puffs_symlink(void *v)
Line 1240  puffs_symlink(void *v)
   
         /* XXX: don't need to relock parent */          /* XXX: don't need to relock parent */
         error =  puffs_vntouser(MPTOPUFFSMP(ap->a_dvp->v_mount),          error =  puffs_vntouser(MPTOPUFFSMP(ap->a_dvp->v_mount),
             PUFFS_VN_SYMLINK, &symlink_arg, sizeof(symlink_arg),              PUFFS_VN_SYMLINK, &symlink_arg, sizeof(symlink_arg), 0,
             VPTOPNC(ap->a_dvp), ap->a_dvp, NULL);              VPTOPNC(ap->a_dvp), ap->a_dvp, NULL);
         if (error)          if (error)
                 goto out;                  goto out;
Line 1229  puffs_readlink(void *v)
Line 1274  puffs_readlink(void *v)
         readlink_arg.pvnr_linklen = linklen;          readlink_arg.pvnr_linklen = linklen;
   
         error = puffs_vntouser(MPTOPUFFSMP(ap->a_vp->v_mount),          error = puffs_vntouser(MPTOPUFFSMP(ap->a_vp->v_mount),
             PUFFS_VN_READLINK, &readlink_arg, sizeof(readlink_arg),              PUFFS_VN_READLINK, &readlink_arg, sizeof(readlink_arg), 0,
             VPTOPNC(ap->a_vp), ap->a_vp, NULL);              VPTOPNC(ap->a_vp), ap->a_vp, NULL);
         if (error)          if (error)
                 return error;                  return error;
Line 1274  puffs_rename(void *v)
Line 1319  puffs_rename(void *v)
         puffs_makecn(&rename_arg.pvnr_cn_targ, ap->a_tcnp);          puffs_makecn(&rename_arg.pvnr_cn_targ, ap->a_tcnp);
   
         error = puffs_vntouser(MPTOPUFFSMP(ap->a_fdvp->v_mount),          error = puffs_vntouser(MPTOPUFFSMP(ap->a_fdvp->v_mount),
             PUFFS_VN_RENAME, &rename_arg, sizeof(rename_arg),              PUFFS_VN_RENAME, &rename_arg, sizeof(rename_arg), 0,
             VPTOPNC(ap->a_fdvp), NULL, NULL);              VPTOPNC(ap->a_fdvp), NULL, NULL);
   
           /*
            * XXX: stay in touch with the cache.  I don't like this, but
            * don't have a better solution either.  See also puffs_link().
            */
           if (error == 0)
                   puffs_updatenode(ap->a_fvp, PUFFS_UPDATECTIME);
   
  out:   out:
         if (ap->a_tvp != NULL)          if (ap->a_tvp != NULL)
                 vput(ap->a_tvp);                  vput(ap->a_tvp);
Line 1354  puffs_read(void *v)
Line 1406  puffs_read(void *v)
   
                 tomove = PUFFS_TOMOVE(uio->uio_resid, pmp);                  tomove = PUFFS_TOMOVE(uio->uio_resid, pmp);
                 argsize = sizeof(struct puffs_vnreq_read);                  argsize = sizeof(struct puffs_vnreq_read);
                 read_argp = malloc(argsize, M_PUFFS, M_WAITOK | M_ZERO);                  read_argp = malloc(argsize + tomove,
                       M_PUFFS, M_WAITOK | M_ZERO);
   
                 error = 0;                  error = 0;
                 while (uio->uio_resid > 0) {                  while (uio->uio_resid > 0) {
Line 1364  puffs_read(void *v)
Line 1417  puffs_read(void *v)
                         puffs_credcvt(&read_argp->pvnr_cred, ap->a_cred);                          puffs_credcvt(&read_argp->pvnr_cred, ap->a_cred);
   
                         argsize = sizeof(struct puffs_vnreq_read);                          argsize = sizeof(struct puffs_vnreq_read);
                         error = puffs_vntouser_adjbuf(pmp, PUFFS_VN_READ,                          error = puffs_vntouser(pmp, PUFFS_VN_READ,
                             (void **)&read_argp, &argsize,                              read_argp, argsize, tomove,
                             read_argp->pvnr_resid, VPTOPNC(ap->a_vp),                              VPTOPNC(ap->a_vp), ap->a_vp, NULL);
                             ap->a_vp, NULL);  
                         if (error)                          if (error)
                                 break;                                  break;
   
Line 1514  puffs_write(void *v)
Line 1566  puffs_write(void *v)
                                 break;                                  break;
   
                         error = puffs_vntouser(MPTOPUFFSMP(ap->a_vp->v_mount),                          error = puffs_vntouser(MPTOPUFFSMP(ap->a_vp->v_mount),
                             PUFFS_VN_WRITE, write_argp, argsize,                              PUFFS_VN_WRITE, write_argp, argsize, 0,
                             VPTOPNC(ap->a_vp), ap->a_vp, NULL);                              VPTOPNC(ap->a_vp), ap->a_vp, NULL);
                         if (error) {                          if (error) {
                                 /* restore uiomove */                                  /* restore uiomove */
Line 1603  puffs_fcnioctl(struct vop_ioctl_args *ap
Line 1655  puffs_fcnioctl(struct vop_ioctl_args *ap
         fcnioctl_arg.pvnr_pid = puffs_lwp2pid(ap->a_l);          fcnioctl_arg.pvnr_pid = puffs_lwp2pid(ap->a_l);
   
         error = puffs_vntouser_req(MPTOPUFFSMP(ap->a_vp->v_mount), puffsop,          error = puffs_vntouser_req(MPTOPUFFSMP(ap->a_vp->v_mount), puffsop,
             &fcnioctl_arg, sizeof(fcnioctl_arg), VPTOPNC(ap->a_vp),              &fcnioctl_arg, sizeof(fcnioctl_arg), 0, VPTOPNC(ap->a_vp),
             pspark.pkso_reqid, NULL, NULL);              pspark.pkso_reqid, NULL, NULL);
   
         /* if we don't need to copy data, we're done */          /* if we don't need to copy data, we're done */
Line 1661  puffs_print(void *v)
Line 1713  puffs_print(void *v)
         /* userspace portion */          /* userspace portion */
         if (EXISTSOP(pmp, PRINT))          if (EXISTSOP(pmp, PRINT))
                 puffs_vntouser(pmp, PUFFS_VN_PRINT,                  puffs_vntouser(pmp, PUFFS_VN_PRINT,
                     &print_arg, sizeof(print_arg), VPTOPNC(ap->a_vp),                      &print_arg, sizeof(print_arg), 0, VPTOPNC(ap->a_vp),
                     LOCKEDVP(ap->a_vp), NULL);                      LOCKEDVP(ap->a_vp), NULL);
   
         return 0;          return 0;
Line 1683  puffs_pathconf(void *v)
Line 1735  puffs_pathconf(void *v)
         pathconf_arg.pvnr_name = ap->a_name;          pathconf_arg.pvnr_name = ap->a_name;
   
         error = puffs_vntouser(MPTOPUFFSMP(ap->a_vp->v_mount),          error = puffs_vntouser(MPTOPUFFSMP(ap->a_vp->v_mount),
             PUFFS_VN_PATHCONF, &pathconf_arg, sizeof(pathconf_arg),              PUFFS_VN_PATHCONF, &pathconf_arg, sizeof(pathconf_arg), 0,
             VPTOPNC(ap->a_vp), ap->a_vp, NULL);              VPTOPNC(ap->a_vp), ap->a_vp, NULL);
         if (error)          if (error)
                 return error;                  return error;
Line 1716  puffs_advlock(void *v)
Line 1768  puffs_advlock(void *v)
         advlock_arg.pvnr_flags = ap->a_flags;          advlock_arg.pvnr_flags = ap->a_flags;
   
         return puffs_vntouser(MPTOPUFFSMP(ap->a_vp->v_mount), PUFFS_VN_ADVLOCK,          return puffs_vntouser(MPTOPUFFSMP(ap->a_vp->v_mount), PUFFS_VN_ADVLOCK,
             &advlock_arg, sizeof(advlock_arg), VPTOPNC(ap->a_vp), NULL, NULL);              &advlock_arg, sizeof(advlock_arg), 0, VPTOPNC(ap->a_vp),
               NULL, NULL);
 }  }
 /*  /*
  * This maps itself to PUFFS_VN_READ/WRITE for data transfer.   * This maps itself to PUFFS_VN_READ/WRITE for data transfer.
Line 1787  puffs_strategy(void *v)
Line 1840  puffs_strategy(void *v)
                 dowritefaf = 1;                  dowritefaf = 1;
   
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
         if (dowritefaf)  
                 KASSERT((bp->b_flags & B_READ) == 0);  
         if (curlwp == uvm.pagedaemon_lwp)          if (curlwp == uvm.pagedaemon_lwp)
                 KASSERT(dowritefaf);                  KASSERT(dowritefaf);
 #endif  #endif
   
         if (bp->b_flags & B_READ) {          tomove = PUFFS_TOMOVE(bp->b_bcount, pmp);
   
           if ((bp->b_flags & (B_READ | B_ASYNC)) == (B_READ | B_ASYNC)) {
                 argsize = sizeof(struct puffs_vnreq_read);                  argsize = sizeof(struct puffs_vnreq_read);
                 read_argp = malloc(argsize, M_PUFFS, M_NOWAIT | M_ZERO);                  read_argp = malloc(argsize + tomove,
                       M_PUFFS, M_NOWAIT | M_ZERO);
                 if (read_argp == NULL) {                  if (read_argp == NULL) {
                         error = ENOMEM;                          error = ENOMEM;
                         goto out;                          goto out;
                 }                  }
   
                 tomove = PUFFS_TOMOVE(bp->b_bcount, pmp);                  read_argp->pvnr_ioflag = 0;
                   read_argp->pvnr_resid = tomove;
                   read_argp->pvnr_offset = bp->b_blkno << DEV_BSHIFT;
                   puffs_credcvt(&read_argp->pvnr_cred, FSCRED);
   
                   puffs_vntouser_call(pmp, PUFFS_VN_READ, read_argp,
                       argsize, tomove, VPTOPNC(vp),
                       puffs_parkdone_asyncbioread, bp,
                       LOCKEDVP(vp), NULL);
                   error = 0;
                   goto wayout;
           } else if (bp->b_flags & B_READ) {
                   argsize = sizeof(struct puffs_vnreq_read);
                   read_argp = malloc(argsize + tomove,
                       M_PUFFS, M_WAITOK | M_ZERO);
   
                 read_argp->pvnr_ioflag = 0;                  read_argp->pvnr_ioflag = 0;
                 read_argp->pvnr_resid = tomove;                  read_argp->pvnr_resid = tomove;
                 read_argp->pvnr_offset = bp->b_blkno << DEV_BSHIFT;                  read_argp->pvnr_offset = bp->b_blkno << DEV_BSHIFT;
                 puffs_credcvt(&read_argp->pvnr_cred, FSCRED);                  puffs_credcvt(&read_argp->pvnr_cred, FSCRED);
   
                 error = puffs_vntouser_adjbuf(pmp, PUFFS_VN_READ,                  error = puffs_vntouser(pmp, PUFFS_VN_READ,
                     (void **)&read_argp, &argsize, read_argp->pvnr_resid,                      read_argp, argsize, tomove,
                     VPTOPNC(vp), LOCKEDVP(vp), NULL);                      VPTOPNC(vp), LOCKEDVP(vp), NULL);
   
                 if (error)                  if (error)
Line 1825  puffs_strategy(void *v)
Line 1893  puffs_strategy(void *v)
                 (void)memcpy(bp->b_data, read_argp->pvnr_data, moved);                  (void)memcpy(bp->b_data, read_argp->pvnr_data, moved);
                 bp->b_resid = bp->b_bcount - moved;                  bp->b_resid = bp->b_bcount - moved;
         } else {          } else {
                   /*
                    * make pages read-only before we write them if we want
                    * write caching info
                    */
                   if (PUFFS_WCACHEINFO(pmp)) {
                           struct uvm_object *uobj = &vp->v_uobj;
                           int npages = (bp->b_bcount + PAGE_SIZE-1) >> PAGE_SHIFT;
                           struct vm_page *vmp;
                           int i;
   
                           for (i = 0; i < npages; i++) {
                                   vmp= uvm_pageratop((vaddr_t)bp->b_data
                                       + (i << PAGE_SHIFT));
                                   DPRINTF(("puffs_strategy: write-protecting "
                                       "vp %p page %p, offset %" PRId64"\n",
                                       vp, vmp, vmp->offset));
                                   mutex_enter(&uobj->vmobjlock);
                                   vmp->flags |= PG_RDONLY;
                                   pmap_page_protect(vmp, VM_PROT_READ);
                                   mutex_exit(&uobj->vmobjlock);
                           }
                   }
   
                 argsize = sizeof(struct puffs_vnreq_write) + bp->b_bcount;                  argsize = sizeof(struct puffs_vnreq_write) + bp->b_bcount;
                 write_argp = malloc(argsize, M_PUFFS, M_NOWAIT | M_ZERO);                  write_argp = malloc(argsize, M_PUFFS, M_NOWAIT | M_ZERO);
                 if (write_argp == NULL) {                  if (write_argp == NULL) {
Line 1832  puffs_strategy(void *v)
Line 1923  puffs_strategy(void *v)
                         goto out;                          goto out;
                 }                  }
   
                 tomove = PUFFS_TOMOVE(bp->b_bcount, pmp);  
   
                 write_argp->pvnr_ioflag = 0;                  write_argp->pvnr_ioflag = 0;
                 write_argp->pvnr_resid = tomove;                  write_argp->pvnr_resid = tomove;
                 write_argp->pvnr_offset = bp->b_blkno << DEV_BSHIFT;                  write_argp->pvnr_offset = bp->b_blkno << DEV_BSHIFT;
Line 1851  puffs_strategy(void *v)
Line 1940  puffs_strategy(void *v)
                         bp->b_resid = bp->b_bcount - tomove;                          bp->b_resid = bp->b_bcount - tomove;
                 } else {                  } else {
                         error = puffs_vntouser(MPTOPUFFSMP(vp->v_mount),                          error = puffs_vntouser(MPTOPUFFSMP(vp->v_mount),
                             PUFFS_VN_WRITE, write_argp, argsize, VPTOPNC(vp),                              PUFFS_VN_WRITE, write_argp, argsize, 0, VPTOPNC(vp),
                             vp, NULL);                              vp, NULL);
                         if (error)                          if (error)
                                 goto out;                                  goto out;
Line 1879  puffs_strategy(void *v)
Line 1968  puffs_strategy(void *v)
                 bp->b_flags |= B_ERROR;                  bp->b_flags |= B_ERROR;
         }          }
   
         biodone(bp);          if ((bp->b_flags & (B_READ | B_ASYNC)) != (B_READ | B_ASYNC))
                   biodone(bp);
    wayout:
         return error;          return error;
 }  }
   
Line 1909  puffs_mmap(void *v)
Line 2000  puffs_mmap(void *v)
                 mmap_arg.pvnr_pid = puffs_lwp2pid(ap->a_l);                  mmap_arg.pvnr_pid = puffs_lwp2pid(ap->a_l);
   
                 error = puffs_vntouser(pmp, PUFFS_VN_MMAP,                  error = puffs_vntouser(pmp, PUFFS_VN_MMAP,
                     &mmap_arg, sizeof(mmap_arg),                      &mmap_arg, sizeof(mmap_arg), 0,
                     VPTOPNC(ap->a_vp), NULL, NULL);                      VPTOPNC(ap->a_vp), NULL, NULL);
         } else {          } else {
                 error = genfs_mmap(v);                  error = genfs_mmap(v);
Line 1948  puffs_bmap(void *v)
Line 2039  puffs_bmap(void *v)
         if (ap->a_bnp)          if (ap->a_bnp)
                 *ap->a_bnp = ap->a_bn;                  *ap->a_bnp = ap->a_bn;
         if (ap->a_runp)          if (ap->a_runp)
                 *ap->a_runp = pmp->pmp_req_maxsize - PUFFS_REQSTRUCT_MAX;                  *ap->a_runp
                       = (PUFFS_TOMOVE(pmp->pmp_req_maxsize, pmp)>>DEV_BSHIFT) - 1;
   
         return 0;          return 0;
 }  }
   
   /*
    * Handle getpages faults in puffs.  We let genfs_getpages() do most
    * of the dirty work, but we come in this route to do accounting tasks.
    * If the user server has specified functions for cache notifications
    * about reads and/or writes, we record which type of operation we got,
    * for which page range, and proceed to issue a FAF notification to the
    * server about it.
    */
   int
   puffs_getpages(void *v)
   {
           struct vop_getpages_args /* {
                   const struct vnodeop_desc *a_desc;
                   struct vnode *a_vp;
                   voff_t a_offset;
                   struct vm_page **a_m;
                   int *a_count;
                   int a_centeridx;
                   vm_prot_t a_access_type;
                   int a_advice;
                   int a_flags;
           } */ *ap = v;
           struct puffs_mount *pmp;
           struct vnode *vp;
           struct vm_page **pgs;
           struct puffs_cacheinfo *pcinfo = NULL;
           struct puffs_cacherun *pcrun;
           void *parkmem = NULL;
           size_t runsizes;
           int i, npages, si, streakon;
           int error, locked, write;
   
           pmp = MPTOPUFFSMP(ap->a_vp->v_mount);
           npages = *ap->a_count;
           pgs = ap->a_m;
           vp = ap->a_vp;
           locked = (ap->a_flags & PGO_LOCKED) != 0;
           write = (ap->a_access_type & VM_PROT_WRITE) != 0;
   
           /* ccg xnaht - gets Wuninitialized wrong */
           pcrun = NULL;
           runsizes = 0;
   
           if (write && PUFFS_WCACHEINFO(pmp)) {
                   /* allocate worst-case memory */
                   runsizes = ((npages / 2) + 1) * sizeof(struct puffs_cacherun);
                   pcinfo = malloc(sizeof(struct puffs_cacheinfo) + runsizes,
                       M_PUFFS, M_ZERO | locked ? M_NOWAIT : M_WAITOK);
   
                   /*
                    * can't block if we're locked and can't mess up caching
                    * information for fs server.  so come back later, please
                    */
                   if (pcinfo == NULL) {
                           error = ENOMEM;
                           goto out;
                   }
   
                   parkmem = puffs_park_alloc(locked == 0);
                   if (parkmem == NULL) {
                           error = ENOMEM;
                           goto out;
                   }
   
                   pcrun = pcinfo->pcache_runs;
           }
   
           error = genfs_getpages(v);
           if (error)
                   goto out;
   
           if (PUFFS_WCACHEINFO(pmp) == 0)
                   goto out;
   
           /*
            * Let's see whose fault it was and inform the user server of
            * possibly read/written pages.  Map pages from read faults
            * strictly read-only, since otherwise we might miss info on
            * when the page is actually write-faulted to.
            */
           if (!locked)
                   mutex_enter(&vp->v_uobj.vmobjlock);
           for (i = 0, si = 0, streakon = 0; i < npages; i++) {
                   if (pgs[i] == NULL || pgs[i] == PGO_DONTCARE) {
                           if (streakon && write) {
                                   streakon = 0;
                                   pcrun[si].pcache_runend
                                       = trunc_page(pgs[i]->offset) + PAGE_MASK;
                                   si++;
                           }
                           continue;
                   }
                   if (streakon == 0 && write) {
                           streakon = 1;
                           pcrun[si].pcache_runstart = pgs[i]->offset;
                   }
   
                   if (!write)
                           pgs[i]->flags |= PG_RDONLY;
           }
           /* was the last page part of our streak? */
           if (streakon) {
                   pcrun[si].pcache_runend
                       = trunc_page(pgs[i-1]->offset) + PAGE_MASK;
                   si++;
           }
           if (!locked)
                   mutex_exit(&vp->v_uobj.vmobjlock);
   
           KASSERT(si <= (npages / 2) + 1);
   
           /* send results to userspace */
           if (write)
                   puffs_cacheop(pmp, parkmem, pcinfo,
                       sizeof(struct puffs_cacheinfo) + runsizes, VPTOPNC(vp));
   
    out:
           if (error) {
                   if (pcinfo != NULL)
                           free(pcinfo, M_PUFFS);
                   if (parkmem != NULL)
                           puffs_park_release(parkmem, 1);
           }
   
           return error;
   }
   
 int  int
 puffs_lock(void *v)  puffs_lock(void *v)

Legend:
Removed from v.1.52.4.2  
changed lines
  Added in v.1.52.4.3

CVSweb <webmaster@jp.NetBSD.org>