Print this page
        
*** 23,33 ****
   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
   * Use is subject to license terms.
   */
  
  /*
!  * Copyright 2016 Joyent, Inc.
   * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
   * Copyright 2016 RackTop Systems.
   */
  
  #include <sys/types.h>
--- 23,33 ----
   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
   * Use is subject to license terms.
   */
  
  /*
!  * Copyright 2016, Joyent, Inc.
   * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
   * Copyright 2016 RackTop Systems.
   */
  
  #include <sys/types.h>
*** 583,596 ****
  {
          struct tmpnode *tp = (struct tmpnode *)VTOTN(vp);
          struct tmount *tm = (struct tmount *)VTOTM(vp);
          int error;
  
-         /* If the filesystem was umounted by force, return immediately. */
-         if (vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
-                 return (EIO);
- 
          /*
           * We don't currently support reading non-regular files
           */
          if (vp->v_type == VDIR)
                  return (EISDIR);
--- 583,592 ----
*** 616,629 ****
  {
          struct tmpnode *tp = (struct tmpnode *)VTOTN(vp);
          struct tmount *tm = (struct tmount *)VTOTM(vp);
          int error;
  
-         /* If the filesystem was umounted by force, return immediately. */
-         if (vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
-                 return (EIO);
- 
          /*
           * We don't currently support writing to non-regular files
           */
          if (vp->v_type != VREG)
                  return (EINVAL);        /* XXX EISDIR? */
--- 612,621 ----
*** 845,857 ****
  {
          struct tmpnode *tp = (struct tmpnode *)VTOTN(dvp);
          struct tmpnode *ntp = NULL;
          int error;
  
-         /* If the filesystem was umounted by force, return immediately. */
-         if (dvp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
-                 return (EIO);
  
          /* allow cd into @ dir */
          if (flags & LOOKUP_XATTR) {
                  struct tmpnode *xdp;
                  struct tmount *tm;
--- 837,846 ----
*** 866,877 ****
                          /* No attributes on attributes */
                          return (EINVAL);
  
                  rw_enter(&tp->tn_rwlock, RW_WRITER);
                  if (tp->tn_xattrdp == NULL) {
-                         int err;
- 
                          if (!(flags & CREATE_XATTR_DIR)) {
                                  rw_exit(&tp->tn_rwlock);
                                  return (ENOENT);
                          }
  
--- 855,864 ----
*** 888,904 ****
                          if ((error = tmp_taccess(tp, VWRITE, cred)) != 0) {
                                  rw_exit(&tp->tn_rwlock);
                                  return (error);
                          }
  
                          tm = VTOTM(dvp);
-                         xdp = tmp_kmem_zalloc(tm, sizeof (struct tmpnode),
-                             KM_SLEEP);
-                         if (xdp == NULL) {
-                                 rw_exit(&tp->tn_rwlock);
-                                 return (ENOSPC);
-                         }
                          tmpnode_init(tm, xdp, &tp->tn_attr, NULL);
                          /*
                           * Fix-up fields unique to attribute directories.
                           */
                          xdp->tn_flags = ISXATTR;
--- 875,887 ----
                          if ((error = tmp_taccess(tp, VWRITE, cred)) != 0) {
                                  rw_exit(&tp->tn_rwlock);
                                  return (error);
                          }
  
+                         xdp = tmp_memalloc(sizeof (struct tmpnode),
+                             TMP_MUSTHAVE);
                          tm = VTOTM(dvp);
                          tmpnode_init(tm, xdp, &tp->tn_attr, NULL);
                          /*
                           * Fix-up fields unique to attribute directories.
                           */
                          xdp->tn_flags = ISXATTR;
*** 912,931 ****
                                  if (tp->tn_attr.va_mode & 0004)
                                          xdp->tn_mode |= 0705;
                          }
                          xdp->tn_vnode->v_type = VDIR;
                          xdp->tn_vnode->v_flag |= V_XATTRDIR;
!                         if ((err = tdirinit(tp, xdp)) != 0) {
!                                 rw_exit(&tp->tn_rwlock);
!                                 /*
!                                  * This never got properly initialized so we can
!                                  * just clean it up.
!                                  */
!                                 xdp->tn_vnode->v_flag &= V_XATTRDIR;
!                                 tmpnode_cleanup(tp);
!                                 return (err);
!                         }
                          tp->tn_xattrdp = xdp;
                  } else {
                          VN_HOLD(tp->tn_xattrdp->tn_vnode);
                  }
                  *vpp = TNTOV(tp->tn_xattrdp);
--- 895,905 ----
                                  if (tp->tn_attr.va_mode & 0004)
                                          xdp->tn_mode |= 0705;
                          }
                          xdp->tn_vnode->v_type = VDIR;
                          xdp->tn_vnode->v_flag |= V_XATTRDIR;
!                         tdirinit(tp, xdp);
                          tp->tn_xattrdp = xdp;
                  } else {
                          VN_HOLD(tp->tn_xattrdp->tn_vnode);
                  }
                  *vpp = TNTOV(tp->tn_xattrdp);
*** 1503,1516 ****
          long outcount = 0;
          long bufsize;
          int reclen;
          caddr_t outbuf;
  
-         /* If the filesystem was umounted by force, return immediately. */
-         if (vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
-                 return (EIO);
- 
          if (uiop->uio_loffset >= MAXOFF_T) {
                  if (eofp)
                          *eofp = 1;
                  return (0);
          }
--- 1477,1486 ----
*** 1640,1655 ****
          error = tdirenter(tm, parent, lnm, DE_CREATE, (struct tmpnode *)NULL,
              (struct tmpnode *)NULL, tva, &self, cred, ct);
          rw_exit(&parent->tn_rwlock);
  
          if (error) {
!                 if (self != NULL)
                          tmpnode_rele(self);
                  return (error);
          }
          len = strlen(tnm) + 1;
!         cp = tmp_kmem_zalloc(tm, len, KM_NOSLEEP | KM_NORMALPRI);
          if (cp == NULL) {
                  tmpnode_rele(self);
                  return (ENOSPC);
          }
          (void) strcpy(cp, tnm);
--- 1610,1625 ----
          error = tdirenter(tm, parent, lnm, DE_CREATE, (struct tmpnode *)NULL,
              (struct tmpnode *)NULL, tva, &self, cred, ct);
          rw_exit(&parent->tn_rwlock);
  
          if (error) {
!                 if (self)
                          tmpnode_rele(self);
                  return (error);
          }
          len = strlen(tnm) + 1;
!         cp = tmp_memalloc(len, 0);
          if (cp == NULL) {
                  tmpnode_rele(self);
                  return (ENOSPC);
          }
          (void) strcpy(cp, tnm);
*** 1710,1740 ****
          /*
           * If we don't have the last hold or the link count is non-zero,
           * there's little to do -- just drop our hold.
           */
          if (vp->v_count > 1 || tp->tn_nlink != 0) {
-                 if (vp->v_vfsp->vfs_flag & VFS_UNMOUNTED) {
-                         /*
-                          * Since the file system was forcibly unmounted, we can
-                          * have a case (v_count == 1, tn_nlink != 0) where this
-                          * file was open so we didn't add an extra hold on the
-                          * file in tmp_unmount. We are counting on the
-                          * interaction of the hold made in tmp_unmount and
-                          * rele-ed in tmp_vfsfree so we need to be sure we
-                          * don't decrement in this case.
-                          */
-                         if (vp->v_count > 1)
                                  vp->v_count--;
-                 } else {
-                         vp->v_count--;
-                 }
                  mutex_exit(&vp->v_lock);
                  mutex_exit(&tp->tn_tlock);
                  rw_exit(&tp->tn_rwlock);
-                 /* If the filesystem was umounted by force, rele the vfs ref */
-                 if (tm->tm_vfsp->vfs_flag & VFS_UNMOUNTED)
-                         VFS_RELE(tm->tm_vfsp);
                  return;
          }
  
          /*
           * We have the last hold *and* the link count is zero, so this
--- 1680,1693 ----
*** 1755,1765 ****
                          ASSERT(tp->tn_size == 0);
                          ASSERT(tp->tn_nblocks == 0);
                          goto top;
                  }
                  if (tp->tn_type == VLNK)
!                         tmp_kmem_free(tm, tp->tn_symlink, tp->tn_size + 1);
          }
  
          /*
           * Remove normal file/dir's xattr dir and xattrs.
           */
--- 1708,1718 ----
                          ASSERT(tp->tn_size == 0);
                          ASSERT(tp->tn_nblocks == 0);
                          goto top;
                  }
                  if (tp->tn_type == VLNK)
!                         tmp_memfree(tp->tn_symlink, tp->tn_size + 1);
          }
  
          /*
           * Remove normal file/dir's xattr dir and xattrs.
           */
*** 1789,1803 ****
          mutex_exit(&tm->tm_contents);
          rw_exit(&tp->tn_rwlock);
          rw_destroy(&tp->tn_rwlock);
          mutex_destroy(&tp->tn_tlock);
          vn_free(TNTOV(tp));
!         tmp_kmem_free(tm, tp, sizeof (struct tmpnode));
! 
!         /* If the filesystem was umounted by force, rele the vfs ref */
!         if (tm->tm_vfsp->vfs_flag & VFS_UNMOUNTED)
!                 VFS_RELE(tm->tm_vfsp);
  }
  
  /* ARGSUSED2 */
  static int
  tmp_fid(struct vnode *vp, struct fid *fidp, caller_context_t *ct)
--- 1742,1752 ----
          mutex_exit(&tm->tm_contents);
          rw_exit(&tp->tn_rwlock);
          rw_destroy(&tp->tn_rwlock);
          mutex_destroy(&tp->tn_tlock);
          vn_free(TNTOV(tp));
!         tmp_memfree(tp, sizeof (struct tmpnode));
  }
  
  /* ARGSUSED2 */
  static int
  tmp_fid(struct vnode *vp, struct fid *fidp, caller_context_t *ct)
*** 1915,1928 ****
          int flags;
          int err = 0;
          struct vnode *pvp;
          u_offset_t poff;
  
-         /* If the filesystem was umounted by force, return immediately. */
-         if (vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
-                 return (EIO);
- 
          if (protp != NULL)
                  *protp = PROT_ALL;
  again:
          if (pp = page_lookup(vp, off, rw == S_CREATE ? SE_EXCL : SE_SHARED)) {
                  if (pl) {
--- 1864,1873 ----
*** 2140,2153 ****
          struct vnode *pvp;
          u_offset_t pstart;
          u_offset_t offset;
          u_offset_t tmpoff;
  
-         /* If the filesystem was umounted by force, return immediately. */
-         if (vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
-                 return (EIO);
- 
          ASSERT(PAGE_LOCKED(pp));
  
          /* Kluster in tmp_klustsize chunks */
          tp = VTOTN(vp);
          tmp_klustsize = klustsize;
--- 2085,2094 ----