···177 XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) > tip->i_df.if_ext_max)178 return EINVAL;179180- /* Check root block of temp in btree form to max in target */00000000181 if (tip->i_d.di_format == XFS_DINODE_FMT_BTREE &&182- XFS_IFORK_BOFF(ip) &&183- tip->i_df.if_broot_bytes > XFS_IFORK_BOFF(ip))0184 return EINVAL;185186- /* Check root block of target in btree form to max in temp */187 if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE &&188- XFS_IFORK_BOFF(tip) &&189- ip->i_df.if_broot_bytes > XFS_IFORK_BOFF(tip))0190 return EINVAL;191192 return 0;
···177 XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) > tip->i_df.if_ext_max)178 return EINVAL;179180+ /*181+ * If we are in a btree format, check that the temp root block will fit182+ * in the target and that it has enough extents to be in btree format183+ * in the target.184+ *185+ * Note that we have to be careful to allow btree->extent conversions186+ * (a common defrag case) which will occur when the temp inode is in187+ * extent format...188+ */189 if (tip->i_d.di_format == XFS_DINODE_FMT_BTREE &&190+ ((XFS_IFORK_BOFF(ip) &&191+ tip->i_df.if_broot_bytes > XFS_IFORK_BOFF(ip)) ||192+ XFS_IFORK_NEXTENTS(tip, XFS_DATA_FORK) <= ip->i_df.if_ext_max))193 return EINVAL;194195+ /* Reciprocal target->temp btree format checks */196 if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE &&197+ ((XFS_IFORK_BOFF(tip) &&198+ ip->i_df.if_broot_bytes > XFS_IFORK_BOFF(tip)) ||199+ XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) <= tip->i_df.if_ext_max))200 return EINVAL;201202 return 0;