[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.182 and 1.182.2.9

version 1.182, 2014/07/25 08:20:52 version 1.182.2.9, 2014/11/05 18:16:17
Line 73  int puffs_vnop_symlink(void *);
Line 73  int puffs_vnop_symlink(void *);
 int     puffs_vnop_rename(void *);  int     puffs_vnop_rename(void *);
 int     puffs_vnop_read(void *);  int     puffs_vnop_read(void *);
 int     puffs_vnop_write(void *);  int     puffs_vnop_write(void *);
   int     puffs_vnop_fallocate(void *);
   int     puffs_vnop_fdiscard(void *);
 int     puffs_vnop_fcntl(void *);  int     puffs_vnop_fcntl(void *);
 int     puffs_vnop_ioctl(void *);  int     puffs_vnop_ioctl(void *);
 int     puffs_vnop_inactive(void *);  int     puffs_vnop_inactive(void *);
Line 113  const struct vnodeopv_entry_desc puffs_v
Line 115  const struct vnodeopv_entry_desc puffs_v
         { &vop_setattr_desc, puffs_vnop_checkop },      /* setattr */          { &vop_setattr_desc, puffs_vnop_checkop },      /* setattr */
         { &vop_read_desc, puffs_vnop_checkop },         /* read */          { &vop_read_desc, puffs_vnop_checkop },         /* read */
         { &vop_write_desc, puffs_vnop_checkop },        /* write */          { &vop_write_desc, puffs_vnop_checkop },        /* write */
         { &vop_fallocate_desc, genfs_eopnotsupp },      /* fallocate */          { &vop_fallocate_desc, puffs_vnop_fallocate },  /* fallocate */
         { &vop_fdiscard_desc, genfs_eopnotsupp },       /* fdiscard */          { &vop_fdiscard_desc, puffs_vnop_fdiscard },    /* fdiscard */
         { &vop_fsync_desc, puffs_vnop_fsync },          /* REAL fsync */          { &vop_fsync_desc, puffs_vnop_fsync },          /* REAL fsync */
         { &vop_seek_desc, puffs_vnop_checkop },         /* seek */          { &vop_seek_desc, puffs_vnop_checkop },         /* seek */
         { &vop_remove_desc, puffs_vnop_checkop },       /* remove */          { &vop_remove_desc, puffs_vnop_checkop },       /* remove */
Line 668  puffs_vnop_lookup(void *v)
Line 670  puffs_vnop_lookup(void *v)
          * match the userland cookie anymore: is the node known?           * match the userland cookie anymore: is the node known?
          */           */
         if (vp == NULL) {          if (vp == NULL) {
                 error = puffs_cookie2vnode(pmp, lookup_msg->pvnr_newnode,  
                                            1, 1, &vp);  
         }  
   
         if (error == PUFFS_NOSUCHCOOKIE) {  
                 error = puffs_getvnode(dvp->v_mount,                  error = puffs_getvnode(dvp->v_mount,
                     lookup_msg->pvnr_newnode, lookup_msg->pvnr_vtype,                      lookup_msg->pvnr_newnode, lookup_msg->pvnr_vtype,
                     lookup_msg->pvnr_size, lookup_msg->pvnr_rdev, &vp);                      lookup_msg->pvnr_size, lookup_msg->pvnr_rdev, &vp);
Line 684  puffs_vnop_lookup(void *v)
Line 681  puffs_vnop_lookup(void *v)
                 }                  }
   
                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);                  vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
         } else if (error) {  
                 puffs_abortbutton(pmp, PUFFS_ABORT_LOOKUP, VPTOPNC(dvp),  
                     lookup_msg->pvnr_newnode, ap->a_cnp);  
                 goto out;  
         }          }
   
         /*          /*
Line 893  puffs_vnop_open(void *v)
Line 886  puffs_vnop_open(void *v)
         PUFFS_MSG_VARS(vn, open);          PUFFS_MSG_VARS(vn, open);
         struct vnode *vp = ap->a_vp;          struct vnode *vp = ap->a_vp;
         struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);          struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
           struct puffs_node *pn = VPTOPP(vp);
         int mode = ap->a_mode;          int mode = ap->a_mode;
         int error;          int error;
   
Line 913  puffs_vnop_open(void *v)
Line 907  puffs_vnop_open(void *v)
         PUFFS_MSG_ENQUEUEWAIT2(pmp, park_open, vp->v_data, NULL, error);          PUFFS_MSG_ENQUEUEWAIT2(pmp, park_open, vp->v_data, NULL, error);
         error = checkerr(pmp, error, __func__);          error = checkerr(pmp, error, __func__);
   
           if (open_msg->pvnr_oflags & PUFFS_OPEN_IO_DIRECT) {
                   if (mode & FREAD)
                           pn->pn_stat |= PNODE_RDIRECT;
                   if (mode & FWRITE)
                           pn->pn_stat |= PNODE_WDIRECT;
           }
  out:   out:
         DPRINTF(("puffs_open: returning %d\n", error));          DPRINTF(("puffs_open: returning %d\n", error));
         PUFFS_MSG_RELEASE(open);          PUFFS_MSG_RELEASE(open);
Line 1132  puffs_vnop_getattr(void *v)
Line 1132  puffs_vnop_getattr(void *v)
         return error;          return error;
 }  }
   
   static void
   zerofill_lastpage(struct vnode *vp, voff_t off)
   {
           char zbuf[PAGE_SIZE];
           struct iovec iov;
           struct uio uio;
           vsize_t len;
           int error;
   
           if (trunc_page(off) == off)
                   return;
   
           if (vp->v_writecount == 0)
                   return;
   
           len = round_page(off) - off;
           memset(zbuf, 0, len);
   
           iov.iov_base = zbuf;
           iov.iov_len = len;
           UIO_SETUP_SYSSPACE(&uio);
           uio.uio_iov = &iov;
           uio.uio_iovcnt = 1;
           uio.uio_offset = off;
           uio.uio_resid = len;
           uio.uio_rw = UIO_WRITE;
   
           error = ubc_uiomove(&vp->v_uobj, &uio, len,
                               UVM_ADV_SEQUENTIAL, UBC_WRITE|UBC_UNMAP_FLAG(vp));
           if (error) {
                   DPRINTF(("zero-fill 0x%" PRIxVSIZE "@0x%" PRIx64
                            " failed: error = %d\n", len, off, error));
           }
   
           return;
   }
   
 static int  static int
 dosetattr(struct vnode *vp, struct vattr *vap, kauth_cred_t cred, int flags)  dosetattr(struct vnode *vp, struct vattr *vap, kauth_cred_t cred, int flags)
 {  {
         PUFFS_MSG_VARS(vn, setattr);          PUFFS_MSG_VARS(vn, setattr);
         struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);          struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
         struct puffs_node *pn = vp->v_data;          struct puffs_node *pn = vp->v_data;
           vsize_t oldsize = vp->v_size;
         int error = 0;          int error = 0;
   
         KASSERT(!(flags & SETATTR_CHSIZE) || mutex_owned(&pn->pn_sizemtx));          KASSERT(!(flags & SETATTR_CHSIZE) || mutex_owned(&pn->pn_sizemtx));
Line 1210  dosetattr(struct vnode *vp, struct vattr
Line 1248  dosetattr(struct vnode *vp, struct vattr
         }          }
   
         if (vap->va_size != VNOVAL) {          if (vap->va_size != VNOVAL) {
                   /*
                    * If we truncated the file, make sure the data beyond
                    * EOF in last page does not remain in cache, otherwise
                    * if the file is later truncated to a larger size (creating
                    * a hole), that area will not return zeroes as it
                    * should.
                    */
                   if ((flags & SETATTR_CHSIZE) && PUFFS_USE_PAGECACHE(pmp) &&
                       (vap->va_size < oldsize))
                           zerofill_lastpage(vp, vap->va_size);
   
                 pn->pn_serversize = vap->va_size;                  pn->pn_serversize = vap->va_size;
                 if (flags & SETATTR_CHSIZE)                  if (flags & SETATTR_CHSIZE)
                         uvm_vnp_setsize(vp, vap->va_size);                          uvm_vnp_setsize(vp, vap->va_size);
Line 1394  puffs_vnop_reclaim(void *v)
Line 1443  puffs_vnop_reclaim(void *v)
         } */ *ap = v;          } */ *ap = v;
         struct vnode *vp = ap->a_vp;          struct vnode *vp = ap->a_vp;
         struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);          struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
         struct puffs_node *pnode = vp->v_data;  
         bool notifyserver = true;          bool notifyserver = true;
   
         /*          /*
Line 1417  puffs_vnop_reclaim(void *v)
Line 1465  puffs_vnop_reclaim(void *v)
          * that and someone might race us into node creation           * that and someone might race us into node creation
          */           */
         mutex_enter(&pmp->pmp_lock);          mutex_enter(&pmp->pmp_lock);
         LIST_REMOVE(pnode, pn_hashent);  
         if (PUFFS_USE_NAMECACHE(pmp))          if (PUFFS_USE_NAMECACHE(pmp))
                 cache_purge(vp);                  cache_purge(vp);
         mutex_exit(&pmp->pmp_lock);          mutex_exit(&pmp->pmp_lock);
Line 1432  puffs_vnop_reclaim(void *v)
Line 1479  puffs_vnop_reclaim(void *v)
                 if (__predict_true(VPTOPP(vp)->pn_parent != NULL))                  if (__predict_true(VPTOPP(vp)->pn_parent != NULL))
                         vrele(VPTOPP(vp)->pn_parent);                          vrele(VPTOPP(vp)->pn_parent);
                 else                  else
                         KASSERT(vp->v_vflag & VV_ROOT);                          KASSERT(vp->v_type == VNON || (vp->v_vflag & VV_ROOT));
         }          }
   
         puffs_putvnode(vp);          puffs_putvnode(vp);
         vp->v_data = NULL;  
   
         return 0;          return 0;
 }  }
Line 1810  puffs_vnop_remove(void *v)
Line 1856  puffs_vnop_remove(void *v)
   
         PUFFS_MSG_RELEASE(remove);          PUFFS_MSG_RELEASE(remove);
   
           puffs_updatenode(VPTOPP(dvp), PUFFS_UPDATECTIME|PUFFS_UPDATEMTIME, 0);
   
         RELEPN_AND_VP(dvp, dpn);          RELEPN_AND_VP(dvp, dpn);
         RELEPN_AND_VP(vp, pn);          RELEPN_AND_VP(vp, pn);
   
Line 1927  puffs_vnop_rmdir(void *v)
Line 1975  puffs_vnop_rmdir(void *v)
   
         PUFFS_MSG_RELEASE(rmdir);          PUFFS_MSG_RELEASE(rmdir);
   
           puffs_updatenode(VPTOPP(dvp), PUFFS_UPDATECTIME|PUFFS_UPDATEMTIME, 0);
   
         /* XXX: some call cache_purge() *for both vnodes* here, investigate */          /* XXX: some call cache_purge() *for both vnodes* here, investigate */
         RELEPN_AND_VP(dvp, dpn);          RELEPN_AND_VP(dvp, dpn);
         RELEPN_AND_VP(vp, pn);          RELEPN_AND_VP(vp, pn);
Line 1972  puffs_vnop_link(void *v)
Line 2022  puffs_vnop_link(void *v)
          * XXX: stay in touch with the cache.  I don't like this, but           * XXX: stay in touch with the cache.  I don't like this, but
          * don't have a better solution either.  See also puffs_rename().           * don't have a better solution either.  See also puffs_rename().
          */           */
         if (error == 0)          if (error == 0) {
                 puffs_updatenode(pn, PUFFS_UPDATECTIME, 0);                  puffs_updatenode(pn, PUFFS_UPDATECTIME, 0);
                   puffs_updatenode(VPTOPP(dvp),
                                    PUFFS_UPDATECTIME|PUFFS_UPDATEMTIME, 0);
           }
   
         RELEPN_AND_VP(dvp, dpn);          RELEPN_AND_VP(dvp, dpn);
         puffs_releasenode(pn);          puffs_releasenode(pn);
Line 2138  puffs_vnop_rename(void *v)
Line 2191  puffs_vnop_rename(void *v)
          */           */
         if (error == 0) {          if (error == 0) {
                 puffs_updatenode(fpn, PUFFS_UPDATECTIME, 0);                  puffs_updatenode(fpn, PUFFS_UPDATECTIME, 0);
                   puffs_updatenode(VPTOPP(fdvp),
                                    PUFFS_UPDATECTIME|PUFFS_UPDATEMTIME, 0);
                   if (fdvp != tdvp)
                           puffs_updatenode(VPTOPP(tdvp),
                                            PUFFS_UPDATECTIME|PUFFS_UPDATEMTIME,
                                            0);
   
                 if (PUFFS_USE_DOTDOTCACHE(pmp) &&                  if (PUFFS_USE_DOTDOTCACHE(pmp) &&
                     (VPTOPP(fvp)->pn_parent != tdvp))                      (VPTOPP(fvp)->pn_parent != tdvp))
Line 2181  puffs_vnop_read(void *v)
Line 2240  puffs_vnop_read(void *v)
         } */ *ap = v;          } */ *ap = v;
         PUFFS_MSG_VARS(vn, read);          PUFFS_MSG_VARS(vn, read);
         struct vnode *vp = ap->a_vp;          struct vnode *vp = ap->a_vp;
           struct puffs_node *pn = VPTOPP(vp);
         struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);          struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
         struct uio *uio = ap->a_uio;          struct uio *uio = ap->a_uio;
         size_t tomove, argsize;          size_t tomove, argsize;
Line 2194  puffs_vnop_read(void *v)
Line 2254  puffs_vnop_read(void *v)
         if (uio->uio_resid == 0)          if (uio->uio_resid == 0)
                 return 0;                  return 0;
         if (uio->uio_offset < 0)          if (uio->uio_offset < 0)
                 return EINVAL;                  return EFBIG;
   
         if (vp->v_type == VREG && PUFFS_USE_PAGECACHE(pmp)) {          if (vp->v_type == VREG &&
               PUFFS_USE_PAGECACHE(pmp) &&
               !(pn->pn_stat & PNODE_RDIRECT)) {
                 const int advice = IO_ADV_DECODE(ap->a_ioflag);                  const int advice = IO_ADV_DECODE(ap->a_ioflag);
   
                 while (uio->uio_resid > 0) {                  while (uio->uio_resid > 0) {
Line 2299  puffs_vnop_write(void *v)
Line 2361  puffs_vnop_write(void *v)
         error = uflags = 0;          error = uflags = 0;
         write_msg = NULL;          write_msg = NULL;
   
           /* std sanity */
           if (uio->uio_resid == 0)
                   return 0;
           if (uio->uio_offset < 0)
                   return EFBIG;
   
         mutex_enter(&pn->pn_sizemtx);          mutex_enter(&pn->pn_sizemtx);
   
         if (vp->v_type == VREG && PUFFS_USE_PAGECACHE(pmp)) {          if (vp->v_type == VREG &&
               PUFFS_USE_PAGECACHE(pmp) &&
               !(pn->pn_stat & PNODE_WDIRECT)) {
                 ubcflags = UBC_WRITE | UBC_PARTIALOK | UBC_UNMAP_FLAG(vp);                  ubcflags = UBC_WRITE | UBC_PARTIALOK | UBC_UNMAP_FLAG(vp);
   
                 /*                  /*
Line 2313  puffs_vnop_write(void *v)
Line 2383  puffs_vnop_write(void *v)
   
                 origoff = uio->uio_offset;                  origoff = uio->uio_offset;
                 while (uio->uio_resid > 0) {                  while (uio->uio_resid > 0) {
                         if (vp->v_mount->mnt_flag & MNT_RELATIME)  
                                 uflags |= PUFFS_UPDATEATIME;  
                         uflags |= PUFFS_UPDATECTIME;  
                         uflags |= PUFFS_UPDATEMTIME;  
                         oldoff = uio->uio_offset;                          oldoff = uio->uio_offset;
                         bytelen = uio->uio_resid;                          bytelen = uio->uio_resid;
   
Line 2377  puffs_vnop_write(void *v)
Line 2443  puffs_vnop_write(void *v)
                         error = VOP_PUTPAGES(vp, trunc_page(origoff),                          error = VOP_PUTPAGES(vp, trunc_page(origoff),
                             round_page(uio->uio_offset), PGO_CLEANIT);                              round_page(uio->uio_offset), PGO_CLEANIT);
                 }                  }
   
                 puffs_updatenode(VPTOPP(vp), uflags, vp->v_size);  
         } else {          } else {
                 /* tomove is non-increasing */                  /* tomove is non-increasing */
                 tomove = PUFFS_TOMOVE(uio->uio_resid, pmp);                  tomove = PUFFS_TOMOVE(uio->uio_resid, pmp);
Line 2412  puffs_vnop_write(void *v)
Line 2476  puffs_vnop_write(void *v)
                         }                          }
   
                         /* adjust file size */                          /* adjust file size */
                         if (vp->v_size < uio->uio_offset)                          if (vp->v_size < uio->uio_offset) {
                                   uflags |= PUFFS_UPDATESIZE;
                                 uvm_vnp_setsize(vp, uio->uio_offset);                                  uvm_vnp_setsize(vp, uio->uio_offset);
                           }
   
                         /* didn't move everything?  bad userspace.  bail */                          /* didn't move everything?  bad userspace.  bail */
                         if (write_msg->pvnr_resid != 0) {                          if (write_msg->pvnr_resid != 0) {
Line 2424  puffs_vnop_write(void *v)
Line 2490  puffs_vnop_write(void *v)
                 puffs_msgmem_release(park_write);                  puffs_msgmem_release(park_write);
         }          }
   
           if (vp->v_mount->mnt_flag & MNT_RELATIME)
                   uflags |= PUFFS_UPDATEATIME;
           uflags |= PUFFS_UPDATECTIME;
           uflags |= PUFFS_UPDATEMTIME;
           puffs_updatenode(VPTOPP(vp), uflags, vp->v_size);
   
         mutex_exit(&pn->pn_sizemtx);          mutex_exit(&pn->pn_sizemtx);
         return error;          return error;
 }  }
   
 int  int
   puffs_vnop_fallocate(void *v)
   {
           struct vop_fallocate_args /* {
                   const struct vnodeop_desc *a_desc;
                   struct vnode *a_vp;
                   off_t a_pos;
                   off_t a_len;
           } */ *ap = v;
           struct vnode *vp = ap->a_vp;
           struct puffs_node *pn = VPTOPP(vp);
           struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
           PUFFS_MSG_VARS(vn, fallocate);
           int error;
   
           mutex_enter(&pn->pn_sizemtx);
   
           PUFFS_MSG_ALLOC(vn, fallocate);
           fallocate_msg->pvnr_off = ap->a_pos;
           fallocate_msg->pvnr_len = ap->a_len;
           puffs_msg_setinfo(park_fallocate, PUFFSOP_VN,
               PUFFS_VN_FALLOCATE, VPTOPNC(vp));
   
           PUFFS_MSG_ENQUEUEWAIT2(pmp, park_fallocate, vp->v_data, NULL, error);
           error = checkerr(pmp, error, __func__);
           PUFFS_MSG_RELEASE(fallocate);
   
           switch (error) {
           case 0:
                   break;
           case EAGAIN:
                   error = EIO;
                   /* FALLTHROUGH */
           default:
                   goto out;
           }
   
           if (ap->a_pos + ap->a_len > vp->v_size) {
                   uvm_vnp_setsize(vp, ap->a_pos + ap->a_len);
                   puffs_updatenode(pn, PUFFS_UPDATESIZE, vp->v_size);
           }
   out:
           mutex_exit(&pn->pn_sizemtx);
   
           return error;
   }
   
   int
   puffs_vnop_fdiscard(void *v)
   {
           struct vop_fdiscard_args /* {
                   const struct vnodeop_desc *a_desc;
                   struct vnode *a_vp;
                   off_t a_pos;
                   off_t a_len;
           } */ *ap = v;
           struct vnode *vp = ap->a_vp;
           struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
           PUFFS_MSG_VARS(vn, fdiscard);
           int error;
   
           PUFFS_MSG_ALLOC(vn, fdiscard);
           fdiscard_msg->pvnr_off = ap->a_pos;
           fdiscard_msg->pvnr_len = ap->a_len;
           puffs_msg_setinfo(park_fdiscard, PUFFSOP_VN,
               PUFFS_VN_FALLOCATE, VPTOPNC(vp));
   
           PUFFS_MSG_ENQUEUEWAIT2(pmp, park_fdiscard, vp->v_data, NULL, error);
           error = checkerr(pmp, error, __func__);
           PUFFS_MSG_RELEASE(fdiscard);
   
           return error;
   }
   
   int
 puffs_vnop_print(void *v)  puffs_vnop_print(void *v)
 {  {
         struct vop_print_args /* {          struct vop_print_args /* {
Line 2695  puffs_vnop_strategy(void *v)
Line 2841  puffs_vnop_strategy(void *v)
                 if (dobiodone == 0)                  if (dobiodone == 0)
                         goto out;                          goto out;
   
                 /*  
                  * XXXXXXXX: wrong, but kernel can't survive strategy  
                  * failure currently.  Here, have one more X: X.  
                  */  
                 if (error != ENOMEM)  
                         error = 0;  
   
                 error = checkerr(pmp, error, __func__);                  error = checkerr(pmp, error, __func__);
                 if (error)                  if (error)
                         goto out;                          goto out;

Legend:
Removed from v.1.182  
changed lines
  Added in v.1.182.2.9

CVSweb <webmaster@jp.NetBSD.org>