Merge tag 'for-5.13-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[linux-2.6-microblaze.git] / fs / xfs / xfs_inode.c
index 2a8bdf3..0369eb2 100644 (file)
@@ -60,8 +60,8 @@ xfs_get_extsz_hint(
         */
        if (xfs_is_always_cow_inode(ip))
                return 0;
-       if ((ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE) && ip->i_d.di_extsize)
-               return ip->i_d.di_extsize;
+       if ((ip->i_diflags & XFS_DIFLAG_EXTSIZE) && ip->i_extsize)
+               return ip->i_extsize;
        if (XFS_IS_REALTIME_INODE(ip))
                return ip->i_mount->m_sb.sb_rextsize;
        return 0;
@@ -80,8 +80,8 @@ xfs_get_cowextsz_hint(
        xfs_extlen_t            a, b;
 
        a = 0;
-       if (ip->i_d.di_flags2 & XFS_DIFLAG2_COWEXTSIZE)
-               a = ip->i_d.di_cowextsize;
+       if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE)
+               a = ip->i_cowextsize;
        b = xfs_get_extsz_hint(ip);
 
        a = max(a, b);
@@ -111,8 +111,7 @@ xfs_ilock_data_map_shared(
 {
        uint                    lock_mode = XFS_ILOCK_SHARED;
 
-       if (ip->i_df.if_format == XFS_DINODE_FMT_BTREE &&
-           (ip->i_df.if_flags & XFS_IFEXTENTS) == 0)
+       if (xfs_need_iread_extents(&ip->i_df))
                lock_mode = XFS_ILOCK_EXCL;
        xfs_ilock(ip, lock_mode);
        return lock_mode;
@@ -124,9 +123,7 @@ xfs_ilock_attr_map_shared(
 {
        uint                    lock_mode = XFS_ILOCK_SHARED;
 
-       if (ip->i_afp &&
-           ip->i_afp->if_format == XFS_DINODE_FMT_BTREE &&
-           (ip->i_afp->if_flags & XFS_IFEXTENTS) == 0)
+       if (ip->i_afp && xfs_need_iread_extents(ip->i_afp))
                lock_mode = XFS_ILOCK_EXCL;
        xfs_ilock(ip, lock_mode);
        return lock_mode;
@@ -598,67 +595,55 @@ xfs_lock_two_inodes(
        }
 }
 
-STATIC uint
-_xfs_dic2xflags(
-       uint16_t                di_flags,
-       uint64_t                di_flags2,
-       bool                    has_attr)
+uint
+xfs_ip2xflags(
+       struct xfs_inode        *ip)
 {
        uint                    flags = 0;
 
-       if (di_flags & XFS_DIFLAG_ANY) {
-               if (di_flags & XFS_DIFLAG_REALTIME)
+       if (ip->i_diflags & XFS_DIFLAG_ANY) {
+               if (ip->i_diflags & XFS_DIFLAG_REALTIME)
                        flags |= FS_XFLAG_REALTIME;
-               if (di_flags & XFS_DIFLAG_PREALLOC)
+               if (ip->i_diflags & XFS_DIFLAG_PREALLOC)
                        flags |= FS_XFLAG_PREALLOC;
-               if (di_flags & XFS_DIFLAG_IMMUTABLE)
+               if (ip->i_diflags & XFS_DIFLAG_IMMUTABLE)
                        flags |= FS_XFLAG_IMMUTABLE;
-               if (di_flags & XFS_DIFLAG_APPEND)
+               if (ip->i_diflags & XFS_DIFLAG_APPEND)
                        flags |= FS_XFLAG_APPEND;
-               if (di_flags & XFS_DIFLAG_SYNC)
+               if (ip->i_diflags & XFS_DIFLAG_SYNC)
                        flags |= FS_XFLAG_SYNC;
-               if (di_flags & XFS_DIFLAG_NOATIME)
+               if (ip->i_diflags & XFS_DIFLAG_NOATIME)
                        flags |= FS_XFLAG_NOATIME;
-               if (di_flags & XFS_DIFLAG_NODUMP)
+               if (ip->i_diflags & XFS_DIFLAG_NODUMP)
                        flags |= FS_XFLAG_NODUMP;
-               if (di_flags & XFS_DIFLAG_RTINHERIT)
+               if (ip->i_diflags & XFS_DIFLAG_RTINHERIT)
                        flags |= FS_XFLAG_RTINHERIT;
-               if (di_flags & XFS_DIFLAG_PROJINHERIT)
+               if (ip->i_diflags & XFS_DIFLAG_PROJINHERIT)
                        flags |= FS_XFLAG_PROJINHERIT;
-               if (di_flags & XFS_DIFLAG_NOSYMLINKS)
+               if (ip->i_diflags & XFS_DIFLAG_NOSYMLINKS)
                        flags |= FS_XFLAG_NOSYMLINKS;
-               if (di_flags & XFS_DIFLAG_EXTSIZE)
+               if (ip->i_diflags & XFS_DIFLAG_EXTSIZE)
                        flags |= FS_XFLAG_EXTSIZE;
-               if (di_flags & XFS_DIFLAG_EXTSZINHERIT)
+               if (ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT)
                        flags |= FS_XFLAG_EXTSZINHERIT;
-               if (di_flags & XFS_DIFLAG_NODEFRAG)
+               if (ip->i_diflags & XFS_DIFLAG_NODEFRAG)
                        flags |= FS_XFLAG_NODEFRAG;
-               if (di_flags & XFS_DIFLAG_FILESTREAM)
+               if (ip->i_diflags & XFS_DIFLAG_FILESTREAM)
                        flags |= FS_XFLAG_FILESTREAM;
        }
 
-       if (di_flags2 & XFS_DIFLAG2_ANY) {
-               if (di_flags2 & XFS_DIFLAG2_DAX)
+       if (ip->i_diflags2 & XFS_DIFLAG2_ANY) {
+               if (ip->i_diflags2 & XFS_DIFLAG2_DAX)
                        flags |= FS_XFLAG_DAX;
-               if (di_flags2 & XFS_DIFLAG2_COWEXTSIZE)
+               if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE)
                        flags |= FS_XFLAG_COWEXTSIZE;
        }
 
-       if (has_attr)
+       if (XFS_IFORK_Q(ip))
                flags |= FS_XFLAG_HASATTR;
-
        return flags;
 }
 
-uint
-xfs_ip2xflags(
-       struct xfs_inode        *ip)
-{
-       struct xfs_icdinode     *dic = &ip->i_d;
-
-       return _xfs_dic2xflags(dic->di_flags, dic->di_flags2, XFS_IFORK_Q(ip));
-}
-
 /*
  * Lookups up an inode from "name". If ci_name is not NULL, then a CI match
  * is allowed, otherwise it has to be an exact match. If a CI match is found,
@@ -708,42 +693,42 @@ xfs_inode_inherit_flags(
        umode_t                 mode = VFS_I(ip)->i_mode;
 
        if (S_ISDIR(mode)) {
-               if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT)
+               if (pip->i_diflags & XFS_DIFLAG_RTINHERIT)
                        di_flags |= XFS_DIFLAG_RTINHERIT;
-               if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) {
+               if (pip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) {
                        di_flags |= XFS_DIFLAG_EXTSZINHERIT;
-                       ip->i_d.di_extsize = pip->i_d.di_extsize;
+                       ip->i_extsize = pip->i_extsize;
                }
-               if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
+               if (pip->i_diflags & XFS_DIFLAG_PROJINHERIT)
                        di_flags |= XFS_DIFLAG_PROJINHERIT;
        } else if (S_ISREG(mode)) {
-               if ((pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) &&
+               if ((pip->i_diflags & XFS_DIFLAG_RTINHERIT) &&
                    xfs_sb_version_hasrealtime(&ip->i_mount->m_sb))
                        di_flags |= XFS_DIFLAG_REALTIME;
-               if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) {
+               if (pip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) {
                        di_flags |= XFS_DIFLAG_EXTSIZE;
-                       ip->i_d.di_extsize = pip->i_d.di_extsize;
+                       ip->i_extsize = pip->i_extsize;
                }
        }
-       if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) &&
+       if ((pip->i_diflags & XFS_DIFLAG_NOATIME) &&
            xfs_inherit_noatime)
                di_flags |= XFS_DIFLAG_NOATIME;
-       if ((pip->i_d.di_flags & XFS_DIFLAG_NODUMP) &&
+       if ((pip->i_diflags & XFS_DIFLAG_NODUMP) &&
            xfs_inherit_nodump)
                di_flags |= XFS_DIFLAG_NODUMP;
-       if ((pip->i_d.di_flags & XFS_DIFLAG_SYNC) &&
+       if ((pip->i_diflags & XFS_DIFLAG_SYNC) &&
            xfs_inherit_sync)
                di_flags |= XFS_DIFLAG_SYNC;
-       if ((pip->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) &&
+       if ((pip->i_diflags & XFS_DIFLAG_NOSYMLINKS) &&
            xfs_inherit_nosymlinks)
                di_flags |= XFS_DIFLAG_NOSYMLINKS;
-       if ((pip->i_d.di_flags & XFS_DIFLAG_NODEFRAG) &&
+       if ((pip->i_diflags & XFS_DIFLAG_NODEFRAG) &&
            xfs_inherit_nodefrag)
                di_flags |= XFS_DIFLAG_NODEFRAG;
-       if (pip->i_d.di_flags & XFS_DIFLAG_FILESTREAM)
+       if (pip->i_diflags & XFS_DIFLAG_FILESTREAM)
                di_flags |= XFS_DIFLAG_FILESTREAM;
 
-       ip->i_d.di_flags |= di_flags;
+       ip->i_diflags |= di_flags;
 }
 
 /* Propagate di_flags2 from a parent inode to a child inode. */
@@ -752,12 +737,12 @@ xfs_inode_inherit_flags2(
        struct xfs_inode        *ip,
        const struct xfs_inode  *pip)
 {
-       if (pip->i_d.di_flags2 & XFS_DIFLAG2_COWEXTSIZE) {
-               ip->i_d.di_flags2 |= XFS_DIFLAG2_COWEXTSIZE;
-               ip->i_d.di_cowextsize = pip->i_d.di_cowextsize;
+       if (pip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE) {
+               ip->i_diflags2 |= XFS_DIFLAG2_COWEXTSIZE;
+               ip->i_cowextsize = pip->i_cowextsize;
        }
-       if (pip->i_d.di_flags2 & XFS_DIFLAG2_DAX)
-               ip->i_d.di_flags2 |= XFS_DIFLAG2_DAX;
+       if (pip->i_diflags2 & XFS_DIFLAG2_DAX)
+               ip->i_diflags2 |= XFS_DIFLAG2_DAX;
 }
 
 /*
@@ -774,6 +759,7 @@ xfs_init_new_inode(
        xfs_nlink_t             nlink,
        dev_t                   rdev,
        prid_t                  prid,
+       bool                    init_xattrs,
        struct xfs_inode        **ipp)
 {
        struct inode            *dir = pip ? VFS_I(pip) : NULL;
@@ -808,7 +794,7 @@ xfs_init_new_inode(
        inode = VFS_I(ip);
        set_nlink(inode, nlink);
        inode->i_rdev = rdev;
-       ip->i_d.di_projid = prid;
+       ip->i_projid = prid;
 
        if (dir && !(dir->i_mode & S_ISGID) &&
            (mp->m_flags & XFS_MOUNT_GRPID)) {
@@ -829,25 +815,22 @@ xfs_init_new_inode(
            !in_group_p(i_gid_into_mnt(mnt_userns, inode)))
                inode->i_mode &= ~S_ISGID;
 
-       ip->i_d.di_size = 0;
+       ip->i_disk_size = 0;
        ip->i_df.if_nextents = 0;
-       ASSERT(ip->i_d.di_nblocks == 0);
+       ASSERT(ip->i_nblocks == 0);
 
        tv = current_time(inode);
        inode->i_mtime = tv;
        inode->i_atime = tv;
        inode->i_ctime = tv;
 
-       ip->i_d.di_extsize = 0;
-       ip->i_d.di_dmevmask = 0;
-       ip->i_d.di_dmstate = 0;
-       ip->i_d.di_flags = 0;
+       ip->i_extsize = 0;
+       ip->i_diflags = 0;
 
        if (xfs_sb_version_has_v3inode(&mp->m_sb)) {
                inode_set_iversion(inode, 1);
-               ip->i_d.di_flags2 = mp->m_ino_geo.new_diflags2;
-               ip->i_d.di_cowextsize = 0;
-               ip->i_d.di_crtime = tv;
+               ip->i_cowextsize = 0;
+               ip->i_crtime = tv;
        }
 
        flags = XFS_ILOG_CORE;
@@ -857,19 +840,17 @@ xfs_init_new_inode(
        case S_IFBLK:
        case S_IFSOCK:
                ip->i_df.if_format = XFS_DINODE_FMT_DEV;
-               ip->i_df.if_flags = 0;
                flags |= XFS_ILOG_DEV;
                break;
        case S_IFREG:
        case S_IFDIR:
-               if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY))
+               if (pip && (pip->i_diflags & XFS_DIFLAG_ANY))
                        xfs_inode_inherit_flags(ip, pip);
-               if (pip && (pip->i_d.di_flags2 & XFS_DIFLAG2_ANY))
+               if (pip && (pip->i_diflags2 & XFS_DIFLAG2_ANY))
                        xfs_inode_inherit_flags2(ip, pip);
                /* FALLTHROUGH */
        case S_IFLNK:
                ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
-               ip->i_df.if_flags = XFS_IFEXTENTS;
                ip->i_df.if_bytes = 0;
                ip->i_df.if_u1.if_root = NULL;
                break;
@@ -877,6 +858,20 @@ xfs_init_new_inode(
                ASSERT(0);
        }
 
+       /*
+        * If we need to create attributes immediately after allocating the
+        * inode, initialise an empty attribute fork right now. We use the
+        * default fork offset for attributes here as we don't know exactly what
+        * size or how many attributes we might be adding. We can do this
+        * safely here because we know the data fork is completely empty and
+        * this saves us from needing to run a separate transaction to set the
+        * fork offset in the immediate future.
+        */
+       if (init_xattrs && xfs_sb_version_hasattr(&mp->m_sb)) {
+               ip->i_forkoff = xfs_default_attroffset(ip) >> 3;
+               ip->i_afp = xfs_ifork_alloc(XFS_DINODE_FMT_EXTENTS, 0);
+       }
+
        /*
         * Log the new values stuffed into the inode.
         */
@@ -910,6 +905,7 @@ xfs_dir_ialloc(
        xfs_nlink_t             nlink,
        dev_t                   rdev,
        prid_t                  prid,
+       bool                    init_xattrs,
        struct xfs_inode        **ipp)
 {
        struct xfs_buf          *agibp;
@@ -937,7 +933,7 @@ xfs_dir_ialloc(
        ASSERT(ino != NULLFSINO);
 
        return xfs_init_new_inode(mnt_userns, *tpp, dp, ino, mode, nlink, rdev,
-                                 prid, ipp);
+                                 prid, init_xattrs, ipp);
 }
 
 /*
@@ -982,6 +978,7 @@ xfs_create(
        struct xfs_name         *name,
        umode_t                 mode,
        dev_t                   rdev,
+       bool                    init_xattrs,
        xfs_inode_t             **ipp)
 {
        int                     is_dir = S_ISDIR(mode);
@@ -1053,7 +1050,7 @@ xfs_create(
         * pointing to itself.
         */
        error = xfs_dir_ialloc(mnt_userns, &tp, dp, mode, is_dir ? 2 : 1, rdev,
-                              prid, &ip);
+                              prid, init_xattrs, &ip);
        if (error)
                goto out_trans_cancel;
 
@@ -1173,7 +1170,8 @@ xfs_create_tmpfile(
        if (error)
                goto out_release_dquots;
 
-       error = xfs_dir_ialloc(mnt_userns, &tp, dp, mode, 0, 0, prid, &ip);
+       error = xfs_dir_ialloc(mnt_userns, &tp, dp, mode, 0, 0, prid,
+                               false, &ip);
        if (error)
                goto out_trans_cancel;
 
@@ -1272,8 +1270,8 @@ xfs_link(
         * creation in our tree when the project IDs are the same; else
         * the tree quota mechanism could be circumvented.
         */
-       if (unlikely((tdp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
-                    tdp->i_d.di_projid != sip->i_d.di_projid)) {
+       if (unlikely((tdp->i_diflags & XFS_DIFLAG_PROJINHERIT) &&
+                    tdp->i_projid != sip->i_projid)) {
                error = -EXDEV;
                goto error_return;
        }
@@ -1331,7 +1329,7 @@ xfs_itruncate_clear_reflink_flags(
        dfork = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
        cfork = XFS_IFORK_PTR(ip, XFS_COW_FORK);
        if (dfork->if_bytes == 0 && cfork->if_bytes == 0)
-               ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK;
+               ip->i_diflags2 &= ~XFS_DIFLAG2_REFLINK;
        if (cfork->if_bytes == 0)
                xfs_inode_clear_cowblocks_tag(ip);
 }
@@ -1442,7 +1440,7 @@ xfs_release(
        xfs_inode_t     *ip)
 {
        xfs_mount_t     *mp = ip->i_mount;
-       int             error;
+       int             error = 0;
 
        if (!S_ISREG(VFS_I(ip)->i_mode) || (VFS_I(ip)->i_mode == 0))
                return 0;
@@ -1478,8 +1476,16 @@ xfs_release(
        if (VFS_I(ip)->i_nlink == 0)
                return 0;
 
-       if (xfs_can_free_eofblocks(ip, false)) {
+       /*
+        * If we can't get the iolock just skip truncating the blocks past EOF
+        * because we could deadlock with the mmap_lock otherwise. We'll get
+        * another chance to drop them once the last reference to the inode is
+        * dropped, so we'll never leak blocks permanently.
+        */
+       if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL))
+               return 0;
 
+       if (xfs_can_free_eofblocks(ip, false)) {
                /*
                 * Check if the inode is being opened, written and closed
                 * frequently and we have delayed allocation blocks outstanding
@@ -1495,26 +1501,20 @@ xfs_release(
                 * place.
                 */
                if (xfs_iflags_test(ip, XFS_IDIRTY_RELEASE))
-                       return 0;
-               /*
-                * If we can't get the iolock just skip truncating the blocks
-                * past EOF because we could deadlock with the mmap_lock
-                * otherwise. We'll get another chance to drop them once the
-                * last reference to the inode is dropped, so we'll never leak
-                * blocks permanently.
-                */
-               if (xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) {
-                       error = xfs_free_eofblocks(ip);
-                       xfs_iunlock(ip, XFS_IOLOCK_EXCL);
-                       if (error)
-                               return error;
-               }
+                       goto out_unlock;
+
+               error = xfs_free_eofblocks(ip);
+               if (error)
+                       goto out_unlock;
 
                /* delalloc blocks after truncation means it really is dirty */
                if (ip->i_delayed_blks)
                        xfs_iflags_set(ip, XFS_IDIRTY_RELEASE);
        }
-       return 0;
+
+out_unlock:
+       xfs_iunlock(ip, XFS_IOLOCK_EXCL);
+       return error;
 }
 
 /*
@@ -1543,7 +1543,7 @@ xfs_inactive_truncate(
         * of a system crash before the truncate completes. See the related
         * comment in xfs_vn_setattr_size() for details.
         */
-       ip->i_d.di_size = 0;
+       ip->i_disk_size = 0;
        xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
 
        error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, 0);
@@ -1697,6 +1697,10 @@ xfs_inactive(
        if (mp->m_flags & XFS_MOUNT_RDONLY)
                return;
 
+       /* Metadata inodes require explicit resource cleanup. */
+       if (xfs_is_metadata_inode(ip))
+               return;
+
        /* Try to clean out the cow blocks if there are any. */
        if (xfs_inode_has_cow_data(ip))
                xfs_reflink_cancel_cow_range(ip, 0, NULLFILEOFF, true);
@@ -1718,7 +1722,7 @@ xfs_inactive(
        }
 
        if (S_ISREG(VFS_I(ip)->i_mode) &&
-           (ip->i_d.di_size != 0 || XFS_ISIZE(ip) != 0 ||
+           (ip->i_disk_size != 0 || XFS_ISIZE(ip) != 0 ||
             ip->i_df.if_nextents > 0 || ip->i_delayed_blks > 0))
                truncate = 1;
 
@@ -1745,7 +1749,7 @@ xfs_inactive(
        }
 
        ASSERT(!ip->i_afp);
-       ASSERT(ip->i_d.di_forkoff == 0);
+       ASSERT(ip->i_forkoff == 0);
 
        /*
         * Free the inode.
@@ -2053,9 +2057,10 @@ xfs_iunlink_update_inode(
 
        ASSERT(xfs_verify_agino_or_null(mp, agno, next_agino));
 
-       error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &ibp, 0);
+       error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &ibp);
        if (error)
                return error;
+       dip = xfs_buf_offset(ibp, ip->i_imap.im_boffset);
 
        /* Make sure the old pointer isn't garbage. */
        old_value = be32_to_cpu(dip->di_next_unlinked);
@@ -2180,13 +2185,14 @@ xfs_iunlink_map_ino(
                return error;
        }
 
-       error = xfs_imap_to_bp(mp, tp, imap, dipp, bpp, 0);
+       error = xfs_imap_to_bp(mp, tp, imap, bpp);
        if (error) {
                xfs_warn(mp, "%s: xfs_imap_to_bp returned error %d.",
                                __func__, error);
                return error;
        }
 
+       *dipp = xfs_buf_offset(*bpp, imap->im_boffset);
        return 0;
 }
 
@@ -2564,8 +2570,8 @@ xfs_ifree(
        ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
        ASSERT(VFS_I(ip)->i_nlink == 0);
        ASSERT(ip->i_df.if_nextents == 0);
-       ASSERT(ip->i_d.di_size == 0 || !S_ISREG(VFS_I(ip)->i_mode));
-       ASSERT(ip->i_d.di_nblocks == 0);
+       ASSERT(ip->i_disk_size == 0 || !S_ISREG(VFS_I(ip)->i_mode));
+       ASSERT(ip->i_nblocks == 0);
 
        /*
         * Pull the on-disk inode from the AGI unlinked list.
@@ -2590,11 +2596,12 @@ xfs_ifree(
        }
 
        VFS_I(ip)->i_mode = 0;          /* mark incore inode as free */
-       ip->i_d.di_flags = 0;
-       ip->i_d.di_flags2 = ip->i_mount->m_ino_geo.new_diflags2;
-       ip->i_d.di_dmevmask = 0;
-       ip->i_d.di_forkoff = 0;         /* mark the attr fork not in use */
+       ip->i_diflags = 0;
+       ip->i_diflags2 = ip->i_mount->m_ino_geo.new_diflags2;
+       ip->i_forkoff = 0;              /* mark the attr fork not in use */
        ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
+       if (xfs_iflags_test(ip, XFS_IPRESERVE_DM_FIELDS))
+               xfs_iflags_clear(ip, XFS_IPRESERVE_DM_FIELDS);
 
        /* Don't attempt to replay owner changes for a deleted inode */
        spin_lock(&iip->ili_lock);
@@ -2870,7 +2877,7 @@ xfs_finish_rename(
 /*
  * xfs_cross_rename()
  *
- * responsible for handling RENAME_EXCHANGE flag in renameat2() sytemcall
+ * responsible for handling RENAME_EXCHANGE flag in renameat2() syscall
  */
 STATIC int
 xfs_cross_rename(
@@ -3103,8 +3110,8 @@ xfs_rename(
         * into our tree when the project IDs are the same; else the
         * tree quota mechanism would be circumvented.
         */
-       if (unlikely((target_dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
-                    target_dp->i_d.di_projid != src_ip->i_d.di_projid)) {
+       if (unlikely((target_dp->i_diflags & XFS_DIFLAG_PROJINHERIT) &&
+                    target_dp->i_projid != src_ip->i_projid)) {
                error = -EXDEV;
                goto out_trans_cancel;
        }
@@ -3414,34 +3421,33 @@ xfs_iflush(
                }
        }
        if (XFS_TEST_ERROR(ip->i_df.if_nextents + xfs_ifork_nextents(ip->i_afp) >
-                               ip->i_d.di_nblocks, mp, XFS_ERRTAG_IFLUSH_5)) {
+                               ip->i_nblocks, mp, XFS_ERRTAG_IFLUSH_5)) {
                xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
                        "%s: detected corrupt incore inode %Lu, "
                        "total extents = %d, nblocks = %Ld, ptr "PTR_FMT,
                        __func__, ip->i_ino,
                        ip->i_df.if_nextents + xfs_ifork_nextents(ip->i_afp),
-                       ip->i_d.di_nblocks, ip);
+                       ip->i_nblocks, ip);
                goto flush_out;
        }
-       if (XFS_TEST_ERROR(ip->i_d.di_forkoff > mp->m_sb.sb_inodesize,
+       if (XFS_TEST_ERROR(ip->i_forkoff > mp->m_sb.sb_inodesize,
                                mp, XFS_ERRTAG_IFLUSH_6)) {
                xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
                        "%s: bad inode %Lu, forkoff 0x%x, ptr "PTR_FMT,
-                       __func__, ip->i_ino, ip->i_d.di_forkoff, ip);
+                       __func__, ip->i_ino, ip->i_forkoff, ip);
                goto flush_out;
        }
 
        /*
-        * Inode item log recovery for v2 inodes are dependent on the
-        * di_flushiter count for correct sequencing. We bump the flush
-        * iteration count so we can detect flushes which postdate a log record
-        * during recovery. This is redundant as we now log every change and
-        * hence this can't happen but we need to still do it to ensure
-        * backwards compatibility with old kernels that predate logging all
-        * inode changes.
+        * Inode item log recovery for v2 inodes are dependent on the flushiter
+        * count for correct sequencing.  We bump the flush iteration count so
+        * we can detect flushes which postdate a log record during recovery.
+        * This is redundant as we now log every change and hence this can't
+        * happen but we need to still do it to ensure backwards compatibility
+        * with old kernels that predate logging all inode changes.
         */
        if (!xfs_sb_version_has_v3inode(&mp->m_sb))
-               ip->i_d.di_flushiter++;
+               ip->i_flushiter++;
 
        /*
         * If there are inline format data / attr forks attached to this inode,
@@ -3462,8 +3468,10 @@ xfs_iflush(
        xfs_inode_to_disk(ip, dip, iip->ili_item.li_lsn);
 
        /* Wrap, we never let the log put out DI_MAX_FLUSH */
-       if (ip->i_d.di_flushiter == DI_MAX_FLUSH)
-               ip->i_d.di_flushiter = 0;
+       if (!xfs_sb_version_has_v3inode(&mp->m_sb)) {
+               if (ip->i_flushiter == DI_MAX_FLUSH)
+                       ip->i_flushiter = 0;
+       }
 
        xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK);
        if (XFS_IFORK_Q(ip))