|
@@ -105,6 +105,47 @@ xfs_calc_inode_res(
|
|
|
2 * XFS_BMBT_BLOCK_LEN(mp));
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * The free inode btree is a conditional feature and the log reservation
|
|
|
+ * requirements differ slightly from that of the traditional inode allocation
|
|
|
+ * btree. The finobt tracks records for inode chunks with at least one free
|
|
|
+ * inode. A record can be removed from the tree for an inode allocation
|
|
|
+ * or free and thus the finobt reservation is unconditional across:
|
|
|
+ *
|
|
|
+ * - inode allocation
|
|
|
+ * - inode free
|
|
|
+ * - inode chunk allocation
|
|
|
+ *
|
|
|
+ * The 'modify' param indicates to include the record modification scenario. The
|
|
|
+ * 'alloc' param indicates to include the reservation for free space btree
|
|
|
+ * modifications on behalf of finobt modifications. This is required only for
|
|
|
+ * transactions that do not already account for free space btree modifications.
|
|
|
+ *
|
|
|
+ * the free inode btree: max depth * block size
|
|
|
+ * the allocation btrees: 2 trees * (max depth - 1) * block size
|
|
|
+ * the free inode btree entry: block size
|
|
|
+ */
|
|
|
+STATIC uint
|
|
|
+xfs_calc_finobt_res(
|
|
|
+ struct xfs_mount *mp,
|
|
|
+ int alloc,
|
|
|
+ int modify)
|
|
|
+{
|
|
|
+ uint res;
|
|
|
+
|
|
|
+ if (!xfs_sb_version_hasfinobt(&mp->m_sb))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ res = xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1));
|
|
|
+ if (alloc)
|
|
|
+ res += xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
|
|
|
+ XFS_FSB_TO_B(mp, 1));
|
|
|
+ if (modify)
|
|
|
+ res += (uint)XFS_FSB_TO_B(mp, 1);
|
|
|
+
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Various log reservation values.
|
|
|
*
|
|
@@ -302,6 +343,7 @@ xfs_calc_remove_reservation(
|
|
|
* the superblock for the nlink flag: sector size
|
|
|
* the directory btree: (max depth + v2) * dir block size
|
|
|
* the directory inode's bmap btree: (max depth + v2) * block size
|
|
|
+ * the finobt (record modification and allocation btrees)
|
|
|
*/
|
|
|
STATIC uint
|
|
|
xfs_calc_create_resv_modify(
|
|
@@ -310,7 +352,8 @@ xfs_calc_create_resv_modify(
|
|
|
return xfs_calc_inode_res(mp, 2) +
|
|
|
xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
|
|
|
(uint)XFS_FSB_TO_B(mp, 1) +
|
|
|
- xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1));
|
|
|
+ xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1)) +
|
|
|
+ xfs_calc_finobt_res(mp, 1, 1);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -348,6 +391,7 @@ __xfs_calc_create_reservation(
|
|
|
* the superblock for the nlink flag: sector size
|
|
|
* the inode btree: max depth * blocksize
|
|
|
* the allocation btrees: 2 trees * (max depth - 1) * block size
|
|
|
+ * the finobt (record insertion)
|
|
|
*/
|
|
|
STATIC uint
|
|
|
xfs_calc_icreate_resv_alloc(
|
|
@@ -357,7 +401,8 @@ xfs_calc_icreate_resv_alloc(
|
|
|
mp->m_sb.sb_sectsize +
|
|
|
xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) +
|
|
|
xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
|
|
|
- XFS_FSB_TO_B(mp, 1));
|
|
|
+ XFS_FSB_TO_B(mp, 1)) +
|
|
|
+ xfs_calc_finobt_res(mp, 0, 0);
|
|
|
}
|
|
|
|
|
|
STATIC uint
|
|
@@ -425,6 +470,7 @@ xfs_calc_symlink_reservation(
|
|
|
* the on disk inode before ours in the agi hash list: inode cluster size
|
|
|
* the inode btree: max depth * blocksize
|
|
|
* the allocation btrees: 2 trees * (max depth - 1) * block size
|
|
|
+ * the finobt (record insertion, removal or modification)
|
|
|
*/
|
|
|
STATIC uint
|
|
|
xfs_calc_ifree_reservation(
|
|
@@ -439,7 +485,8 @@ xfs_calc_ifree_reservation(
|
|
|
xfs_calc_buf_res(2 + mp->m_ialloc_blks +
|
|
|
mp->m_in_maxlevels, 0) +
|
|
|
xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
|
|
|
- XFS_FSB_TO_B(mp, 1));
|
|
|
+ XFS_FSB_TO_B(mp, 1)) +
|
|
|
+ xfs_calc_finobt_res(mp, 0, 1);
|
|
|
}
|
|
|
|
|
|
/*
|