hammer2 - Refactor frontend part 4/many
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 17 Jun 2015 06:10:40 +0000 (23:10 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Thu, 18 Jun 2015 00:15:40 +0000 (17:15 -0700)
* Embed the inode's meta-data (hammer2_inode_meta) in the
  in-memory hammer2_inode structure, making it accessible
  once the inode has been loaded without having to reissue
  I/O.

* In preparation for separating the cluster locking from the
  inode locking.

sys/vfs/hammer2/hammer2.h
sys/vfs/hammer2/hammer2_inode.c
sys/vfs/hammer2/hammer2_subr.c
sys/vfs/hammer2/hammer2_vfsops.c
sys/vfs/hammer2/hammer2_vnops.c

index 0173a78..4928f43 100644 (file)
@@ -675,12 +675,10 @@ struct hammer2_inode {
        struct spinlock         cluster_spin;   /* update cluster */
        hammer2_cluster_t       cluster;
        struct lockf            advlock;
-       hammer2_tid_t           inum;
        u_int                   flags;
        u_int                   refs;           /* +vpref, +flushref */
        uint8_t                 comp_heuristic;
-       hammer2_off_t           size;           /* cache file size */
-       uint64_t                mtime;          /* cache mtime */
+       hammer2_inode_meta_t    meta;           /* copy of meta-data */
 };
 
 typedef struct hammer2_inode hammer2_inode_t;
@@ -692,7 +690,7 @@ typedef struct hammer2_inode hammer2_inode_t;
 #define HAMMER2_INODE_RESIZED          0x0010
 #define HAMMER2_INODE_MTIME            0x0020
 #define HAMMER2_INODE_ISUNLINKED       0x0040
-#define HAMMER2_INODE_DATAGOOD         0x0080  /* inode meta-data */
+#define HAMMER2_INODE_METAGOOD         0x0080  /* inode meta-data good */
 
 int hammer2_inode_cmp(hammer2_inode_t *ip1, hammer2_inode_t *ip2);
 RB_PROTOTYPE2(hammer2_inode_tree, hammer2_inode, rbnode, hammer2_inode_cmp,
@@ -1092,9 +1090,7 @@ int hammer2_getradix(size_t bytes);
 
 int hammer2_calc_logical(hammer2_inode_t *ip, hammer2_off_t uoff,
                        hammer2_key_t *lbasep, hammer2_key_t *leofp);
-int hammer2_calc_physical(hammer2_inode_t *ip,
-                       const hammer2_inode_data_t *ipdata,
-                       hammer2_key_t lbase);
+int hammer2_calc_physical(hammer2_inode_t *ip, hammer2_key_t lbase);
 void hammer2_update_time(uint64_t *timep);
 void hammer2_adjreadcounter(hammer2_blockref_t *bref, size_t bytes);
 
@@ -1124,7 +1120,8 @@ hammer2_inode_t *hammer2_inode_create(hammer2_trans_t *trans,
                        hammer2_cluster_t **clusterp,
                        int flags, int *errorp);
 int hammer2_inode_connect(hammer2_trans_t *trans,
-                       hammer2_cluster_t **clusterp, int hlink,
+                       hammer2_inode_t *ip, hammer2_cluster_t **clusterp,
+                       int hlink,
                        hammer2_inode_t *dip, hammer2_cluster_t *dcluster,
                        const uint8_t *name, size_t name_len,
                        hammer2_key_t key);
index bc85bcb..6f97bc0 100644 (file)
@@ -49,14 +49,14 @@ static void hammer2_inode_move_to_hidden(hammer2_trans_t *trans,
                                         hammer2_tid_t inum);
 
 RB_GENERATE2(hammer2_inode_tree, hammer2_inode, rbnode, hammer2_inode_cmp,
-            hammer2_tid_t, inum);
+            hammer2_tid_t, meta.inum);
 
 int
 hammer2_inode_cmp(hammer2_inode_t *ip1, hammer2_inode_t *ip2)
 {
-       if (ip1->inum < ip2->inum)
+       if (ip1->meta.inum < ip2->meta.inum)
                return(-1);
-       if (ip1->inum > ip2->inum)
+       if (ip1->meta.inum > ip2->meta.inum)
                return(1);
        return(0);
 }
@@ -553,13 +553,13 @@ again:
        nip->cluster.flags |= HAMMER2_CLUSTER_INODE;
        if (cluster) {
                nipdata = &hammer2_cluster_rdata(cluster)->ipdata;
-               nip->inum = nipdata->meta.inum;
-               nip->size = nipdata->meta.size;
-               nip->mtime = nipdata->meta.mtime;
+               nip->meta = nipdata->meta;
+               atomic_set_int(&nip->flags, HAMMER2_INODE_METAGOOD);
                hammer2_inode_repoint(nip, NULL, cluster);
        } else {
-               nip->inum = 1;                  /* PFS inum is always 1 XXX */
+               nip->meta.inum = 1;             /* PFS inum is always 1 XXX */
                /* mtime will be updated when a cluster is available */
+               atomic_set_int(&nip->flags, HAMMER2_INODE_METAGOOD);
        }
 
        nip->pip = dip;                         /* can be NULL */
@@ -790,6 +790,7 @@ retry:
        bcopy(name, nipdata->filename, name_len);
        nipdata->meta.name_key = lhc;
        nipdata->meta.name_len = name_len;
+       nip->meta = nipdata->meta;
        hammer2_cluster_modsync(cluster);
        *clusterp = cluster;
 
@@ -807,7 +808,8 @@ retry:
 static
 void
 hammer2_hardlink_shiftup(hammer2_trans_t *trans, hammer2_cluster_t *cluster,
-                       hammer2_inode_t *dip, hammer2_cluster_t *dcluster,
+                       hammer2_inode_t *ip, hammer2_inode_t *dip,
+                       hammer2_cluster_t *dcluster,
                        int nlinks, int *errorp)
 {
        const hammer2_inode_data_t *iptmp;
@@ -886,6 +888,14 @@ hammer2_hardlink_shiftup(hammer2_trans_t *trans, hammer2_cluster_t *cluster,
        nipdata->meta.name_len = strlen(nipdata->filename);
        nipdata->meta.name_key = lhc;
        nipdata->meta.nlinks += nlinks;
+
+       /*
+        * Resync ip->meta.  Some fields have to be retained.
+        */
+       nipdata->meta.size = ip->meta.size;
+       nipdata->meta.mtime = ip->meta.mtime;
+       ip->meta = nipdata->meta;
+
        hammer2_cluster_modsync(cluster);
 }
 
@@ -902,7 +912,8 @@ hammer2_hardlink_shiftup(hammer2_trans_t *trans, hammer2_cluster_t *cluster,
  */
 int
 hammer2_inode_connect(hammer2_trans_t *trans,
-                     hammer2_cluster_t **clusterp, int hlink,
+                     hammer2_inode_t *ip, hammer2_cluster_t **clusterp,
+                     int hlink,
                      hammer2_inode_t *dip, hammer2_cluster_t *dcluster,
                      const uint8_t *name, size_t name_len,
                      hammer2_key_t lhc)
@@ -1064,6 +1075,15 @@ hammer2_inode_connect(hammer2_trans_t *trans,
                wipdata->meta.name_len = name_len;
                wipdata->meta.nlinks = 1;
                hammer2_cluster_modsync(ncluster);
+
+               /*
+                * Resync the in-memory inode, some fields must be retained.
+                */
+               if (ip) {       /* XXX move_to_hidden passes NULL */
+                       wipdata->meta.size = ip->meta.size;
+                       wipdata->meta.mtime = ip->meta.mtime;
+                       ip->meta = wipdata->meta;
+               }
        }
 
        /*
@@ -1478,6 +1498,7 @@ again:
                        wipdata = &hammer2_cluster_wdata(cluster)->ipdata;
                        ripdata = wipdata;
                        wipdata->meta.nlinks += nlinks;
+                       /* XXX race */
                        /* XXX debugging */
                        if ((int64_t)wipdata->meta.nlinks < 0) {
                                wipdata->meta.nlinks = 0;
@@ -1679,7 +1700,8 @@ hammer2_inode_move_to_hidden(hammer2_trans_t *trans,
 
        hammer2_cluster_delete(trans, *cparentp, *clusterp, 0);
        dcluster = hammer2_inode_lock(pmp->ihidden, HAMMER2_RESOLVE_ALWAYS);
-       error = hammer2_inode_connect(trans, clusterp, 0,
+       error = hammer2_inode_connect(trans,
+                                     NULL/*XXX*/, clusterp, 0,
                                      pmp->ihidden, dcluster,
                                      NULL, 0, inum);
        hammer2_inode_unlock(pmp->ihidden, dcluster);
@@ -1837,7 +1859,7 @@ hammer2_hardlink_consolidate(hammer2_trans_t *trans,
         *          to the older/original version.
         */
        KKASSERT(cluster->focus->flags & HAMMER2_CHAIN_DELETED);
-       hammer2_hardlink_shiftup(trans, cluster, cdip, cdcluster,
+       hammer2_hardlink_shiftup(trans, cluster, ip, cdip, cdcluster,
                                 nlinks, &error);
 
        if (error == 0)
@@ -2038,13 +2060,14 @@ hammer2_inode_fsync(hammer2_trans_t *trans, hammer2_inode_t *ip,
        if (ip->flags & HAMMER2_INODE_MTIME) {
                wipdata = hammer2_cluster_modify_ip(trans, ip, cparent, 0);
                atomic_clear_int(&ip->flags, HAMMER2_INODE_MTIME);
-               wipdata->meta.mtime = ip->mtime;
+               wipdata->meta.mtime = ip->meta.mtime;
                dosync = 1;
                ripdata = wipdata;
        }
-       if ((ip->flags & HAMMER2_INODE_RESIZED) && ip->size < ripdata->meta.size) {
+       if ((ip->flags & HAMMER2_INODE_RESIZED) &&
+           ip->meta.size < ripdata->meta.size) {
                wipdata = hammer2_cluster_modify_ip(trans, ip, cparent, 0);
-               wipdata->meta.size = ip->size;
+               wipdata->meta.size = ip->meta.size;
                dosync = 1;
                ripdata = wipdata;
                atomic_clear_int(&ip->flags, HAMMER2_INODE_RESIZED);
@@ -2084,9 +2107,9 @@ hammer2_inode_fsync(hammer2_trans_t *trans, hammer2_inode_t *ip,
                hammer2_cluster_lookup_done(dparent);
        } else
        if ((ip->flags & HAMMER2_INODE_RESIZED) &&
-           ip->size > ripdata->meta.size) {
+           ip->meta.size > ripdata->meta.size) {
                wipdata = hammer2_cluster_modify_ip(trans, ip, cparent, 0);
-               wipdata->meta.size = ip->size;
+               wipdata->meta.size = ip->meta.size;
                atomic_clear_int(&ip->flags, HAMMER2_INODE_RESIZED);
 
                /*
@@ -2094,7 +2117,7 @@ hammer2_inode_fsync(hammer2_trans_t *trans, hammer2_inode_t *ip,
                 * available.
                 */
                if ((wipdata->meta.op_flags & HAMMER2_OPFLAG_DIRECTDATA) &&
-                   ip->size > HAMMER2_EMBEDDED_BYTES) {
+                   ip->meta.size > HAMMER2_EMBEDDED_BYTES) {
                        wipdata->meta.op_flags &= ~HAMMER2_OPFLAG_DIRECTDATA;
                        bzero(&wipdata->u.blockset,
                              sizeof(wipdata->u.blockset));
index 53e3f28..808a8fc 100644 (file)
@@ -316,45 +316,20 @@ hammer2_getradix(size_t bytes)
 }
 
 /*
- * ip must be locked sh/ex
- *
- * Use 16KB logical buffers for file blocks <= 1MB and 64KB logical buffers
- * otherwise.  The write code may utilize smaller device buffers when
- * compressing or handling the EOF case, but is not able to coalesce smaller
- * logical buffers into larger device buffers.
- *
- * For now this means that even large files will have a bunch of 16KB blocks
- * at the beginning of the file.  On the plus side this tends to cause small
- * files to cluster together in the freemap.
+ * The logical block size is currently always PBUFSIZE.
  */
 int
 hammer2_calc_logical(hammer2_inode_t *ip, hammer2_off_t uoff,
                     hammer2_key_t *lbasep, hammer2_key_t *leofp)
 {
-#if 0
-       if (uoff < (hammer2_off_t)1024 * 1024) {
-               if (lbasep)
-                       *lbasep = uoff & ~HAMMER2_LBUFMASK64;
-               if (leofp) {
-                       if (ip->size > (hammer2_key_t)1024 * 1024)
-                               *leofp = (hammer2_key_t)1024 * 1024;
-                       else
-                               *leofp = (ip->size + HAMMER2_LBUFMASK64) &
-                                        ~HAMMER2_LBUFMASK64;
-               }
-               return (HAMMER2_LBUFSIZE);
-       } else {
-#endif
-               if (lbasep)
-                       *lbasep = uoff & ~HAMMER2_PBUFMASK64;
-               if (leofp) {
-                       *leofp = (ip->size + HAMMER2_PBUFMASK64) &
-                                ~HAMMER2_PBUFMASK64;
-               }
-               return (HAMMER2_PBUFSIZE);
-#if 0
+       KKASSERT(ip->flags & HAMMER2_INODE_METAGOOD);
+       if (lbasep)
+               *lbasep = uoff & ~HAMMER2_PBUFMASK64;
+       if (leofp) {
+               *leofp = (ip->meta.size + HAMMER2_PBUFMASK64) &
+                        ~HAMMER2_PBUFMASK64;
        }
-#endif
+       return (HAMMER2_PBUFSIZE);
 }
 
 /*
@@ -365,20 +340,19 @@ hammer2_calc_logical(hammer2_inode_t *ip, hammer2_off_t uoff,
  * Returns 0 if the requested base offset is beyond the file EOF.
  */
 int
-hammer2_calc_physical(hammer2_inode_t *ip,
-                     const hammer2_inode_data_t *ipdata,
-                     hammer2_key_t lbase)
+hammer2_calc_physical(hammer2_inode_t *ip, hammer2_key_t lbase)
 {
        int lblksize;
        int pblksize;
        int eofbytes;
 
+       KKASSERT(ip->flags & HAMMER2_INODE_METAGOOD);
        lblksize = hammer2_calc_logical(ip, lbase, NULL, NULL);
-       if (lbase + lblksize <= ipdata->meta.size)
+       if (lbase + lblksize <= ip->meta.size)
                return (lblksize);
-       if (lbase >= ipdata->meta.size)
+       if (lbase >= ip->meta.size)
                return (0);
-       eofbytes = (int)(ipdata->meta.size - lbase);
+       eofbytes = (int)(ip->meta.size - lbase);
        pblksize = lblksize;
        while (pblksize >= eofbytes && pblksize >= HAMMER2_ALLOC_MIN)
                pblksize >>= 1;
index 64def26..ae9b5f0 100644 (file)
@@ -212,20 +212,17 @@ static void hammer2_unmount_helper(struct mount *mp, hammer2_pfs_t *pmp,
  */
 static void hammer2_write_file_core(struct buf *bp, hammer2_trans_t *trans,
                                hammer2_inode_t *ip,
-                               const hammer2_inode_data_t *ripdata,
                                hammer2_cluster_t *cparent,
                                hammer2_key_t lbase, int ioflag, int pblksize,
                                int *errorp);
 static void hammer2_compress_and_write(struct buf *bp, hammer2_trans_t *trans,
                                hammer2_inode_t *ip,
-                               const hammer2_inode_data_t *ripdata,
                                hammer2_cluster_t *cparent,
                                hammer2_key_t lbase, int ioflag,
                                int pblksize, int *errorp,
                                int comp_algo, int check_algo);
 static void hammer2_zero_check_and_write(struct buf *bp,
                                hammer2_trans_t *trans, hammer2_inode_t *ip,
-                               const hammer2_inode_data_t *ripdata,
                                hammer2_cluster_t *cparent,
                                hammer2_key_t lbase,
                                int ioflag, int pblksize, int *errorp,
@@ -233,7 +230,6 @@ static void hammer2_zero_check_and_write(struct buf *bp,
 static int test_block_zeros(const char *buf, size_t bytes);
 static void zero_write(struct buf *bp, hammer2_trans_t *trans,
                                hammer2_inode_t *ip,
-                               const hammer2_inode_data_t *ripdata,
                                hammer2_cluster_t *cparent,
                                hammer2_key_t lbase,
                                int *errorp);
@@ -1214,7 +1210,6 @@ hammer2_write_thread(void *arg)
        struct vnode *vp;
        hammer2_inode_t *ip;
        hammer2_cluster_t *cparent;
-       const hammer2_inode_data_t *ripdata;
        hammer2_key_t lbase;
        int lblksize;
        int pblksize;
@@ -1283,15 +1278,13 @@ hammer2_write_thread(void *arg)
                                         HAMMER2_INODE_MTIME)) {
                                hammer2_inode_fsync(&trans, ip, cparent);
                        }
-                       ripdata = &hammer2_cluster_rdata(cparent)->ipdata;
                        lblksize = hammer2_calc_logical(ip, bio->bio_offset,
                                                        &lbase, NULL);
-                       pblksize = hammer2_calc_physical(ip, ripdata, lbase);
-                       hammer2_write_file_core(bp, &trans, ip, ripdata,
+                       pblksize = hammer2_calc_physical(ip, lbase);
+                       hammer2_write_file_core(bp, &trans, ip,
                                                cparent,
                                                lbase, IO_ASYNC,
                                                pblksize, &error);
-                       /* ripdata can be invalid after call */
                        hammer2_inode_unlock(ip, cparent);
                        if (error) {
                                kprintf("hammer2: error in buffer write\n");
@@ -1433,14 +1426,13 @@ static
 void
 hammer2_write_file_core(struct buf *bp, hammer2_trans_t *trans,
                        hammer2_inode_t *ip,
-                       const hammer2_inode_data_t *ripdata,
                        hammer2_cluster_t *cparent,
                        hammer2_key_t lbase, int ioflag, int pblksize,
                        int *errorp)
 {
        hammer2_cluster_t *cluster;
 
-       switch(HAMMER2_DEC_ALGO(ripdata->meta.comp_algo)) {
+       switch(HAMMER2_DEC_ALGO(ip->meta.comp_algo)) {
        case HAMMER2_COMP_NONE:
                /*
                 * We have to assign physical storage to the buffer
@@ -1466,9 +1458,8 @@ hammer2_write_file_core(struct buf *bp, hammer2_trans_t *trans,
                        hammer2_cluster_modsync(cluster);
                } else {
                        hammer2_write_bp(cluster, bp, ioflag, pblksize,
-                                        errorp, ripdata->meta.check_algo);
+                                        errorp, ip->meta.check_algo);
                }
-               /* ripdata can become invalid */
                if (cluster) {
                        hammer2_cluster_unlock(cluster);
                        hammer2_cluster_drop(cluster);
@@ -1479,9 +1470,9 @@ hammer2_write_file_core(struct buf *bp, hammer2_trans_t *trans,
                 * Check for zero-fill only
                 */
                hammer2_zero_check_and_write(bp, trans, ip,
-                                   ripdata, cparent, lbase,
+                                   cparent, lbase,
                                    ioflag, pblksize, errorp,
-                                   ripdata->meta.check_algo);
+                                   ip->meta.check_algo);
                break;
        case HAMMER2_COMP_LZ4:
        case HAMMER2_COMP_ZLIB:
@@ -1490,11 +1481,11 @@ hammer2_write_file_core(struct buf *bp, hammer2_trans_t *trans,
                 * Check for zero-fill and attempt compression.
                 */
                hammer2_compress_and_write(bp, trans, ip,
-                                          ripdata, cparent,
+                                          cparent,
                                           lbase, ioflag,
                                           pblksize, errorp,
-                                          ripdata->meta.comp_algo,
-                                          ripdata->meta.check_algo);
+                                          ip->meta.comp_algo,
+                                          ip->meta.check_algo);
                break;
        }
 }
@@ -1507,7 +1498,7 @@ hammer2_write_file_core(struct buf *bp, hammer2_trans_t *trans,
 static
 void
 hammer2_compress_and_write(struct buf *bp, hammer2_trans_t *trans,
-       hammer2_inode_t *ip, const hammer2_inode_data_t *ripdata,
+       hammer2_inode_t *ip,
        hammer2_cluster_t *cparent,
        hammer2_key_t lbase, int ioflag, int pblksize,
        int *errorp, int comp_algo, int check_algo)
@@ -1520,7 +1511,7 @@ hammer2_compress_and_write(struct buf *bp, hammer2_trans_t *trans,
        char *comp_buffer;
 
        if (test_block_zeros(bp->b_data, pblksize)) {
-               zero_write(bp, trans, ip, ripdata, cparent, lbase, errorp);
+               zero_write(bp, trans, ip, cparent, lbase, errorp);
                return;
        }
 
@@ -1623,8 +1614,6 @@ hammer2_compress_and_write(struct buf *bp, hammer2_trans_t *trans,
        cluster = hammer2_assign_physical(trans, ip, cparent,
                                          lbase, comp_block_size,
                                          errorp);
-       ripdata = NULL;
-
        if (*errorp) {
                kprintf("WRITE PATH: An error occurred while "
                        "assigning physical space.\n");
@@ -1751,7 +1740,7 @@ done:
 static
 void
 hammer2_zero_check_and_write(struct buf *bp, hammer2_trans_t *trans,
-       hammer2_inode_t *ip, const hammer2_inode_data_t *ripdata,
+       hammer2_inode_t *ip,
        hammer2_cluster_t *cparent,
        hammer2_key_t lbase, int ioflag, int pblksize, int *errorp,
        int check_algo)
@@ -1759,14 +1748,12 @@ hammer2_zero_check_and_write(struct buf *bp, hammer2_trans_t *trans,
        hammer2_cluster_t *cluster;
 
        if (test_block_zeros(bp->b_data, pblksize)) {
-               zero_write(bp, trans, ip, ripdata, cparent, lbase, errorp);
-               /* ripdata can become invalid */
+               zero_write(bp, trans, ip, cparent, lbase, errorp);
        } else {
                cluster = hammer2_assign_physical(trans, ip, cparent,
                                                  lbase, pblksize, errorp);
                hammer2_write_bp(cluster, bp, ioflag, pblksize, errorp,
                                 check_algo);
-               /* ripdata can become invalid */
                if (cluster) {
                        hammer2_cluster_unlock(cluster);
                        hammer2_cluster_drop(cluster);
@@ -1797,7 +1784,7 @@ test_block_zeros(const char *buf, size_t bytes)
 static
 void
 zero_write(struct buf *bp, hammer2_trans_t *trans,
-          hammer2_inode_t *ip, const hammer2_inode_data_t *ripdata,
+          hammer2_inode_t *ip,
           hammer2_cluster_t *cparent,
           hammer2_key_t lbase, int *errorp __unused)
 {
index 6f45a00..95b312b 100644 (file)
@@ -296,7 +296,7 @@ hammer2_vop_getattr(struct vop_getattr_args *ap)
        vap->va_gid = hammer2_to_unix_xid(&ripdata->meta.gid);
        vap->va_rmajor = 0;
        vap->va_rminor = 0;
-       vap->va_size = ip->size;        /* protected by shared lock */
+       vap->va_size = ip->meta.size;   /* protected by shared lock */
        vap->va_blocksize = HAMMER2_PBUFSIZE;
        vap->va_flags = ripdata->meta.uflags;
        hammer2_time_to_timespec(ripdata->meta.ctime, &vap->va_ctime);
@@ -415,13 +415,13 @@ hammer2_vop_setattr(struct vop_setattr_args *ap)
        /*
         * Resize the file
         */
-       if (vap->va_size != VNOVAL && ip->size != vap->va_size) {
+       if (vap->va_size != VNOVAL && ip->meta.size != vap->va_size) {
                switch(vp->v_type) {
                case VREG:
-                       if (vap->va_size == ip->size)
+                       if (vap->va_size == ip->meta.size)
                                break;
                        hammer2_inode_unlock(ip, cluster);
-                       if (vap->va_size < ip->size) {
+                       if (vap->va_size < ip->meta.size) {
                                hammer2_truncate_file(ip, vap->va_size);
                        } else {
                                hammer2_extend_file(ip, vap->va_size);
@@ -838,7 +838,7 @@ hammer2_read_file(hammer2_inode_t *ip, struct uio *uio, int seqcount)
         *          vnode level.
         */
        hammer2_mtx_sh(&ip->lock);
-       size = ip->size;
+       size = ip->meta.size;
        hammer2_mtx_unlock(&ip->lock);
 
        while (uio->uio_resid > 0 && uio->uio_offset < size) {
@@ -896,8 +896,8 @@ hammer2_write_file(hammer2_inode_t *ip,
         */
        hammer2_mtx_ex(&ip->lock);
        if (ioflag & IO_APPEND)
-               uio->uio_offset = ip->size;
-       old_eof = ip->size;
+               uio->uio_offset = ip->meta.size;
+       old_eof = ip->meta.size;
        hammer2_mtx_unlock(&ip->lock);
 
        /*
@@ -1046,7 +1046,7 @@ hammer2_write_file(hammer2_inode_t *ip,
                hammer2_truncate_file(ip, old_eof);
        } else if (modified) {
                hammer2_mtx_ex(&ip->lock);
-               hammer2_update_time(&ip->mtime);
+               hammer2_update_time(&ip->meta.mtime);
                atomic_set_int(&ip->flags, HAMMER2_INODE_MTIME);
                hammer2_mtx_unlock(&ip->lock);
        }
@@ -1084,7 +1084,7 @@ hammer2_truncate_file(hammer2_inode_t *ip, hammer2_key_t nsize)
                           0);
        }
        hammer2_mtx_ex(&ip->lock);
-       ip->size = nsize;
+       ip->meta.size = nsize;
        atomic_set_int(&ip->flags, HAMMER2_INODE_RESIZED);
        hammer2_mtx_unlock(&ip->lock);
        LOCKSTOP;
@@ -1109,8 +1109,8 @@ hammer2_extend_file(hammer2_inode_t *ip, hammer2_key_t nsize)
 
        LOCKSTART;
        hammer2_mtx_ex(&ip->lock);
-       osize = ip->size;
-       ip->size = nsize;
+       osize = ip->meta.size;
+       ip->meta.size = nsize;
        hammer2_mtx_unlock(&ip->lock);
 
        if (ip->vp) {
@@ -1454,7 +1454,8 @@ hammer2_vop_nlink(struct vop_nlink_args *ap)
         * WARNING! chain can get moved by the connect (indirectly due to
         *          potential indirect block creation).
         */
-       error = hammer2_inode_connect(&trans, &cluster, 1,
+       error = hammer2_inode_connect(&trans,
+                                     ip, &cluster, 1,
                                      tdip, tdcluster,
                                      name, name_len, 0);
        if (error == 0) {
@@ -1634,7 +1635,7 @@ hammer2_vop_nsymlink(struct vop_nsymlink_args *ap)
                                 HAMMER2_OPFLAG_DIRECTDATA);
                        bcopy(ap->a_target, nipdata->u.data, bytes);
                        nipdata->meta.size = bytes;
-                       nip->size = bytes;
+                       nip->meta.size = bytes;
                        hammer2_cluster_modsync(ncparent);
                        hammer2_inode_unlock(nip, ncparent);
                        /* nipdata = NULL; not needed */
@@ -1901,7 +1902,8 @@ hammer2_vop_nrename(struct vop_nrename_args *ap)
         * NOTE:    Pass nlinks as 0 because we retained the link count from
         *          the unlink, so we do not have to modify it.
         */
-       error = hammer2_inode_connect(&trans, &cluster, hlink,
+       error = hammer2_inode_connect(&trans,
+                                     ip, &cluster, hlink,
                                      tdip, tdcluster,
                                      tname, tname_len, 0);
        if (error == 0) {
@@ -2099,7 +2101,7 @@ filt_hammer2read(struct knote *kn, long hint)
                kn->kn_flags |= (EV_EOF | EV_NODATA | EV_ONESHOT);
                return(1);
        }
-       off = ip->size - kn->kn_fp->f_offset;
+       off = ip->meta.size - kn->kn_fp->f_offset;
        kn->kn_data = (off < INTPTR_MAX) ? off : INTPTR_MAX;
        if (kn->kn_sfflags & NOTE_OLDAPI)
                return(1);