[PATCH 4/7] xfs: Add "Use Dir BMBT height" argument to XFS_BM_MAXLEVELS()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



XFS_BM_MAXLEVELS() returns the maximum possible height of BMBT tree for
either data or attribute fork. For data forks, this commit adds a new
argument to XFS_BM_MAXLEVELS() to let the users choose between the
maximum heights of dir and non-dir BMBTs.

As of this commit, both dir and non-dir BMBTs have the same maximum
height. A future commit in this series will use 2^27 extent count as the
input to compute the maximum height of a directory BMBT which will in
turn cause the maximum heights of dir and non-dir BMBTs to differ.

Signed-off-by: Chandan Babu R <chandanrlinux@xxxxxxxxx>
---
 fs/xfs/libxfs/xfs_attr.c        |  5 ++--
 fs/xfs/libxfs/xfs_bmap.c        |  5 ++--
 fs/xfs/libxfs/xfs_bmap_btree.h  |  4 +++-
 fs/xfs/libxfs/xfs_trans_resv.c  | 25 +++++++++++---------
 fs/xfs/libxfs/xfs_trans_resv.h  |  4 ++--
 fs/xfs/libxfs/xfs_trans_space.h | 41 +++++++++++++++++----------------
 fs/xfs/xfs_bmap_item.c          |  3 ++-
 fs/xfs/xfs_reflink.c            |  4 ++--
 8 files changed, 50 insertions(+), 41 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index a4b23edf887e..357e29a5a167 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -150,7 +150,7 @@ xfs_attr_calc_size(
 	 * "local" or "remote" (note: local != inline).
 	 */
 	size = xfs_attr_leaf_newentsize(args, local);
-	nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
+	nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK, 0);
 	if (*local) {
 		if (size > (args->geo->blksize / 2)) {
 			/* Double split possible */
@@ -163,7 +163,8 @@ xfs_attr_calc_size(
 		 */
 		uint	dblocks = xfs_attr3_rmt_blocks(mp, args->valuelen);
 		nblks += dblocks;
-		nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
+		nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks,
+				XFS_ATTR_FORK, 0);
 	}
 
 	return nblks;
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 01e2b543b139..8b0029b3cecf 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -182,13 +182,14 @@ xfs_bmap_worst_indlen(
 	mp = ip->i_mount;
 	maxrecs = mp->m_bmap_dmxr[0];
 	for (level = 0, rval = 0;
-	     level < XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK);
+	     level < XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK, 0);
 	     level++) {
 		len += maxrecs - 1;
 		do_div(len, maxrecs);
 		rval += len;
 		if (len == 1)
-			return rval + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) -
+			return rval +
+				XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK, 0) -
 				level - 1;
 		if (level == 0)
 			maxrecs = mp->m_bmap_dmxr[1];
diff --git a/fs/xfs/libxfs/xfs_bmap_btree.h b/fs/xfs/libxfs/xfs_bmap_btree.h
index 72bf74c79fb9..a047be5883d1 100644
--- a/fs/xfs/libxfs/xfs_bmap_btree.h
+++ b/fs/xfs/libxfs/xfs_bmap_btree.h
@@ -79,7 +79,9 @@ struct xfs_trans;
 /*
  * Maximum number of bmap btree levels.
  */
-#define XFS_BM_MAXLEVELS(mp,w)		((mp)->m_bm_maxlevels[(w)])
+#define XFS_BM_MAXLEVELS(mp,w,use_dir_bmbt) \
+	((!(use_dir_bmbt)) ? \
+		(mp)->m_bm_maxlevels[(w)] : (mp)->m_bm_dir_maxlevel)
 
 /*
  * Prototypes for xfs_bmap.c to call.
diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c
index b44b521c605c..39cfca1b71b6 100644
--- a/fs/xfs/libxfs/xfs_trans_resv.c
+++ b/fs/xfs/libxfs/xfs_trans_resv.c
@@ -265,14 +265,14 @@ xfs_calc_write_reservation(
 	unsigned int		blksz = XFS_FSB_TO_B(mp, 1);
 
 	t1 = xfs_calc_inode_res(mp, 1) +
-	     xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), blksz) +
+	     xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK, 0), blksz) +
 	     xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) +
 	     xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), blksz);
 
 	if (xfs_sb_version_hasrealtime(&mp->m_sb)) {
 		t2 = xfs_calc_inode_res(mp, 1) +
-		     xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK),
-				     blksz) +
+		     xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK, 0),
+			blksz) +
 		     xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) +
 		     xfs_calc_buf_res(xfs_rtalloc_log_count(mp, 1), blksz) +
 		     xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), blksz);
@@ -313,7 +313,8 @@ xfs_calc_itruncate_reservation(
 	unsigned int		blksz = XFS_FSB_TO_B(mp, 1);
 
 	t1 = xfs_calc_inode_res(mp, 1) +
-	     xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1, blksz);
+	     xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK, 0) + 1,
+			     blksz);
 
 	t2 = xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) +
 	     xfs_calc_buf_res(xfs_allocfree_log_count(mp, 4), blksz);
@@ -592,7 +593,7 @@ xfs_calc_growrtalloc_reservation(
 	struct xfs_mount	*mp)
 {
 	return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
-		xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK),
+		xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK, 0),
 				 XFS_FSB_TO_B(mp, 1)) +
 		xfs_calc_inode_res(mp, 1) +
 		xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
@@ -669,7 +670,7 @@ xfs_calc_addafork_reservation(
 		xfs_calc_inode_res(mp, 1) +
 		xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
 		xfs_calc_buf_res(1, mp->m_dir_geo->blksize) +
-		xfs_calc_buf_res(XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1,
+		xfs_calc_buf_res(XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK, 0) + 1,
 				 XFS_FSB_TO_B(mp, 1)) +
 		xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
 				 XFS_FSB_TO_B(mp, 1));
@@ -691,7 +692,7 @@ xfs_calc_attrinval_reservation(
 	struct xfs_mount	*mp)
 {
 	return max((xfs_calc_inode_res(mp, 1) +
-		    xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK),
+		    xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK, 0),
 				     XFS_FSB_TO_B(mp, 1))),
 		   (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) +
 		    xfs_calc_buf_res(xfs_allocfree_log_count(mp, 4),
@@ -717,10 +718,11 @@ xfs_calc_attrset_reservation(
 	int			bmbt_blks;
 
 	da_blks = XFS_DAENTER_BLOCKS(mp, XFS_ATTR_FORK);
-	bmbt_blks = XFS_DAENTER_BMAPS(mp, XFS_ATTR_FORK);
+	bmbt_blks = XFS_DAENTER_BMAPS(mp, XFS_ATTR_FORK, 0);
 
 	max_rmt_blks = xfs_attr3_rmt_blocks(mp, XATTR_SIZE_MAX);
-	bmbt_blks += XFS_NEXTENTADD_SPACE_RES(mp, max_rmt_blks, XFS_ATTR_FORK);
+	bmbt_blks += XFS_NEXTENTADD_SPACE_RES(mp, max_rmt_blks,
+			XFS_ATTR_FORK, 0);
 
 	return XFS_DQUOT_LOGRES(mp) +
 		xfs_calc_inode_res(mp, 1) +
@@ -752,8 +754,9 @@ xfs_calc_attrrm_reservation(
 		     xfs_calc_buf_res(XFS_DA_NODE_MAXDEPTH,
 				      XFS_FSB_TO_B(mp, 1)) +
 		     (uint)XFS_FSB_TO_B(mp,
-					XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) +
-		     xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), 0)),
+				XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK, 0)) +
+		     xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK, 0),
+				     0)),
 		    (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) +
 		     xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2),
 				      XFS_FSB_TO_B(mp, 1))));
diff --git a/fs/xfs/libxfs/xfs_trans_resv.h b/fs/xfs/libxfs/xfs_trans_resv.h
index f50996ae18e6..d64989eeebd7 100644
--- a/fs/xfs/libxfs/xfs_trans_resv.h
+++ b/fs/xfs/libxfs/xfs_trans_resv.h
@@ -61,10 +61,10 @@ struct xfs_trans_resv {
  */
 #define	XFS_DIROP_LOG_RES(mp)	\
 	(XFS_FSB_TO_B(mp, XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK)) + \
-	 (XFS_FSB_TO_B(mp, XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1)))
+	 (XFS_FSB_TO_B(mp, XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK, 1) + 1)))
 #define	XFS_DIROP_LOG_COUNT(mp)	\
 	(XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \
-	 XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1)
+	 XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK, 1) + 1)
 
 /*
  * Various log count values.
diff --git a/fs/xfs/libxfs/xfs_trans_space.h b/fs/xfs/libxfs/xfs_trans_space.h
index b559af70cf51..c51d809a16b1 100644
--- a/fs/xfs/libxfs/xfs_trans_space.h
+++ b/fs/xfs/libxfs/xfs_trans_space.h
@@ -25,15 +25,16 @@
 
 #define XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp)    \
 		(((mp)->m_alloc_mxr[0]) - ((mp)->m_alloc_mnr[0]))
-#define	XFS_EXTENTADD_SPACE_RES(mp,w)	(XFS_BM_MAXLEVELS(mp,w) - 1)
-#define XFS_NEXTENTADD_SPACE_RES(mp,b,w)\
+#define	XFS_EXTENTADD_SPACE_RES(mp,w,dbmbt)	\
+	(XFS_BM_MAXLEVELS(mp,w,dbmbt) - 1)
+#define XFS_NEXTENTADD_SPACE_RES(mp,b,w,dbmbt)		   \
 	(((b + XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp) - 1) / \
 	  XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp)) * \
-	  XFS_EXTENTADD_SPACE_RES(mp,w))
+		XFS_EXTENTADD_SPACE_RES(mp,w,dbmbt))
 
 /* Blocks we might need to add "b" mappings & rmappings to a file. */
-#define XFS_SWAP_RMAP_SPACE_RES(mp,b,w)\
-	(XFS_NEXTENTADD_SPACE_RES((mp), (b), (w)) + \
+#define XFS_SWAP_RMAP_SPACE_RES(mp,b,w)	    \
+	(XFS_NEXTENTADD_SPACE_RES((mp), (b), (w), 0) +	\
 	 XFS_NRMAPADD_SPACE_RES((mp), (b)))
 
 #define	XFS_DAENTER_1B(mp,w)	\
@@ -47,19 +48,19 @@
 	(XFS_DA_NODE_MAXDEPTH + (((w) == XFS_DATA_FORK) ? 2 : 1))
 #define	XFS_DAENTER_BLOCKS(mp,w)	\
 	(XFS_DAENTER_1B(mp,w) * XFS_DAENTER_DBS(mp,w))
-#define	XFS_DAENTER_BMAP1B(mp,w)	\
-	XFS_NEXTENTADD_SPACE_RES(mp, XFS_DAENTER_1B(mp, w), w)
-#define	XFS_DAENTER_BMAPS(mp,w)		\
-	(XFS_DAENTER_DBS(mp,w) * XFS_DAENTER_BMAP1B(mp,w))
-#define	XFS_DAENTER_SPACE_RES(mp,w)	\
-	(XFS_DAENTER_BLOCKS(mp,w) + XFS_DAENTER_BMAPS(mp,w))
-#define	XFS_DAREMOVE_SPACE_RES(mp,w)	XFS_DAENTER_BMAPS(mp,w)
+#define	XFS_DAENTER_BMAP1B(mp,w,dbmbt)	\
+	XFS_NEXTENTADD_SPACE_RES(mp, XFS_DAENTER_1B(mp, w), w, dbmbt)
+#define	XFS_DAENTER_BMAPS(mp,w,dbmbt)	\
+	(XFS_DAENTER_DBS(mp,w) * XFS_DAENTER_BMAP1B(mp,w,dbmbt))
+#define	XFS_DAENTER_SPACE_RES(mp,w,dbmbt)	\
+	(XFS_DAENTER_BLOCKS(mp,w) + XFS_DAENTER_BMAPS(mp,w,dbmbt))
+#define	XFS_DAREMOVE_SPACE_RES(mp,w,dbmbt)	XFS_DAENTER_BMAPS(mp,w,dbmbt)
 #define	XFS_DIRENTER_MAX_SPLIT(mp,nl)	1
 #define	XFS_DIRENTER_SPACE_RES(mp,nl)	\
-	(XFS_DAENTER_SPACE_RES(mp, XFS_DATA_FORK) * \
+	(XFS_DAENTER_SPACE_RES(mp, XFS_DATA_FORK, 1) *	\
 	 XFS_DIRENTER_MAX_SPLIT(mp,nl))
 #define	XFS_DIRREMOVE_SPACE_RES(mp)	\
-	XFS_DAREMOVE_SPACE_RES(mp, XFS_DATA_FORK)
+	XFS_DAREMOVE_SPACE_RES(mp, XFS_DATA_FORK, 1)
 #define	XFS_IALLOC_SPACE_RES(mp)	\
 	(M_IGEO(mp)->ialloc_blks + \
 	 (xfs_sb_version_hasfinobt(&mp->m_sb) ? 2 : 1 * \
@@ -69,26 +70,26 @@
  * Space reservation values for various transactions.
  */
 #define	XFS_ADDAFORK_SPACE_RES(mp)	\
-	((mp)->m_dir_geo->fsbcount + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK))
+	((mp)->m_dir_geo->fsbcount + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK, 0))
 #define	XFS_ATTRRM_SPACE_RES(mp)	\
-	XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK)
+	XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK, 0)
 /* This macro is not used - see inline code in xfs_attr_set */
 #define	XFS_ATTRSET_SPACE_RES(mp, v)	\
-	(XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK) + XFS_B_TO_FSB(mp, v))
+	(XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK, 0) + XFS_B_TO_FSB(mp, v))
 #define	XFS_CREATE_SPACE_RES(mp,nl)	\
 	(XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl))
 #define	XFS_DIOSTRAT_SPACE_RES(mp, v)	\
-	(XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK) + (v))
+	(XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK, 0) + (v))
 #define	XFS_GROWFS_SPACE_RES(mp)	\
 	(2 * (mp)->m_ag_maxlevels)
 #define	XFS_GROWFSRT_SPACE_RES(mp,b)	\
-	((b) + XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK))
+	((b) + XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK, 0))
 #define	XFS_LINK_SPACE_RES(mp,nl)	\
 	XFS_DIRENTER_SPACE_RES(mp,nl)
 #define	XFS_MKDIR_SPACE_RES(mp,nl)	\
 	(XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl))
 #define	XFS_QM_DQALLOC_SPACE_RES(mp)	\
-	(XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK) + \
+	(XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK, 0) + \
 	 XFS_DQUOT_CLUSTER_SIZE_FSB)
 #define	XFS_QM_QINOCREATE_SPACE_RES(mp)	\
 	XFS_IALLOC_SPACE_RES(mp)
diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c
index 6736c5ab188f..0a8a8377a150 100644
--- a/fs/xfs/xfs_bmap_item.c
+++ b/fs/xfs/xfs_bmap_item.c
@@ -482,7 +482,8 @@ xfs_bui_item_recover(
 	}
 
 	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate,
-			XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK), 0, 0, &tp);
+			XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK, 0), 0,
+			0, &tp);
 	if (error)
 		return error;
 	/*
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index 107bf2a2f344..fd35a0bf2c47 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -614,7 +614,7 @@ xfs_reflink_end_cow_extent(
 		return 0;
 	}
 
-	resblks = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK);
+	resblks = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK, 0);
 	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0,
 			XFS_TRANS_RESERVE, &tp);
 	if (error)
@@ -1017,7 +1017,7 @@ xfs_reflink_remap_extent(
 	}
 
 	/* Start a rolling transaction to switch the mappings */
-	resblks = XFS_EXTENTADD_SPACE_RES(ip->i_mount, XFS_DATA_FORK);
+	resblks = XFS_EXTENTADD_SPACE_RES(ip->i_mount, XFS_DATA_FORK, 0);
 	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, 0, &tp);
 	if (error)
 		goto out;
-- 
2.20.1




[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux