[PATCH 4/5] xfs: correct the parent pointer space reservation comment

Javier Tia <[email protected]>
Newsgroups org.kernel.vger.linux-xfs,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
The comment on xfs_parent_calc_space_res() claims parent pointers are
"always the first attr in an attr tree".  They are not: a parent pointer
is recorded per dirent, so an inode with N hardlinks carries N of them,
and `xfs_io -c "parent -p"` on a 31-link file lists 31.  By the Nth link
the attr fork is in leaf or node format and the insert is not into a
fresh tree.

The reservation itself is fine, which is what makes the comment worth
fixing rather than the code.  XFS_DAENTER_SPACE_RES() reserves
XFS_DA_NODE_MAXDEPTH blocks plus a bmap allowance for each, i.e. enough
to split every level of a maximum-depth attr dabtree.  That depth is a
format ceiling, not a runtime property, so the result cannot depend on
the format the fork happens to be in.  Anyone auditing a reservation
shortfall here reads the comment, concludes the sizing rests on an
assumption that demonstrably does not hold, and goes looking for a bug
that is not there.

Record why no double split allowance is needed either, since that is one
of two visible differences from xfs_attr_calc_size() and is not obvious
from the expression: a parent pointer's name is a dirent name and its
value is a struct xfs_parent_rec, so the leaf entry is local and at most
round_up(3 + 255 + 12, 4) = 272 bytes.  Parent pointers require V5 and
therefore XFS_MIN_CRC_BLOCKSIZE, so the smallest half-block this can be
compared against is 512 and the double split branch is unreachable on
every mountable geometry.  Locality is decided against a different
threshold, xfs_attr_leaf_entsize_local_max() at three quarters of a
block, which the 272 bytes also clears.

Record the other difference too.  The second term hands a byte count to
XFS_NEXTENTADD_SPACE_RES(), whose parameter counts mappings, so it asks
for more extent-add allowance than the one mapping a parent pointer
adds.  The factor depends on the block size, because the macro divides
by XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(), so the comment says only that it
over-reserves - a patch whose whole point is that the old comment stated
a geometry-dependent thing as invariant should not do the same.  That it
over-reserves is why it is not a bug and why this patch leaves it alone.

Signed-off-by: Javier Tia <[email protected]>
---
 fs/xfs/libxfs/xfs_trans_space.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_trans_space.c b/fs/xfs/libxfs/xfs_trans_space.c
index 9b8f495c9049..c4cd547033e5 100644
--- a/fs/xfs/libxfs/xfs_trans_space.c
+++ b/fs/xfs/libxfs/xfs_trans_space.c
@@ -22,8 +22,23 @@ xfs_parent_calc_space_res(
 	unsigned int		namelen)
 {
 	/*
-	 * Parent pointers are always the first attr in an attr tree, and never
-	 * larger than a block
+	 * A parent pointer is recorded per dirent, so an inode with N links
+	 * carries N of them and the attr fork can already be in leaf or node
+	 * format when one is added.  That does not affect the reservation:
+	 * XFS_DAENTER_SPACE_RES covers a split at every level of a
+	 * maximum-depth attr dabtree, whatever format the fork is in now.
+	 *
+	 * The name is a dirent name and the value is a struct xfs_parent_rec,
+	 * so the leaf entry is always local and never exceeds 272 bytes.
+	 * Parent pointers require V5, hence a 1k minimum block size, so the
+	 * entry always stays under half a block and this needs none of the
+	 * double split allowance that xfs_attr_calc_size() makes.
+	 *
+	 * The second term hands a byte count to a macro whose parameter counts
+	 * mappings, so it asks for more extent-add allowance than the single
+	 * mapping a parent pointer adds - how much more depends on the block
+	 * size.  It over-reserves either way, which is why it is left alone:
+	 * correcting the unit would shrink a reservation that is only generous.
 	 */
 	return XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK) +
 	       XFS_NEXTENTADD_SPACE_RES(mp, namelen, XFS_ATTR_FORK);
-- 
Javier Tia
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.