Commit fd26a880 authored by Darrick J. Wong's avatar Darrick J. Wong Committed by Dave Chinner

xfs: factor rmap btree size into the indlen calculations

When we're estimating the amount of space it's going to take to satisfy
a delalloc reservation, we need to include the space that we might need
to grow the rmapbt.  This helps us to avoid running out of space later
when _iomap_write_allocate needs more space than we reserved.  Eryu Guan
observed this happening on generic/224 when sunit/swidth were set.
Reported-by: default avatarEryu Guan <eguan@redhat.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
parent 1247ec4c
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include "xfs_rmap.h" #include "xfs_rmap.h"
#include "xfs_ag_resv.h" #include "xfs_ag_resv.h"
#include "xfs_refcount.h" #include "xfs_refcount.h"
#include "xfs_rmap_btree.h"
kmem_zone_t *xfs_bmap_free_item_zone; kmem_zone_t *xfs_bmap_free_item_zone;
...@@ -190,8 +191,12 @@ xfs_bmap_worst_indlen( ...@@ -190,8 +191,12 @@ xfs_bmap_worst_indlen(
int maxrecs; /* maximum record count at this level */ int maxrecs; /* maximum record count at this level */
xfs_mount_t *mp; /* mount structure */ xfs_mount_t *mp; /* mount structure */
xfs_filblks_t rval; /* return value */ xfs_filblks_t rval; /* return value */
xfs_filblks_t orig_len;
mp = ip->i_mount; mp = ip->i_mount;
/* Calculate the worst-case size of the bmbt. */
orig_len = len;
maxrecs = mp->m_bmap_dmxr[0]; maxrecs = mp->m_bmap_dmxr[0];
for (level = 0, rval = 0; for (level = 0, rval = 0;
level < XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK); level < XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK);
...@@ -199,12 +204,20 @@ xfs_bmap_worst_indlen( ...@@ -199,12 +204,20 @@ xfs_bmap_worst_indlen(
len += maxrecs - 1; len += maxrecs - 1;
do_div(len, maxrecs); do_div(len, maxrecs);
rval += len; rval += len;
if (len == 1) if (len == 1) {
return rval + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - rval += XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) -
level - 1; level - 1;
break;
}
if (level == 0) if (level == 0)
maxrecs = mp->m_bmap_dmxr[1]; maxrecs = mp->m_bmap_dmxr[1];
} }
/* Calculate the worst-case size of the rmapbt. */
if (xfs_sb_version_hasrmapbt(&mp->m_sb))
rval += 1 + xfs_rmapbt_calc_size(mp, orig_len) +
mp->m_rmap_maxlevels;
return rval; return rval;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment