diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
| -rw-r--r-- | fs/xfs/xfs_inode.c | 272 | 
1 files changed, 140 insertions, 132 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index f93370bd7b1e..0369eb22c1bb 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -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,11 +794,11 @@ 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)) { -		inode->i_uid = fsuid_into_mnt(mnt_userns); +		inode_fsuid_set(inode, mnt_userns);  		inode->i_gid = dir->i_gid;  		inode->i_mode = mode;  	} else { @@ -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; @@ -878,6 +859,20 @@ xfs_init_new_inode(  	}  	/* +	 * 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.  	 */  	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); @@ -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); @@ -1007,8 +1004,8 @@ xfs_create(  	/*  	 * Make sure that we have allocated dquot(s) on disk.  	 */ -	error = xfs_qm_vop_dqalloc(dp, fsuid_into_mnt(mnt_userns), -			fsgid_into_mnt(mnt_userns), prid, +	error = xfs_qm_vop_dqalloc(dp, mapped_fsuid(mnt_userns), +			mapped_fsgid(mnt_userns), prid,  			XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT,  			&udqp, &gdqp, &pdqp);  	if (error) @@ -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; @@ -1158,8 +1155,8 @@ xfs_create_tmpfile(  	/*  	 * Make sure that we have allocated dquot(s) on disk.  	 */ -	error = xfs_qm_vop_dqalloc(dp, fsuid_into_mnt(mnt_userns), -			fsgid_into_mnt(mnt_userns), prid, +	error = xfs_qm_vop_dqalloc(dp, mapped_fsuid(mnt_userns), +			mapped_fsgid(mnt_userns), prid,  			XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT,  			&udqp, &gdqp, &pdqp);  	if (error) @@ -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))  |