|
@@ -234,71 +234,93 @@ xfs_calc_remove_reservation(
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * For symlink we can modify:
|
|
|
+ * For create, break it in to the two cases that the transaction
|
|
|
+ * covers. We start with the modify case - allocation done by modification
|
|
|
+ * of the state of existing inodes - and the allocation case.
|
|
|
+ */
|
|
|
+
|
|
|
+/*
|
|
|
+ * For create we can modify:
|
|
|
* the parent directory inode: inode size
|
|
|
* the new inode: inode size
|
|
|
- * the inode btree entry: 1 block
|
|
|
+ * the inode btree entry: block size
|
|
|
+ * 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 blocks for the symlink: 1 kB
|
|
|
- * Or in the first xact we allocate some inodes giving:
|
|
|
+ */
|
|
|
+STATIC uint
|
|
|
+xfs_calc_create_resv_modify(
|
|
|
+ struct xfs_mount *mp)
|
|
|
+{
|
|
|
+ return xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) +
|
|
|
+ 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));
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * For create we can allocate some inodes giving:
|
|
|
* the agi and agf of the ag getting the new inodes: 2 * sectorsize
|
|
|
+ * the superblock for the nlink flag: sector size
|
|
|
* the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
|
|
|
* the inode btree: max depth * blocksize
|
|
|
- * the allocation btrees: 2 trees * (2 * max depth - 1) * block size
|
|
|
+ * the allocation btrees: 2 trees * (max depth - 1) * block size
|
|
|
*/
|
|
|
STATIC uint
|
|
|
-xfs_calc_symlink_reservation(
|
|
|
+xfs_calc_create_resv_alloc(
|
|
|
+ struct xfs_mount *mp)
|
|
|
+{
|
|
|
+ return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
|
|
|
+ mp->m_sb.sb_sectsize +
|
|
|
+ xfs_calc_buf_res(XFS_IALLOC_BLOCKS(mp), XFS_FSB_TO_B(mp, 1)) +
|
|
|
+ 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));
|
|
|
+}
|
|
|
+
|
|
|
+STATIC uint
|
|
|
+__xfs_calc_create_reservation(
|
|
|
struct xfs_mount *mp)
|
|
|
{
|
|
|
return XFS_DQUOT_LOGRES(mp) +
|
|
|
- MAX((xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) +
|
|
|
- xfs_calc_buf_res(1, 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(1, 1024)),
|
|
|
- (xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
|
|
|
- xfs_calc_buf_res(XFS_IALLOC_BLOCKS(mp),
|
|
|
- XFS_FSB_TO_B(mp, 1)) +
|
|
|
- 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))));
|
|
|
+ MAX(xfs_calc_create_resv_alloc(mp),
|
|
|
+ xfs_calc_create_resv_modify(mp));
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * For create we can modify:
|
|
|
- * the parent directory inode: inode size
|
|
|
- * the new inode: inode size
|
|
|
- * the inode btree entry: block size
|
|
|
- * 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
|
|
|
- * Or in the first xact we allocate some inodes giving:
|
|
|
+ * For icreate we can allocate some inodes giving:
|
|
|
* the agi and agf of the ag getting the new inodes: 2 * sectorsize
|
|
|
* the superblock for the nlink flag: sector size
|
|
|
- * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
|
|
|
* the inode btree: max depth * blocksize
|
|
|
* the allocation btrees: 2 trees * (max depth - 1) * block size
|
|
|
*/
|
|
|
STATIC uint
|
|
|
-xfs_calc_create_reservation(
|
|
|
+xfs_calc_icreate_resv_alloc(
|
|
|
struct xfs_mount *mp)
|
|
|
+{
|
|
|
+ return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
|
|
|
+ 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));
|
|
|
+}
|
|
|
+
|
|
|
+STATIC uint
|
|
|
+xfs_calc_icreate_reservation(xfs_mount_t *mp)
|
|
|
{
|
|
|
return XFS_DQUOT_LOGRES(mp) +
|
|
|
- MAX((xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) +
|
|
|
- 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(2, mp->m_sb.sb_sectsize) +
|
|
|
- mp->m_sb.sb_sectsize +
|
|
|
- xfs_calc_buf_res(XFS_IALLOC_BLOCKS(mp),
|
|
|
- XFS_FSB_TO_B(mp, 1)) +
|
|
|
- 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))));
|
|
|
+ MAX(xfs_calc_icreate_resv_alloc(mp),
|
|
|
+ xfs_calc_create_resv_modify(mp));
|
|
|
+}
|
|
|
+
|
|
|
+STATIC uint
|
|
|
+xfs_calc_create_reservation(
|
|
|
+ struct xfs_mount *mp)
|
|
|
+{
|
|
|
+ if (xfs_sb_version_hascrc(&mp->m_sb))
|
|
|
+ return xfs_calc_icreate_reservation(mp);
|
|
|
+ return __xfs_calc_create_reservation(mp);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -311,6 +333,20 @@ xfs_calc_mkdir_reservation(
|
|
|
return xfs_calc_create_reservation(mp);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+/*
|
|
|
+ * Making a new symplink is the same as creating a new file, but
|
|
|
+ * with the added blocks for remote symlink data which can be up to 1kB in
|
|
|
+ * length (MAXPATHLEN).
|
|
|
+ */
|
|
|
+STATIC uint
|
|
|
+xfs_calc_symlink_reservation(
|
|
|
+ struct xfs_mount *mp)
|
|
|
+{
|
|
|
+ return xfs_calc_create_reservation(mp) +
|
|
|
+ xfs_calc_buf_res(1, MAXPATHLEN);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* In freeing an inode we can modify:
|
|
|
* the inode being freed: inode size
|