xfs: make sure maxlen is still congruent with prod when rounding down
[platform/kernel/linux-starfive.git] / fs / xfs / xfs_rtalloc.c
index 31fd65b..0e4e2df 100644 (file)
@@ -212,6 +212,23 @@ xfs_rtallocate_range(
 }
 
 /*
+ * Make sure we don't run off the end of the rt volume.  Be careful that
+ * adjusting maxlen downwards doesn't cause us to fail the alignment checks.
+ */
+static inline xfs_extlen_t
+xfs_rtallocate_clamp_len(
+       struct xfs_mount        *mp,
+       xfs_rtblock_t           startrtx,
+       xfs_extlen_t            rtxlen,
+       xfs_extlen_t            prod)
+{
+       xfs_extlen_t            ret;
+
+       ret = min(mp->m_sb.sb_rextents, startrtx + rtxlen) - startrtx;
+       return rounddown(ret, prod);
+}
+
+/*
  * Attempt to allocate an extent minlen<=len<=maxlen starting from
  * bitmap block bbno.  If we don't get maxlen then use prod to trim
  * the length, if given.  Returns error; returns starting block in *rtblock.
@@ -248,7 +265,7 @@ xfs_rtallocate_extent_block(
             i <= end;
             i++) {
                /* Make sure we don't scan off the end of the rt volume. */
-               maxlen = min(mp->m_sb.sb_rextents, i + maxlen) - i;
+               maxlen = xfs_rtallocate_clamp_len(mp, i, maxlen, prod);
 
                /*
                 * See if there's a free extent of maxlen starting at i.
@@ -355,7 +372,8 @@ xfs_rtallocate_extent_exact(
        int             isfree;         /* extent is free */
        xfs_rtblock_t   next;           /* next block to try (dummy) */
 
-       ASSERT(minlen % prod == 0 && maxlen % prod == 0);
+       ASSERT(minlen % prod == 0);
+       ASSERT(maxlen % prod == 0);
        /*
         * Check if the range in question (for maxlen) is free.
         */
@@ -438,7 +456,9 @@ xfs_rtallocate_extent_near(
        xfs_rtblock_t   n;              /* next block to try */
        xfs_rtblock_t   r;              /* result block */
 
-       ASSERT(minlen % prod == 0 && maxlen % prod == 0);
+       ASSERT(minlen % prod == 0);
+       ASSERT(maxlen % prod == 0);
+
        /*
         * If the block number given is off the end, silently set it to
         * the last block.
@@ -447,7 +467,7 @@ xfs_rtallocate_extent_near(
                bno = mp->m_sb.sb_rextents - 1;
 
        /* Make sure we don't run off the end of the rt volume. */
-       maxlen = min(mp->m_sb.sb_rextents, bno + maxlen) - bno;
+       maxlen = xfs_rtallocate_clamp_len(mp, bno, maxlen, prod);
        if (maxlen < minlen) {
                *rtblock = NULLRTBLOCK;
                return 0;
@@ -638,7 +658,8 @@ xfs_rtallocate_extent_size(
        xfs_rtblock_t   r;              /* result block number */
        xfs_suminfo_t   sum;            /* summary information for extents */
 
-       ASSERT(minlen % prod == 0 && maxlen % prod == 0);
+       ASSERT(minlen % prod == 0);
+       ASSERT(maxlen % prod == 0);
        ASSERT(maxlen != 0);
 
        /*