|
@@ -3568,6 +3568,27 @@ xfs_bmap_extents_to_btree(
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * Calculate the default attribute fork offset for newly created inodes.
|
|
|
|
+ */
|
|
|
|
+uint
|
|
|
|
+xfs_default_attroffset(
|
|
|
|
+ struct xfs_inode *ip)
|
|
|
|
+{
|
|
|
|
+ struct xfs_mount *mp = ip->i_mount;
|
|
|
|
+ uint offset;
|
|
|
|
+
|
|
|
|
+ if (mp->m_sb.sb_inodesize == 256) {
|
|
|
|
+ offset = XFS_LITINO(mp) -
|
|
|
|
+ XFS_BMDR_SPACE_CALC(MINABTPTRS);
|
|
|
|
+ } else {
|
|
|
|
+ offset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ASSERT(offset < XFS_LITINO(mp));
|
|
|
|
+ return offset;
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Helper routine to reset inode di_forkoff field when switching
|
|
* Helper routine to reset inode di_forkoff field when switching
|
|
* attribute fork from local to extent format - we reset it where
|
|
* attribute fork from local to extent format - we reset it where
|
|
@@ -3580,15 +3601,18 @@ xfs_bmap_forkoff_reset(
|
|
int whichfork)
|
|
int whichfork)
|
|
{
|
|
{
|
|
if (whichfork == XFS_ATTR_FORK &&
|
|
if (whichfork == XFS_ATTR_FORK &&
|
|
- (ip->i_d.di_format != XFS_DINODE_FMT_DEV) &&
|
|
|
|
- (ip->i_d.di_format != XFS_DINODE_FMT_UUID) &&
|
|
|
|
- (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
|
|
|
|
- ((mp->m_attroffset >> 3) > ip->i_d.di_forkoff)) {
|
|
|
|
- ip->i_d.di_forkoff = mp->m_attroffset >> 3;
|
|
|
|
- ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) /
|
|
|
|
- (uint)sizeof(xfs_bmbt_rec_t);
|
|
|
|
- ip->i_afp->if_ext_max = XFS_IFORK_ASIZE(ip) /
|
|
|
|
- (uint)sizeof(xfs_bmbt_rec_t);
|
|
|
|
|
|
+ ip->i_d.di_format != XFS_DINODE_FMT_DEV &&
|
|
|
|
+ ip->i_d.di_format != XFS_DINODE_FMT_UUID &&
|
|
|
|
+ ip->i_d.di_format != XFS_DINODE_FMT_BTREE) {
|
|
|
|
+ uint dfl_forkoff = xfs_default_attroffset(ip) >> 3;
|
|
|
|
+
|
|
|
|
+ if (dfl_forkoff > ip->i_d.di_forkoff) {
|
|
|
|
+ ip->i_d.di_forkoff = dfl_forkoff;
|
|
|
|
+ ip->i_df.if_ext_max =
|
|
|
|
+ XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t);
|
|
|
|
+ ip->i_afp->if_ext_max =
|
|
|
|
+ XFS_IFORK_ASIZE(ip) / sizeof(xfs_bmbt_rec_t);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -4057,7 +4081,7 @@ xfs_bmap_add_attrfork(
|
|
case XFS_DINODE_FMT_BTREE:
|
|
case XFS_DINODE_FMT_BTREE:
|
|
ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size);
|
|
ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size);
|
|
if (!ip->i_d.di_forkoff)
|
|
if (!ip->i_d.di_forkoff)
|
|
- ip->i_d.di_forkoff = mp->m_attroffset >> 3;
|
|
|
|
|
|
+ ip->i_d.di_forkoff = xfs_default_attroffset(ip) >> 3;
|
|
else if (mp->m_flags & XFS_MOUNT_ATTR2)
|
|
else if (mp->m_flags & XFS_MOUNT_ATTR2)
|
|
version = 2;
|
|
version = 2;
|
|
break;
|
|
break;
|
|
@@ -4204,12 +4228,12 @@ xfs_bmap_compute_maxlevels(
|
|
* (a signed 16-bit number, xfs_aextnum_t).
|
|
* (a signed 16-bit number, xfs_aextnum_t).
|
|
*
|
|
*
|
|
* Note that we can no longer assume that if we are in ATTR1 that
|
|
* Note that we can no longer assume that if we are in ATTR1 that
|
|
- * the fork offset of all the inodes will be (m_attroffset >> 3)
|
|
|
|
- * because we could have mounted with ATTR2 and then mounted back
|
|
|
|
- * with ATTR1, keeping the di_forkoff's fixed but probably at
|
|
|
|
- * various positions. Therefore, for both ATTR1 and ATTR2
|
|
|
|
- * we have to assume the worst case scenario of a minimum size
|
|
|
|
- * available.
|
|
|
|
|
|
+ * the fork offset of all the inodes will be
|
|
|
|
+ * (xfs_default_attroffset(ip) >> 3) because we could have mounted
|
|
|
|
+ * with ATTR2 and then mounted back with ATTR1, keeping the
|
|
|
|
+ * di_forkoff's fixed but probably at various positions. Therefore,
|
|
|
|
+ * for both ATTR1 and ATTR2 we have to assume the worst case scenario
|
|
|
|
+ * of a minimum size available.
|
|
*/
|
|
*/
|
|
if (whichfork == XFS_DATA_FORK) {
|
|
if (whichfork == XFS_DATA_FORK) {
|
|
maxleafents = MAXEXTNUM;
|
|
maxleafents = MAXEXTNUM;
|