Remove SYNC_ATTR check
[zfs.git] / module / zfs / zfs_znode.c
index b7f95f4..61eb877 100644 (file)
@@ -88,7 +88,6 @@
  * (such as VFS logic) that will not compile easily in userland.
  */
 #ifdef _KERNEL
-#ifdef HAVE_ZPL
 /*
  * Needed to close a small window in zfs_znode_move() that allows the zfsvfs to
  * be freed before it can be safely accessed.
@@ -98,17 +97,6 @@ krwlock_t zfsvfs_lock;
 static kmem_cache_t *znode_cache = NULL;
 
 /*ARGSUSED*/
-static void
-znode_evict_error(dmu_buf_t *dbuf, void *user_ptr)
-{
-       /*
-        * We should never drop all dbuf refs without first clearing
-        * the eviction callback.
-        */
-       panic("evicting znode %p\n", user_ptr);
-}
-
-/*ARGSUSED*/
 static int
 zfs_znode_cache_constructor(void *buf, void *arg, int kmflags)
 {
@@ -160,189 +148,6 @@ zfs_znode_cache_destructor(void *buf, void *arg)
        ASSERT(zp->z_acl_cached == NULL);
 }
 
-#ifdef ZNODE_STATS
-static struct {
-       uint64_t zms_zfsvfs_invalid;
-       uint64_t zms_zfsvfs_recheck1;
-       uint64_t zms_zfsvfs_unmounted;
-       uint64_t zms_zfsvfs_recheck2;
-       uint64_t zms_obj_held;
-       uint64_t zms_vnode_locked;
-       uint64_t zms_not_only_dnlc;
-} znode_move_stats;
-#endif /* ZNODE_STATS */
-
-static void
-zfs_znode_move_impl(znode_t *ozp, znode_t *nzp)
-{
-       vnode_t *vp;
-
-       /* Copy fields. */
-       nzp->z_zfsvfs = ozp->z_zfsvfs;
-
-       /* Swap vnodes. */
-       vp = nzp->z_vnode;
-       nzp->z_vnode = ozp->z_vnode;
-       ozp->z_vnode = vp; /* let destructor free the overwritten vnode */
-       ZTOV(ozp)->v_data = ozp;
-       ZTOV(nzp)->v_data = nzp;
-
-       nzp->z_id = ozp->z_id;
-       ASSERT(ozp->z_dirlocks == NULL); /* znode not in use */
-       ASSERT(avl_numnodes(&ozp->z_range_avl) == 0);
-       nzp->z_unlinked = ozp->z_unlinked;
-       nzp->z_atime_dirty = ozp->z_atime_dirty;
-       nzp->z_zn_prefetch = ozp->z_zn_prefetch;
-       nzp->z_blksz = ozp->z_blksz;
-       nzp->z_seq = ozp->z_seq;
-       nzp->z_mapcnt = ozp->z_mapcnt;
-       nzp->z_gen = ozp->z_gen;
-       nzp->z_sync_cnt = ozp->z_sync_cnt;
-       nzp->z_is_sa = ozp->z_is_sa;
-       nzp->z_sa_hdl = ozp->z_sa_hdl;
-       bcopy(ozp->z_atime, nzp->z_atime, sizeof (uint64_t) * 2);
-       nzp->z_links = ozp->z_links;
-       nzp->z_size = ozp->z_size;
-       nzp->z_pflags = ozp->z_pflags;
-       nzp->z_uid = ozp->z_uid;
-       nzp->z_gid = ozp->z_gid;
-       nzp->z_mode = ozp->z_mode;
-
-       /*
-        * Since this is just an idle znode and kmem is already dealing with
-        * memory pressure, release any cached ACL.
-        */
-       if (ozp->z_acl_cached) {
-               zfs_acl_free(ozp->z_acl_cached);
-               ozp->z_acl_cached = NULL;
-       }
-
-       sa_set_userp(nzp->z_sa_hdl, nzp);
-
-       /*
-        * Invalidate the original znode by clearing fields that provide a
-        * pointer back to the znode. Set the low bit of the vfs pointer to
-        * ensure that zfs_znode_move() recognizes the znode as invalid in any
-        * subsequent callback.
-        */
-       ozp->z_sa_hdl = NULL;
-       POINTER_INVALIDATE(&ozp->z_zfsvfs);
-
-       /*
-        * Mark the znode.
-        */
-       nzp->z_moved = 1;
-       ozp->z_moved = (uint8_t)-1;
-}
-
-/*ARGSUSED*/
-static kmem_cbrc_t
-zfs_znode_move(void *buf, void *newbuf, size_t size, void *arg)
-{
-       znode_t *ozp = buf, *nzp = newbuf;
-       zfsvfs_t *zfsvfs;
-       vnode_t *vp;
-
-       /*
-        * The znode is on the file system's list of known znodes if the vfs
-        * pointer is valid. We set the low bit of the vfs pointer when freeing
-        * the znode to invalidate it, and the memory patterns written by kmem
-        * (baddcafe and deadbeef) set at least one of the two low bits. A newly
-        * created znode sets the vfs pointer last of all to indicate that the
-        * znode is known and in a valid state to be moved by this function.
-        */
-       zfsvfs = ozp->z_zfsvfs;
-       if (!POINTER_IS_VALID(zfsvfs)) {
-               ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_invalid);
-               return (KMEM_CBRC_DONT_KNOW);
-       }
-
-       /*
-        * Close a small window in which it's possible that the filesystem could
-        * be unmounted and freed, and zfsvfs, though valid in the previous
-        * statement, could point to unrelated memory by the time we try to
-        * prevent the filesystem from being unmounted.
-        */
-       rw_enter(&zfsvfs_lock, RW_WRITER);
-       if (zfsvfs != ozp->z_zfsvfs) {
-               rw_exit(&zfsvfs_lock);
-               ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_recheck1);
-               return (KMEM_CBRC_DONT_KNOW);
-       }
-
-       /*
-        * If the znode is still valid, then so is the file system. We know that
-        * no valid file system can be freed while we hold zfsvfs_lock, so we
-        * can safely ensure that the filesystem is not and will not be
-        * unmounted. The next statement is equivalent to ZFS_ENTER().
-        */
-       rrw_enter(&zfsvfs->z_teardown_lock, RW_READER, FTAG);
-       if (zfsvfs->z_unmounted) {
-               ZFS_EXIT(zfsvfs);
-               rw_exit(&zfsvfs_lock);
-               ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_unmounted);
-               return (KMEM_CBRC_DONT_KNOW);
-       }
-       rw_exit(&zfsvfs_lock);
-
-       mutex_enter(&zfsvfs->z_znodes_lock);
-       /*
-        * Recheck the vfs pointer in case the znode was removed just before
-        * acquiring the lock.
-        */
-       if (zfsvfs != ozp->z_zfsvfs) {
-               mutex_exit(&zfsvfs->z_znodes_lock);
-               ZFS_EXIT(zfsvfs);
-               ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_recheck2);
-               return (KMEM_CBRC_DONT_KNOW);
-       }
-
-       /*
-        * At this point we know that as long as we hold z_znodes_lock, the
-        * znode cannot be freed and fields within the znode can be safely
-        * accessed. Now, prevent a race with zfs_zget().
-        */
-       if (ZFS_OBJ_HOLD_TRYENTER(zfsvfs, ozp->z_id) == 0) {
-               mutex_exit(&zfsvfs->z_znodes_lock);
-               ZFS_EXIT(zfsvfs);
-               ZNODE_STAT_ADD(znode_move_stats.zms_obj_held);
-               return (KMEM_CBRC_LATER);
-       }
-
-       vp = ZTOV(ozp);
-       if (mutex_tryenter(&vp->v_lock) == 0) {
-               ZFS_OBJ_HOLD_EXIT(zfsvfs, ozp->z_id);
-               mutex_exit(&zfsvfs->z_znodes_lock);
-               ZFS_EXIT(zfsvfs);
-               ZNODE_STAT_ADD(znode_move_stats.zms_vnode_locked);
-               return (KMEM_CBRC_LATER);
-       }
-
-       /* Only move znodes that are referenced _only_ by the DNLC. */
-       if (vp->v_count != 1 || !vn_in_dnlc(vp)) {
-               mutex_exit(&vp->v_lock);
-               ZFS_OBJ_HOLD_EXIT(zfsvfs, ozp->z_id);
-               mutex_exit(&zfsvfs->z_znodes_lock);
-               ZFS_EXIT(zfsvfs);
-               ZNODE_STAT_ADD(znode_move_stats.zms_not_only_dnlc);
-               return (KMEM_CBRC_LATER);
-       }
-
-       /*
-        * The znode is known and in a valid state to move. We're holding the
-        * locks needed to execute the critical section.
-        */
-       zfs_znode_move_impl(ozp, nzp);
-       mutex_exit(&vp->v_lock);
-       ZFS_OBJ_HOLD_EXIT(zfsvfs, ozp->z_id);
-
-       list_link_replace(&ozp->z_link_node, &nzp->z_link_node);
-       mutex_exit(&zfsvfs->z_znodes_lock);
-       ZFS_EXIT(zfsvfs);
-
-       return (KMEM_CBRC_YES);
-}
-
 void
 zfs_znode_init(void)
 {
@@ -354,18 +159,12 @@ zfs_znode_init(void)
        znode_cache = kmem_cache_create("zfs_znode_cache",
            sizeof (znode_t), 0, zfs_znode_cache_constructor,
            zfs_znode_cache_destructor, NULL, NULL, NULL, 0);
-       kmem_cache_set_move(znode_cache, zfs_znode_move);
 }
 
 void
 zfs_znode_fini(void)
 {
        /*
-        * Cleanup vfs & vnode ops
-        */
-       zfs_remove_op_tables();
-
-       /*
         * Cleanup zcache
         */
        if (znode_cache)
@@ -374,101 +173,11 @@ zfs_znode_fini(void)
        rw_destroy(&zfsvfs_lock);
 }
 
-struct vnodeops *zfs_dvnodeops;
-struct vnodeops *zfs_fvnodeops;
-struct vnodeops *zfs_symvnodeops;
-struct vnodeops *zfs_xdvnodeops;
-struct vnodeops *zfs_evnodeops;
-struct vnodeops *zfs_sharevnodeops;
-
-void
-zfs_remove_op_tables()
-{
-       /*
-        * Remove vfs ops
-        */
-       ASSERT(zfsfstype);
-       (void) vfs_freevfsops_by_type(zfsfstype);
-       zfsfstype = 0;
-
-       /*
-        * Remove vnode ops
-        */
-       if (zfs_dvnodeops)
-               vn_freevnodeops(zfs_dvnodeops);
-       if (zfs_fvnodeops)
-               vn_freevnodeops(zfs_fvnodeops);
-       if (zfs_symvnodeops)
-               vn_freevnodeops(zfs_symvnodeops);
-       if (zfs_xdvnodeops)
-               vn_freevnodeops(zfs_xdvnodeops);
-       if (zfs_evnodeops)
-               vn_freevnodeops(zfs_evnodeops);
-       if (zfs_sharevnodeops)
-               vn_freevnodeops(zfs_sharevnodeops);
-
-       zfs_dvnodeops = NULL;
-       zfs_fvnodeops = NULL;
-       zfs_symvnodeops = NULL;
-       zfs_xdvnodeops = NULL;
-       zfs_evnodeops = NULL;
-       zfs_sharevnodeops = NULL;
-}
-
-extern const fs_operation_def_t zfs_dvnodeops_template[];
-extern const fs_operation_def_t zfs_fvnodeops_template[];
-extern const fs_operation_def_t zfs_xdvnodeops_template[];
-extern const fs_operation_def_t zfs_symvnodeops_template[];
-extern const fs_operation_def_t zfs_evnodeops_template[];
-extern const fs_operation_def_t zfs_sharevnodeops_template[];
-
-int
-zfs_create_op_tables()
-{
-       int error;
-
-       /*
-        * zfs_dvnodeops can be set if mod_remove() calls mod_installfs()
-        * due to a failure to remove the the 2nd modlinkage (zfs_modldrv).
-        * In this case we just return as the ops vectors are already set up.
-        */
-       if (zfs_dvnodeops)
-               return (0);
-
-       error = vn_make_ops(MNTTYPE_ZFS, zfs_dvnodeops_template,
-           &zfs_dvnodeops);
-       if (error)
-               return (error);
-
-       error = vn_make_ops(MNTTYPE_ZFS, zfs_fvnodeops_template,
-           &zfs_fvnodeops);
-       if (error)
-               return (error);
-
-       error = vn_make_ops(MNTTYPE_ZFS, zfs_symvnodeops_template,
-           &zfs_symvnodeops);
-       if (error)
-               return (error);
-
-       error = vn_make_ops(MNTTYPE_ZFS, zfs_xdvnodeops_template,
-           &zfs_xdvnodeops);
-       if (error)
-               return (error);
-
-       error = vn_make_ops(MNTTYPE_ZFS, zfs_evnodeops_template,
-           &zfs_evnodeops);
-       if (error)
-               return (error);
-
-       error = vn_make_ops(MNTTYPE_ZFS, zfs_sharevnodeops_template,
-           &zfs_sharevnodeops);
-
-       return (error);
-}
-
+#ifdef HAVE_ZPL
 int
 zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
 {
+#ifdef HAVE_SHARE
        zfs_acl_ids_t acl_ids;
        vattr_t vattr;
        znode_t *sharezp;
@@ -510,6 +219,9 @@ zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
        kmem_cache_free(znode_cache, sharezp);
 
        return (error);
+#else
+       return (0);
+#endif /* HAVE_SHARE */
 }
 
 /*
@@ -526,6 +238,8 @@ zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
 #define        MAXMIN64        0xffffffffUL
 #endif
 
+#endif /* HAVE_ZPL */
+
 /*
  * Create special expldev for ZFS private use.
  * Can't use standard expldev since it doesn't do
@@ -612,7 +326,7 @@ zfs_znode_dmu_fini(znode_t *zp)
 }
 
 /*
- * Construct a new znode/vnode and intialize.
+ * Construct a new znode+inode and initialize.
  *
  * This does not do a call to dmu_set_user() that is
  * up to the caller to do, in case you don't want to
@@ -623,14 +337,19 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
     dmu_object_type_t obj_type, sa_handle_t *hdl)
 {
        znode_t *zp;
-       vnode_t *vp;
-       uint64_t mode;
+       struct inode *inode;
        uint64_t parent;
        sa_bulk_attr_t bulk[9];
        int count = 0;
 
-       zp = kmem_cache_alloc(znode_cache, KM_SLEEP);
+       ASSERT(zfsvfs != NULL);
+       ASSERT(zfsvfs->z_vfs != NULL);
+       ASSERT(zfsvfs->z_vfs->mnt_sb != NULL);
+
+       inode = iget_locked(zfsvfs->z_vfs->mnt_sb, db->db_object);
+       zp = ITOZ(inode);
 
+       ASSERT(inode->i_state & I_NEW);
        ASSERT(zp->z_dirlocks == NULL);
        ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs));
        zp->z_moved = 0;
@@ -648,20 +367,20 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
        zp->z_seq = 0x7A4653;
        zp->z_sync_cnt = 0;
 
-       vp = ZTOV(zp);
-       vn_reinit(vp);
-
        zfs_znode_sa_init(zfsvfs, zp, db, obj_type, hdl);
 
-       SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL, &mode, 8);
-       SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GEN(zfsvfs), NULL, &zp->z_gen, 8);
+       SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL,
+           &zp->z_mode, 8);
+       SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GEN(zfsvfs), NULL,
+           &zp->z_gen, 8);
        SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zfsvfs), NULL,
            &zp->z_size, 8);
        SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zfsvfs), NULL,
            &zp->z_links, 8);
        SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL,
            &zp->z_pflags, 8);
-       SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zfsvfs), NULL, &parent, 8);
+       SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zfsvfs), NULL,
+           &parent, 8);
        SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zfsvfs), NULL,
            &zp->z_atime, 16);
        SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zfsvfs), NULL,
@@ -672,57 +391,23 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
        if (sa_bulk_lookup(zp->z_sa_hdl, bulk, count) != 0 || zp->z_gen == 0) {
                if (hdl == NULL)
                        sa_handle_destroy(zp->z_sa_hdl);
-               kmem_cache_free(znode_cache, zp);
+               iput(inode);
                return (NULL);
        }
 
-       zp->z_mode = mode;
-       vp->v_vfsp = zfsvfs->z_parent->z_vfs;
-
-       vp->v_type = IFTOVT((mode_t)mode);
-
-       switch (vp->v_type) {
-       case VDIR:
-               if (zp->z_pflags & ZFS_XATTR) {
-                       vn_setops(vp, zfs_xdvnodeops);
-                       vp->v_flag |= V_XATTRDIR;
-               } else {
-                       vn_setops(vp, zfs_dvnodeops);
-               }
-               zp->z_zn_prefetch = B_TRUE; /* z_prefetch default is enabled */
-               break;
-       case VBLK:
-       case VCHR:
-               {
-                       uint64_t rdev;
-                       VERIFY(sa_lookup(zp->z_sa_hdl, SA_ZPL_RDEV(zfsvfs),
-                           &rdev, sizeof (rdev)) == 0);
-
-                       vp->v_rdev = zfs_cmpldev(rdev);
-               }
-               /*FALLTHROUGH*/
-       case VFIFO:
-       case VSOCK:
-       case VDOOR:
-               vn_setops(vp, zfs_fvnodeops);
-               break;
-       case VREG:
-               vp->v_flag |= VMODSORT;
-               if (parent == zfsvfs->z_shares_dir) {
-                       ASSERT(zp->z_uid == 0 && zp->z_gid == 0);
-                       vn_setops(vp, zfs_sharevnodeops);
-               } else {
-                       vn_setops(vp, zfs_fvnodeops);
-               }
-               break;
-       case VLNK:
-               vn_setops(vp, zfs_symvnodeops);
-               break;
-       default:
-               vn_setops(vp, zfs_evnodeops);
-               break;
+       inode->i_mode = (umode_t)zp->z_mode;
+       if ((S_ISCHR(inode->i_mode)) || (S_ISBLK(inode->i_mode))) {
+               uint64_t rdev;
+               VERIFY(sa_lookup(zp->z_sa_hdl, SA_ZPL_RDEV(zfsvfs),
+                   &rdev, sizeof (rdev)) == 0);
+               inode->i_rdev = zfs_cmpldev(rdev);
        }
 
+       /* zp->z_set_ops_inode() must be set in sb->alloc_inode() */
+       ASSERT(zp->z_set_ops_inode != NULL);
+       zp->z_set_ops_inode(inode);
+       unlock_new_inode(inode);
+
        mutex_enter(&zfsvfs->z_znodes_lock);
        list_insert_tail(&zfsvfs->z_all_znodes, zp);
        membar_producer();
@@ -737,6 +422,47 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
        return (zp);
 }
 
+/*
+ * Update the embedded inode given the znode.  We should work toward
+ * eliminating this function as soon as possible by removing values
+ * which are duplicated between the znode and inode.  If the generic
+ * inode has the correct field it should be used, and the ZFS code
+ * updated to access the inode.  This can be done incrementally.
+ */
+void
+zfs_inode_update(znode_t *zp)
+{
+       zfsvfs_t        *zfsvfs;
+       struct inode    *inode;
+       uint32_t        blksize;
+       uint64_t        atime[2], mtime[2], ctime[2];
+
+       ASSERT(zp != NULL);
+       zfsvfs = zp->z_zfsvfs;
+       inode = ZTOI(zp);
+
+       sa_lookup(zp->z_sa_hdl, SA_ZPL_ATIME(zfsvfs), &atime, 16);
+       sa_lookup(zp->z_sa_hdl, SA_ZPL_MTIME(zfsvfs), &mtime, 16);
+       sa_lookup(zp->z_sa_hdl, SA_ZPL_CTIME(zfsvfs), &ctime, 16);
+
+       spin_lock(&inode->i_lock);
+       inode->i_generation = zp->z_gen;
+       inode->i_uid = zp->z_uid;
+       inode->i_gid = zp->z_gid;
+       inode->i_nlink = zp->z_links;
+       inode->i_mode = zp->z_mode;
+       inode->i_blkbits = SPA_MINBLOCKSHIFT;
+       dmu_object_size_from_db(sa_get_db(zp->z_sa_hdl), &blksize,
+           (u_longlong_t *)&inode->i_blocks);
+
+       ZFS_TIME_DECODE(&inode->i_atime, atime);
+       ZFS_TIME_DECODE(&inode->i_mtime, mtime);
+       ZFS_TIME_DECODE(&inode->i_ctime, ctime);
+
+       i_size_write(inode, zp->z_size);
+       spin_unlock(&inode->i_lock);
+}
+
 static uint64_t empty_xattr;
 static uint64_t pad[4];
 static zfs_acl_phys_t acl_phys;
@@ -1015,6 +741,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr,
 void
 zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx)
 {
+#ifdef HAVE_XVATTR
        xoptattr_t *xoap;
 
        xoap = xva_getxoptattr(xvap);
@@ -1101,6 +828,7 @@ zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx)
                    zp->z_pflags, tx);
                XVA_SET_RTN(xvap, XAT_SPARSE);
        }
+#endif /* HAVE_XVATTR */
 }
 
 int
@@ -1429,6 +1157,7 @@ zfs_grow_blocksize(znode_t *zp, uint64_t size, dmu_tx_t *tx)
        dmu_object_size_from_db(sa_get_db(zp->z_sa_hdl), &zp->z_blksz, &dummy);
 }
 
+#ifdef HAVE_ZPL
 /*
  * This is a dummy interface used when pvn_vplist_dirty() should *not*
  * be calling back into the fs for a putpage().  E.g.: when truncating
@@ -1442,6 +1171,7 @@ zfs_no_putpage(vnode_t *vp, page_t *pp, u_offset_t *offp, size_t *lenp,
        ASSERT(0);
        return (0);
 }
+#endif /* HAVE_ZPL */
 
 /*
  * Increase the file length
@@ -1573,7 +1303,9 @@ static int
 zfs_trunc(znode_t *zp, uint64_t end)
 {
        zfsvfs_t *zfsvfs = zp->z_zfsvfs;
+#ifdef HAVE_ZPL
        vnode_t *vp = ZTOV(zp);
+#endif /* HAVE_ZPL */
        dmu_tx_t *tx;
        rl_t *rl;
        int error;
@@ -1627,6 +1359,7 @@ top:
 
        dmu_tx_commit(tx);
 
+#ifdef HAVE_ZPL
        /*
         * Clear any mapped pages in the truncated region.  This has to
         * happen outside of the transaction to avoid the possibility of
@@ -1650,6 +1383,7 @@ top:
                    B_INVAL | B_TRUNC, NULL);
                ASSERT(error == 0);
        }
+#endif /* HAVE_ZPL */
 
        zfs_range_unlock(rl);
 
@@ -1671,7 +1405,9 @@ top:
 int
 zfs_freesp(znode_t *zp, uint64_t off, uint64_t len, int flag, boolean_t log)
 {
+#ifdef HAVE_ZPL
        vnode_t *vp = ZTOV(zp);
+#endif /* HAVE_ZPL */
        dmu_tx_t *tx;
        zfsvfs_t *zfsvfs = zp->z_zfsvfs;
        zilog_t *zilog = zfsvfs->z_log;
@@ -1693,6 +1429,7 @@ zfs_freesp(znode_t *zp, uint64_t off, uint64_t len, int flag, boolean_t log)
                        return (error);
        }
 
+#ifdef HAVE_ZPL
        /*
         * Check for any locks in the region to be freed.
         */
@@ -1702,6 +1439,7 @@ zfs_freesp(znode_t *zp, uint64_t off, uint64_t len, int flag, boolean_t log)
                if (error = chklock(vp, FWRITE, off, length, flag, NULL))
                        return (error);
        }
+#endif /* HAVE_ZPL */
 
        if (len == 0) {
                error = zfs_trunc(zp, off);
@@ -1738,9 +1476,9 @@ log:
        zfs_log_truncate(zilog, tx, TX_TRUNCATE, zp, off, len);
 
        dmu_tx_commit(tx);
+       zfs_inode_update(zp);
        return (0);
 }
-#endif /* HAVE_ZPL */
 
 void
 zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)