summaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_trans_resv.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-11 18:03:47 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-11 18:03:47 +0200
commit412dd3a6daf0cadce1b2d6a34fa3713f40255579 (patch)
treebb2518c00c9d56acc8d36f87ed9c3144d8cf8201 /fs/xfs/xfs_trans_resv.c
parentMerge branch 'for-linus' of git://git.kernel.dk/linux-block (diff)
parentMerge branch 'xfs-misc-fixes-3-for-3.16' into for-next (diff)
downloadlinux-412dd3a6daf0cadce1b2d6a34fa3713f40255579.tar.xz
linux-412dd3a6daf0cadce1b2d6a34fa3713f40255579.zip
Merge tag 'xfs-for-linus-3.16-rc1' of git://oss.sgi.com/xfs/xfs
Pull xfs updates from Dave Chinner: "This update contains: - cleanup removing unused function args - rework of the filestreams allocator to use dentry cache parent lookups - new on-disk free inode btree and optimised inode allocator - various bug fixes - rework of internal attribute API - cleanup of superblock feature bit support to remove historic cruft - more fixes and minor cleanups - added a new directory/attribute geometry abstraction - yet more fixes and minor cleanups" * tag 'xfs-for-linus-3.16-rc1' of git://oss.sgi.com/xfs/xfs: (86 commits) xfs: fix xfs_da_args sparse warning in xfs_readdir xfs: Fix rounding in xfs_alloc_fix_len() xfs: tone down writepage/releasepage WARN_ONs xfs: small cleanup in xfs_lowbit64() xfs: kill xfs_buf_geterror() xfs: xfs_readsb needs to check for magic numbers xfs: block allocation work needs to be kswapd aware xfs: remove redundant geometry information from xfs_da_state xfs: replace attr LBSIZE with xfs_da_geometry xfs: pass xfs_da_args to xfs_attr_leaf_newentsize xfs: use xfs_da_geometry for block size in attr code xfs: remove mp->m_dir_geo from directory logging xfs: reduce direct usage of mp->m_dir_geo xfs: move node entry counts to xfs_da_geometry xfs: convert dir/attr btree threshold to xfs_da_geometry xfs: convert m_dirblksize to xfs_da_geometry xfs: convert m_dirblkfsbs to xfs_da_geometry xfs: convert directory segment limits to xfs_da_geometry xfs: convert directory db conversion to xfs_da_geometry xfs: convert directory dablk conversion to xfs_da_geometry ...
Diffstat (limited to 'fs/xfs/xfs_trans_resv.c')
-rw-r--r--fs/xfs/xfs_trans_resv.c56
1 files changed, 52 insertions, 4 deletions
diff --git a/fs/xfs/xfs_trans_resv.c b/fs/xfs/xfs_trans_resv.c
index ae368165244d..f2bda7c76b8a 100644
--- a/fs/xfs/xfs_trans_resv.c
+++ b/fs/xfs/xfs_trans_resv.c
@@ -26,6 +26,7 @@
#include "xfs_ag.h"
#include "xfs_mount.h"
#include "xfs_da_format.h"
+#include "xfs_da_btree.h"
#include "xfs_inode.h"
#include "xfs_bmap_btree.h"
#include "xfs_ialloc.h"
@@ -106,6 +107,47 @@ xfs_calc_inode_res(
}
/*
+ * 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.
*
* These are based on the size of the file system block because that is what
@@ -302,6 +344,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 +353,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 +392,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 +402,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 +471,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 +486,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);
}
/*
@@ -562,7 +610,7 @@ xfs_calc_addafork_reservation(
return XFS_DQUOT_LOGRES(mp) +
xfs_calc_inode_res(mp, 1) +
xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
- xfs_calc_buf_res(1, mp->m_dirblksize) +
+ xfs_calc_buf_res(1, mp->m_dir_geo->blksize) +
xfs_calc_buf_res(XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1,
XFS_FSB_TO_B(mp, 1)) +
xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),