xfs: Inode create transaction reservations

Define the log and space transaction sizes. Factor the current
create log reservation macro into the two logical halves and reuse
one half for the new icreate transactions. The icreate transaction
is transparent to all the high level create code - the
pre-calculated reservations will correctly set the reservations
dependent on whether the filesystem supports the icreate
transaction.

Signed-off-by: Dave Chinner <david@fromorbit.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
This commit is contained in:
Dave Chinner 2013-06-27 16:04:54 +10:00 committed by Ben Myers
parent 3ebe7d2d73
commit b8402b4729
1 changed files with 81 additions and 45 deletions

View File

@ -234,37 +234,10 @@ xfs_calc_remove_reservation(
} }
/* /*
* For symlink we can modify: * For create, break it in to the two cases that the transaction
* the parent directory inode: inode size * covers. We start with the modify case - allocation done by modification
* the new inode: inode size * of the state of existing inodes - and the allocation case.
* the inode btree entry: 1 block
* 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:
* the agi and agf of the ag getting the new inodes: 2 * sectorsize
* 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
*/ */
STATIC uint
xfs_calc_symlink_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))));
}
/* /*
* For create we can modify: * For create we can modify:
@ -274,7 +247,19 @@ xfs_calc_symlink_reservation(
* the superblock for the nlink flag: sector size * the superblock for the nlink flag: sector size
* the directory btree: (max depth + v2) * dir block size * the directory btree: (max depth + v2) * dir block size
* the directory inode's bmap btree: (max depth + v2) * block size * the directory inode's bmap btree: (max depth + v2) * block size
* 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 agi and agf of the ag getting the new inodes: 2 * sectorsize
* the superblock for the nlink flag: sector size * the superblock for the nlink flag: sector size
* the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
@ -282,23 +267,60 @@ xfs_calc_symlink_reservation(
* the allocation btrees: 2 trees * (max depth - 1) * block size * the allocation btrees: 2 trees * (max depth - 1) * block size
*/ */
STATIC uint STATIC uint
xfs_calc_create_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) struct xfs_mount *mp)
{ {
return XFS_DQUOT_LOGRES(mp) + return XFS_DQUOT_LOGRES(mp) +
MAX((xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) + MAX(xfs_calc_create_resv_alloc(mp),
xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + xfs_calc_create_resv_modify(mp));
(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) + * For icreate we can allocate some inodes giving:
mp->m_sb.sb_sectsize + * the agi and agf of the ag getting the new inodes: 2 * sectorsize
xfs_calc_buf_res(XFS_IALLOC_BLOCKS(mp), * the superblock for the nlink flag: sector size
XFS_FSB_TO_B(mp, 1)) + * the inode btree: max depth * blocksize
xfs_calc_buf_res(mp->m_in_maxlevels, * the allocation btrees: 2 trees * (max depth - 1) * block size
XFS_FSB_TO_B(mp, 1)) + */
xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), STATIC uint
XFS_FSB_TO_B(mp, 1)))); 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_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); 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: * In freeing an inode we can modify:
* the inode being freed: inode size * the inode being freed: inode size