Commit 9d4ca5af authored by Chandan Babu R's avatar Chandan Babu R

Merge tag 'refactor-rt-unit-conversions-6.7_2023-10-19' of...

Merge tag 'refactor-rt-unit-conversions-6.7_2023-10-19' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux into xfs-6.7-mergeA

xfs: refactor rt extent unit conversions [v1.1]

This series replaces all the open-coded integer division and
multiplication conversions between rt blocks and rt extents with calls
to static inline helpers.  Having cleaned all that up, the helpers are
augmented to skip the expensive operations in favor of bit shifts and
masking if the rt extent size is a power of two.

v1.1: various cleanups suggested by hch

With a bit of luck, this should all go splendidly.
Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarChandan Babu R <chandanbabu@kernel.org>

* tag 'refactor-rt-unit-conversions-6.7_2023-10-19' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux:
  xfs: use shifting and masking when converting rt extents, if possible
  xfs: create rt extent rounding helpers for realtime extent blocks
  xfs: convert do_div calls to xfs_rtb_to_rtx helper calls
  xfs: create helpers to convert rt block numbers to rt extent numbers
  xfs: create a helper to convert extlen to rtextlen
  xfs: create a helper to compute leftovers of realtime extents
  xfs: create a helper to convert rtextents to rtblocks
parents 3ef52c01 ef5a83b7
...@@ -2989,7 +2989,7 @@ xfs_bmap_extsize_align( ...@@ -2989,7 +2989,7 @@ xfs_bmap_extsize_align(
* If realtime, and the result isn't a multiple of the realtime * If realtime, and the result isn't a multiple of the realtime
* extent size we need to remove blocks until it is. * extent size we need to remove blocks until it is.
*/ */
if (rt && (temp = (align_alen % mp->m_sb.sb_rextsize))) { if (rt && (temp = xfs_extlen_to_rtxmod(mp, align_alen))) {
/* /*
* We're not covering the original request, or * We're not covering the original request, or
* we won't be able to once we fix the length. * we won't be able to once we fix the length.
...@@ -3016,7 +3016,7 @@ xfs_bmap_extsize_align( ...@@ -3016,7 +3016,7 @@ xfs_bmap_extsize_align(
else { else {
align_alen -= orig_off - align_off; align_alen -= orig_off - align_off;
align_off = orig_off; align_off = orig_off;
align_alen -= align_alen % mp->m_sb.sb_rextsize; align_alen -= xfs_extlen_to_rtxmod(mp, align_alen);
} }
/* /*
* Result doesn't cover the request, fail it. * Result doesn't cover the request, fail it.
...@@ -4826,12 +4826,8 @@ xfs_bmap_del_extent_delay( ...@@ -4826,12 +4826,8 @@ xfs_bmap_del_extent_delay(
ASSERT(got->br_startoff <= del->br_startoff); ASSERT(got->br_startoff <= del->br_startoff);
ASSERT(got_endoff >= del_endoff); ASSERT(got_endoff >= del_endoff);
if (isrt) { if (isrt)
uint64_t rtexts = del->br_blockcount; xfs_mod_frextents(mp, xfs_rtb_to_rtx(mp, del->br_blockcount));
do_div(rtexts, mp->m_sb.sb_rextsize);
xfs_mod_frextents(mp, rtexts);
}
/* /*
* Update the inode delalloc counter now and wait to update the * Update the inode delalloc counter now and wait to update the
...@@ -5276,7 +5272,6 @@ __xfs_bunmapi( ...@@ -5276,7 +5272,6 @@ __xfs_bunmapi(
int tmp_logflags; /* partial logging flags */ int tmp_logflags; /* partial logging flags */
int wasdel; /* was a delayed alloc extent */ int wasdel; /* was a delayed alloc extent */
int whichfork; /* data or attribute fork */ int whichfork; /* data or attribute fork */
xfs_fsblock_t sum;
xfs_filblks_t len = *rlen; /* length to unmap in file */ xfs_filblks_t len = *rlen; /* length to unmap in file */
xfs_fileoff_t end; xfs_fileoff_t end;
struct xfs_iext_cursor icur; struct xfs_iext_cursor icur;
...@@ -5371,8 +5366,8 @@ __xfs_bunmapi( ...@@ -5371,8 +5366,8 @@ __xfs_bunmapi(
if (!isrt) if (!isrt)
goto delete; goto delete;
sum = del.br_startblock + del.br_blockcount; mod = xfs_rtb_to_rtxoff(mp,
div_u64_rem(sum, mp->m_sb.sb_rextsize, &mod); del.br_startblock + del.br_blockcount);
if (mod) { if (mod) {
/* /*
* Realtime extent not lined up at the end. * Realtime extent not lined up at the end.
...@@ -5419,7 +5414,8 @@ __xfs_bunmapi( ...@@ -5419,7 +5414,8 @@ __xfs_bunmapi(
goto error0; goto error0;
goto nodelete; goto nodelete;
} }
div_u64_rem(del.br_startblock, mp->m_sb.sb_rextsize, &mod);
mod = xfs_rtb_to_rtxoff(mp, del.br_startblock);
if (mod) { if (mod) {
xfs_extlen_t off = mp->m_sb.sb_rextsize - mod; xfs_extlen_t off = mp->m_sb.sb_rextsize - mod;
......
...@@ -1024,13 +1024,13 @@ xfs_rtfree_blocks( ...@@ -1024,13 +1024,13 @@ xfs_rtfree_blocks(
ASSERT(rtlen <= XFS_MAX_BMBT_EXTLEN); ASSERT(rtlen <= XFS_MAX_BMBT_EXTLEN);
len = div_u64_rem(rtlen, mp->m_sb.sb_rextsize, &mod); len = xfs_rtb_to_rtxrem(mp, rtlen, &mod);
if (mod) { if (mod) {
ASSERT(mod == 0); ASSERT(mod == 0);
return -EIO; return -EIO;
} }
start = div_u64_rem(rtbno, mp->m_sb.sb_rextsize, &mod); start = xfs_rtb_to_rtxrem(mp, rtbno, &mod);
if (mod) { if (mod) {
ASSERT(mod == 0); ASSERT(mod == 0);
return -EIO; return -EIO;
......
...@@ -6,6 +6,131 @@ ...@@ -6,6 +6,131 @@
#ifndef __XFS_RTBITMAP_H__ #ifndef __XFS_RTBITMAP_H__
#define __XFS_RTBITMAP_H__ #define __XFS_RTBITMAP_H__
static inline xfs_rtblock_t
xfs_rtx_to_rtb(
struct xfs_mount *mp,
xfs_rtxnum_t rtx)
{
if (mp->m_rtxblklog >= 0)
return rtx << mp->m_rtxblklog;
return rtx * mp->m_sb.sb_rextsize;
}
static inline xfs_extlen_t
xfs_rtxlen_to_extlen(
struct xfs_mount *mp,
xfs_rtxlen_t rtxlen)
{
if (mp->m_rtxblklog >= 0)
return rtxlen << mp->m_rtxblklog;
return rtxlen * mp->m_sb.sb_rextsize;
}
/* Compute the misalignment between an extent length and a realtime extent .*/
static inline unsigned int
xfs_extlen_to_rtxmod(
struct xfs_mount *mp,
xfs_extlen_t len)
{
if (mp->m_rtxblklog >= 0)
return len & mp->m_rtxblkmask;
return len % mp->m_sb.sb_rextsize;
}
static inline xfs_rtxlen_t
xfs_extlen_to_rtxlen(
struct xfs_mount *mp,
xfs_extlen_t len)
{
if (mp->m_rtxblklog >= 0)
return len >> mp->m_rtxblklog;
return len / mp->m_sb.sb_rextsize;
}
/* Convert an rt block number into an rt extent number. */
static inline xfs_rtxnum_t
xfs_rtb_to_rtx(
struct xfs_mount *mp,
xfs_rtblock_t rtbno)
{
if (likely(mp->m_rtxblklog >= 0))
return rtbno >> mp->m_rtxblklog;
return div_u64(rtbno, mp->m_sb.sb_rextsize);
}
/* Return the offset of an rt block number within an rt extent. */
static inline xfs_extlen_t
xfs_rtb_to_rtxoff(
struct xfs_mount *mp,
xfs_rtblock_t rtbno)
{
if (likely(mp->m_rtxblklog >= 0))
return rtbno & mp->m_rtxblkmask;
return do_div(rtbno, mp->m_sb.sb_rextsize);
}
/*
* Crack an rt block number into an rt extent number and an offset within that
* rt extent. Returns the rt extent number directly and the offset in @off.
*/
static inline xfs_rtxnum_t
xfs_rtb_to_rtxrem(
struct xfs_mount *mp,
xfs_rtblock_t rtbno,
xfs_extlen_t *off)
{
if (likely(mp->m_rtxblklog >= 0)) {
*off = rtbno & mp->m_rtxblkmask;
return rtbno >> mp->m_rtxblklog;
}
return div_u64_rem(rtbno, mp->m_sb.sb_rextsize, off);
}
/*
* Convert an rt block number into an rt extent number, rounding up to the next
* rt extent if the rt block is not aligned to an rt extent boundary.
*/
static inline xfs_rtxnum_t
xfs_rtb_to_rtxup(
struct xfs_mount *mp,
xfs_rtblock_t rtbno)
{
if (likely(mp->m_rtxblklog >= 0)) {
if (rtbno & mp->m_rtxblkmask)
return (rtbno >> mp->m_rtxblklog) + 1;
return rtbno >> mp->m_rtxblklog;
}
if (do_div(rtbno, mp->m_sb.sb_rextsize))
rtbno++;
return rtbno;
}
/* Round this rtblock up to the nearest rt extent size. */
static inline xfs_rtblock_t
xfs_rtb_roundup_rtx(
struct xfs_mount *mp,
xfs_rtblock_t rtbno)
{
return roundup_64(rtbno, mp->m_sb.sb_rextsize);
}
/* Round this rtblock down to the nearest rt extent size. */
static inline xfs_rtblock_t
xfs_rtb_rounddown_rtx(
struct xfs_mount *mp,
xfs_rtblock_t rtbno)
{
return rounddown_64(rtbno, mp->m_sb.sb_rextsize);
}
/* /*
* Functions for walking free space rtextents in the realtime bitmap. * Functions for walking free space rtextents in the realtime bitmap.
*/ */
......
...@@ -975,6 +975,8 @@ xfs_sb_mount_common( ...@@ -975,6 +975,8 @@ xfs_sb_mount_common(
mp->m_blockmask = sbp->sb_blocksize - 1; mp->m_blockmask = sbp->sb_blocksize - 1;
mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG; mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
mp->m_blockwmask = mp->m_blockwsize - 1; mp->m_blockwmask = mp->m_blockwsize - 1;
mp->m_rtxblklog = log2_if_power2(sbp->sb_rextsize);
mp->m_rtxblkmask = mask64_if_power2(sbp->sb_rextsize);
mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1); mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1);
mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0); mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0);
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "xfs_trans.h" #include "xfs_trans.h"
#include "xfs_qm.h" #include "xfs_qm.h"
#include "xfs_trans_space.h" #include "xfs_trans_space.h"
#include "xfs_rtbitmap.h"
#define _ALLOC true #define _ALLOC true
#define _FREE false #define _FREE false
...@@ -220,7 +221,7 @@ xfs_rtalloc_block_count( ...@@ -220,7 +221,7 @@ xfs_rtalloc_block_count(
unsigned int blksz = XFS_FSB_TO_B(mp, 1); unsigned int blksz = XFS_FSB_TO_B(mp, 1);
unsigned int rtbmp_bytes; unsigned int rtbmp_bytes;
rtbmp_bytes = (XFS_MAX_BMBT_EXTLEN / mp->m_sb.sb_rextsize) / NBBY; rtbmp_bytes = xfs_extlen_to_rtxlen(mp, XFS_MAX_BMBT_EXTLEN) / NBBY;
return (howmany(rtbmp_bytes, blksz) + 1) * num_ops; return (howmany(rtbmp_bytes, blksz) + 1) * num_ops;
} }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "xfs_reflink.h" #include "xfs_reflink.h"
#include "xfs_rmap.h" #include "xfs_rmap.h"
#include "xfs_bmap_util.h" #include "xfs_bmap_util.h"
#include "xfs_rtbitmap.h"
#include "scrub/scrub.h" #include "scrub/scrub.h"
#include "scrub/common.h" #include "scrub/common.h"
#include "scrub/btree.h" #include "scrub/btree.h"
...@@ -225,7 +226,7 @@ xchk_inode_extsize( ...@@ -225,7 +226,7 @@ xchk_inode_extsize(
*/ */
if ((flags & XFS_DIFLAG_RTINHERIT) && if ((flags & XFS_DIFLAG_RTINHERIT) &&
(flags & XFS_DIFLAG_EXTSZINHERIT) && (flags & XFS_DIFLAG_EXTSZINHERIT) &&
value % sc->mp->m_sb.sb_rextsize > 0) xfs_extlen_to_rtxmod(sc->mp, value) > 0)
xchk_ino_set_warning(sc, ino); xchk_ino_set_warning(sc, ino);
} }
......
...@@ -50,8 +50,8 @@ xchk_rtbitmap_rec( ...@@ -50,8 +50,8 @@ xchk_rtbitmap_rec(
xfs_rtblock_t startblock; xfs_rtblock_t startblock;
xfs_filblks_t blockcount; xfs_filblks_t blockcount;
startblock = rec->ar_startext * mp->m_sb.sb_rextsize; startblock = xfs_rtx_to_rtb(mp, rec->ar_startext);
blockcount = rec->ar_extcount * mp->m_sb.sb_rextsize; blockcount = xfs_rtx_to_rtb(mp, rec->ar_extcount);
if (!xfs_verify_rtbext(mp, startblock, blockcount)) if (!xfs_verify_rtbext(mp, startblock, blockcount))
xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
...@@ -128,26 +128,22 @@ xchk_rtbitmap( ...@@ -128,26 +128,22 @@ xchk_rtbitmap(
void void
xchk_xref_is_used_rt_space( xchk_xref_is_used_rt_space(
struct xfs_scrub *sc, struct xfs_scrub *sc,
xfs_rtblock_t fsbno, xfs_rtblock_t rtbno,
xfs_extlen_t len) xfs_extlen_t len)
{ {
xfs_rtxnum_t startext; xfs_rtxnum_t startext;
xfs_rtxnum_t endext; xfs_rtxnum_t endext;
xfs_rtxlen_t extcount;
bool is_free; bool is_free;
int error; int error;
if (xchk_skip_xref(sc->sm)) if (xchk_skip_xref(sc->sm))
return; return;
startext = fsbno; startext = xfs_rtb_to_rtx(sc->mp, rtbno);
endext = fsbno + len - 1; endext = xfs_rtb_to_rtx(sc->mp, rtbno + len - 1);
do_div(startext, sc->mp->m_sb.sb_rextsize);
do_div(endext, sc->mp->m_sb.sb_rextsize);
extcount = endext - startext + 1;
xfs_ilock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP); xfs_ilock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
error = xfs_rtalloc_extent_is_free(sc->mp, sc->tp, startext, extcount, error = xfs_rtalloc_extent_is_free(sc->mp, sc->tp, startext,
&is_free); endext - startext + 1, &is_free);
if (!xchk_should_check_xref(sc, &error, NULL)) if (!xchk_should_check_xref(sc, &error, NULL))
goto out_unlock; goto out_unlock;
if (is_free) if (is_free)
......
...@@ -134,8 +134,8 @@ xchk_rtsum_record_free( ...@@ -134,8 +134,8 @@ xchk_rtsum_record_free(
lenlog = XFS_RTBLOCKLOG(rec->ar_extcount); lenlog = XFS_RTBLOCKLOG(rec->ar_extcount);
offs = XFS_SUMOFFS(mp, lenlog, rbmoff); offs = XFS_SUMOFFS(mp, lenlog, rbmoff);
rtbno = rec->ar_startext * mp->m_sb.sb_rextsize; rtbno = xfs_rtx_to_rtb(mp, rec->ar_startext);
rtlen = rec->ar_extcount * mp->m_sb.sb_rextsize; rtlen = xfs_rtx_to_rtb(mp, rec->ar_extcount);
if (!xfs_verify_rtbext(mp, rtbno, rtlen)) { if (!xfs_verify_rtbext(mp, rtbno, rtlen)) {
xchk_ino_xref_set_corrupt(sc, mp->m_rbmip->i_ino); xchk_ino_xref_set_corrupt(sc, mp->m_rbmip->i_ino);
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "xfs_icache.h" #include "xfs_icache.h"
#include "xfs_iomap.h" #include "xfs_iomap.h"
#include "xfs_reflink.h" #include "xfs_reflink.h"
#include "xfs_rtbitmap.h"
/* Kernel only BMAP related definitions and functions */ /* Kernel only BMAP related definitions and functions */
...@@ -89,14 +90,14 @@ xfs_bmap_rtalloc( ...@@ -89,14 +90,14 @@ xfs_bmap_rtalloc(
align = xfs_get_extsz_hint(ap->ip); align = xfs_get_extsz_hint(ap->ip);
retry: retry:
prod = align / mp->m_sb.sb_rextsize; prod = xfs_extlen_to_rtxlen(mp, align);
error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev, error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev,
align, 1, ap->eof, 0, align, 1, ap->eof, 0,
ap->conv, &ap->offset, &ap->length); ap->conv, &ap->offset, &ap->length);
if (error) if (error)
return error; return error;
ASSERT(ap->length); ASSERT(ap->length);
ASSERT(ap->length % mp->m_sb.sb_rextsize == 0); ASSERT(xfs_extlen_to_rtxmod(mp, ap->length) == 0);
/* /*
* If we shifted the file offset downward to satisfy an extent size * If we shifted the file offset downward to satisfy an extent size
...@@ -116,17 +117,14 @@ xfs_bmap_rtalloc( ...@@ -116,17 +117,14 @@ xfs_bmap_rtalloc(
prod = 1; prod = 1;
/* /*
* Set ralen to be the actual requested length in rtextents. * Set ralen to be the actual requested length in rtextents.
*/ *
ralen = ap->length / mp->m_sb.sb_rextsize;
/*
* If the old value was close enough to XFS_BMBT_MAX_EXTLEN that * If the old value was close enough to XFS_BMBT_MAX_EXTLEN that
* we rounded up to it, cut it back so it's valid again. * we rounded up to it, cut it back so it's valid again.
* Note that if it's a really large request (bigger than * Note that if it's a really large request (bigger than
* XFS_BMBT_MAX_EXTLEN), we don't hear about that number, and can't * XFS_BMBT_MAX_EXTLEN), we don't hear about that number, and can't
* adjust the starting point to match it. * adjust the starting point to match it.
*/ */
if (ralen * mp->m_sb.sb_rextsize >= XFS_MAX_BMBT_EXTLEN) ralen = xfs_extlen_to_rtxlen(mp, min(ap->length, XFS_MAX_BMBT_EXTLEN));
ralen = XFS_MAX_BMBT_EXTLEN / mp->m_sb.sb_rextsize;
/* /*
* Lock out modifications to both the RT bitmap and summary inodes * Lock out modifications to both the RT bitmap and summary inodes
...@@ -147,7 +145,7 @@ xfs_bmap_rtalloc( ...@@ -147,7 +145,7 @@ xfs_bmap_rtalloc(
error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx); error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx);
if (error) if (error)
return error; return error;
ap->blkno = rtx * mp->m_sb.sb_rextsize; ap->blkno = xfs_rtx_to_rtb(mp, rtx);
} else { } else {
ap->blkno = 0; ap->blkno = 0;
} }
...@@ -158,20 +156,18 @@ xfs_bmap_rtalloc( ...@@ -158,20 +156,18 @@ xfs_bmap_rtalloc(
* Realtime allocation, done through xfs_rtallocate_extent. * Realtime allocation, done through xfs_rtallocate_extent.
*/ */
if (ignore_locality) if (ignore_locality)
ap->blkno = 0; rtx = 0;
else else
do_div(ap->blkno, mp->m_sb.sb_rextsize); rtx = xfs_rtb_to_rtx(mp, ap->blkno);
rtx = ap->blkno; raminlen = max_t(xfs_rtxlen_t, 1, xfs_extlen_to_rtxlen(mp, minlen));
ap->length = ralen; error = xfs_rtallocate_extent(ap->tp, rtx, raminlen, ralen, &ralen,
raminlen = max_t(xfs_extlen_t, 1, minlen / mp->m_sb.sb_rextsize); ap->wasdel, prod, &rtx);
error = xfs_rtallocate_extent(ap->tp, ap->blkno, raminlen, ap->length,
&ralen, ap->wasdel, prod, &rtx);
if (error) if (error)
return error; return error;
if (rtx != NULLRTEXTNO) { if (rtx != NULLRTEXTNO) {
ap->blkno = rtx * mp->m_sb.sb_rextsize; ap->blkno = xfs_rtx_to_rtb(mp, rtx);
ap->length = ralen * mp->m_sb.sb_rextsize; ap->length = xfs_rtxlen_to_extlen(mp, ralen);
ap->ip->i_nblocks += ap->length; ap->ip->i_nblocks += ap->length;
xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE); xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
if (ap->wasdel) if (ap->wasdel)
...@@ -688,7 +684,7 @@ xfs_can_free_eofblocks( ...@@ -688,7 +684,7 @@ xfs_can_free_eofblocks(
*/ */
end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_ISIZE(ip)); end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_ISIZE(ip));
if (XFS_IS_REALTIME_INODE(ip) && mp->m_sb.sb_rextsize > 1) if (XFS_IS_REALTIME_INODE(ip) && mp->m_sb.sb_rextsize > 1)
end_fsb = roundup_64(end_fsb, mp->m_sb.sb_rextsize); end_fsb = xfs_rtb_roundup_rtx(mp, end_fsb);
last_fsb = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes); last_fsb = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes);
if (last_fsb <= end_fsb) if (last_fsb <= end_fsb)
return false; return false;
...@@ -987,10 +983,8 @@ xfs_free_file_space( ...@@ -987,10 +983,8 @@ xfs_free_file_space(
/* We can only free complete realtime extents. */ /* We can only free complete realtime extents. */
if (XFS_IS_REALTIME_INODE(ip) && mp->m_sb.sb_rextsize > 1) { if (XFS_IS_REALTIME_INODE(ip) && mp->m_sb.sb_rextsize > 1) {
startoffset_fsb = roundup_64(startoffset_fsb, startoffset_fsb = xfs_rtb_roundup_rtx(mp, startoffset_fsb);
mp->m_sb.sb_rextsize); endoffset_fsb = xfs_rtb_rounddown_rtx(mp, endoffset_fsb);
endoffset_fsb = rounddown_64(endoffset_fsb,
mp->m_sb.sb_rextsize);
} }
/* /*
......
...@@ -483,11 +483,11 @@ xfs_getfsmap_rtdev_rtbitmap_helper( ...@@ -483,11 +483,11 @@ xfs_getfsmap_rtdev_rtbitmap_helper(
xfs_rtblock_t rtbno; xfs_rtblock_t rtbno;
xfs_daddr_t rec_daddr, len_daddr; xfs_daddr_t rec_daddr, len_daddr;
rtbno = rec->ar_startext * mp->m_sb.sb_rextsize; rtbno = xfs_rtx_to_rtb(mp, rec->ar_startext);
rec_daddr = XFS_FSB_TO_BB(mp, rtbno); rec_daddr = XFS_FSB_TO_BB(mp, rtbno);
irec.rm_startblock = rtbno; irec.rm_startblock = rtbno;
rtbno = rec->ar_extcount * mp->m_sb.sb_rextsize; rtbno = xfs_rtx_to_rtb(mp, rec->ar_extcount);
len_daddr = XFS_FSB_TO_BB(mp, rtbno); len_daddr = XFS_FSB_TO_BB(mp, rtbno);
irec.rm_blockcount = rtbno; irec.rm_blockcount = rtbno;
...@@ -514,7 +514,7 @@ xfs_getfsmap_rtdev_rtbitmap( ...@@ -514,7 +514,7 @@ xfs_getfsmap_rtdev_rtbitmap(
uint64_t eofs; uint64_t eofs;
int error; int error;
eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rextents * mp->m_sb.sb_rextsize); eofs = XFS_FSB_TO_BB(mp, xfs_rtx_to_rtb(mp, mp->m_sb.sb_rextents));
if (keys[0].fmr_physical >= eofs) if (keys[0].fmr_physical >= eofs)
return 0; return 0;
start_rtb = XFS_BB_TO_FSBT(mp, start_rtb = XFS_BB_TO_FSBT(mp,
...@@ -539,11 +539,8 @@ xfs_getfsmap_rtdev_rtbitmap( ...@@ -539,11 +539,8 @@ xfs_getfsmap_rtdev_rtbitmap(
* Set up query parameters to return free rtextents covering the range * Set up query parameters to return free rtextents covering the range
* we want. * we want.
*/ */
alow.ar_startext = start_rtb; alow.ar_startext = xfs_rtb_to_rtx(mp, start_rtb);
ahigh.ar_startext = end_rtb; ahigh.ar_startext = xfs_rtb_to_rtxup(mp, end_rtb);
do_div(alow.ar_startext, mp->m_sb.sb_rextsize);
if (do_div(ahigh.ar_startext, mp->m_sb.sb_rextsize))
ahigh.ar_startext++;
error = xfs_rtalloc_query_range(mp, tp, &alow, &ahigh, error = xfs_rtalloc_query_range(mp, tp, &alow, &ahigh,
xfs_getfsmap_rtdev_rtbitmap_helper, info); xfs_getfsmap_rtdev_rtbitmap_helper, info);
if (error) if (error)
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "xfs_log.h" #include "xfs_log.h"
#include "xfs_log_priv.h" #include "xfs_log_priv.h"
#include "xfs_error.h" #include "xfs_error.h"
#include "xfs_rtbitmap.h"
#include <linux/iversion.h> #include <linux/iversion.h>
...@@ -107,7 +108,7 @@ xfs_inode_item_precommit( ...@@ -107,7 +108,7 @@ xfs_inode_item_precommit(
*/ */
if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) && if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) &&
(ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) && (ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) &&
(ip->i_extsize % ip->i_mount->m_sb.sb_rextsize) > 0) { xfs_extlen_to_rtxmod(ip->i_mount, ip->i_extsize) > 0) {
ip->i_diflags &= ~(XFS_DIFLAG_EXTSIZE | ip->i_diflags &= ~(XFS_DIFLAG_EXTSIZE |
XFS_DIFLAG_EXTSZINHERIT); XFS_DIFLAG_EXTSZINHERIT);
ip->i_extsize = 0; ip->i_extsize = 0;
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "xfs_reflink.h" #include "xfs_reflink.h"
#include "xfs_ioctl.h" #include "xfs_ioctl.h"
#include "xfs_xattr.h" #include "xfs_xattr.h"
#include "xfs_rtbitmap.h"
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/namei.h> #include <linux/namei.h>
...@@ -1004,7 +1005,7 @@ xfs_fill_fsxattr( ...@@ -1004,7 +1005,7 @@ xfs_fill_fsxattr(
* later. * later.
*/ */
if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) && if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) &&
ip->i_extsize % mp->m_sb.sb_rextsize > 0) { xfs_extlen_to_rtxmod(mp, ip->i_extsize) > 0) {
fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE | fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE |
FS_XFLAG_EXTSZINHERIT); FS_XFLAG_EXTSZINHERIT);
fa->fsx_extsize = 0; fa->fsx_extsize = 0;
...@@ -1130,7 +1131,7 @@ xfs_ioctl_setattr_xflags( ...@@ -1130,7 +1131,7 @@ xfs_ioctl_setattr_xflags(
/* If realtime flag is set then must have realtime device */ /* If realtime flag is set then must have realtime device */
if (fa->fsx_xflags & FS_XFLAG_REALTIME) { if (fa->fsx_xflags & FS_XFLAG_REALTIME) {
if (mp->m_sb.sb_rblocks == 0 || mp->m_sb.sb_rextsize == 0 || if (mp->m_sb.sb_rblocks == 0 || mp->m_sb.sb_rextsize == 0 ||
(ip->i_extsize % mp->m_sb.sb_rextsize)) xfs_extlen_to_rtxmod(mp, ip->i_extsize))
return -EINVAL; return -EINVAL;
} }
......
...@@ -198,6 +198,18 @@ static inline uint64_t howmany_64(uint64_t x, uint32_t y) ...@@ -198,6 +198,18 @@ static inline uint64_t howmany_64(uint64_t x, uint32_t y)
return x; return x;
} }
/* If @b is a power of 2, return log2(b). Else return -1. */
static inline int8_t log2_if_power2(unsigned long b)
{
return is_power_of_2(b) ? ilog2(b) : -1;
}
/* If @b is a power of 2, return a mask of the lower bits, else return zero. */
static inline unsigned long long mask64_if_power2(unsigned long b)
{
return is_power_of_2(b) ? b - 1 : 0;
}
int xfs_rw_bdev(struct block_device *bdev, sector_t sector, unsigned int count, int xfs_rw_bdev(struct block_device *bdev, sector_t sector, unsigned int count,
char *data, enum req_op op); char *data, enum req_op op);
......
...@@ -119,6 +119,7 @@ typedef struct xfs_mount { ...@@ -119,6 +119,7 @@ typedef struct xfs_mount {
uint8_t m_blkbb_log; /* blocklog - BBSHIFT */ uint8_t m_blkbb_log; /* blocklog - BBSHIFT */
uint8_t m_agno_log; /* log #ag's */ uint8_t m_agno_log; /* log #ag's */
uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ uint8_t m_sectbb_log; /* sectlog - BBSHIFT */
int8_t m_rtxblklog; /* log2 of rextsize, if possible */
uint m_blockmask; /* sb_blocksize-1 */ uint m_blockmask; /* sb_blocksize-1 */
uint m_blockwsize; /* sb_blocksize in words */ uint m_blockwsize; /* sb_blocksize in words */
uint m_blockwmask; /* blockwsize-1 */ uint m_blockwmask; /* blockwsize-1 */
...@@ -152,6 +153,7 @@ typedef struct xfs_mount { ...@@ -152,6 +153,7 @@ typedef struct xfs_mount {
uint64_t m_features; /* active filesystem features */ uint64_t m_features; /* active filesystem features */
uint64_t m_low_space[XFS_LOWSP_MAX]; uint64_t m_low_space[XFS_LOWSP_MAX];
uint64_t m_low_rtexts[XFS_LOWSP_MAX]; uint64_t m_low_rtexts[XFS_LOWSP_MAX];
uint64_t m_rtxblkmask; /* rt extent block mask */
struct xfs_ino_geometry m_ino_geo; /* inode geometry */ struct xfs_ino_geometry m_ino_geo; /* inode geometry */
struct xfs_trans_resv m_resv; /* precomputed res values */ struct xfs_trans_resv m_resv; /* precomputed res values */
/* low free space thresholds */ /* low free space thresholds */
......
...@@ -1054,12 +1054,12 @@ xfs_growfs_rt( ...@@ -1054,12 +1054,12 @@ xfs_growfs_rt(
* Calculate new sb and mount fields for this round. * Calculate new sb and mount fields for this round.
*/ */
nsbp->sb_rextsize = in->extsize; nsbp->sb_rextsize = in->extsize;
nmp->m_rtxblklog = -1; /* don't use shift or masking */
nsbp->sb_rbmblocks = bmbno + 1; nsbp->sb_rbmblocks = bmbno + 1;
nrblocks_step = (bmbno + 1) * NBBY * nsbp->sb_blocksize * nrblocks_step = (bmbno + 1) * NBBY * nsbp->sb_blocksize *
nsbp->sb_rextsize; nsbp->sb_rextsize;
nsbp->sb_rblocks = min(nrblocks, nrblocks_step); nsbp->sb_rblocks = min(nrblocks, nrblocks_step);
nsbp->sb_rextents = nsbp->sb_rblocks; nsbp->sb_rextents = xfs_rtb_to_rtx(nmp, nsbp->sb_rblocks);
do_div(nsbp->sb_rextents, nsbp->sb_rextsize);
ASSERT(nsbp->sb_rextents != 0); ASSERT(nsbp->sb_rextents != 0);
nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents); nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents);
nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1; nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1;
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "xfs_xattr.h" #include "xfs_xattr.h"
#include "xfs_iunlink_item.h" #include "xfs_iunlink_item.h"
#include "xfs_dahash_test.h" #include "xfs_dahash_test.h"
#include "xfs_rtbitmap.h"
#include "scrub/stats.h" #include "scrub/stats.h"
#include <linux/magic.h> #include <linux/magic.h>
...@@ -890,7 +891,7 @@ xfs_fs_statfs( ...@@ -890,7 +891,7 @@ xfs_fs_statfs(
statp->f_blocks = sbp->sb_rblocks; statp->f_blocks = sbp->sb_rblocks;
freertx = percpu_counter_sum_positive(&mp->m_frextents); freertx = percpu_counter_sum_positive(&mp->m_frextents);
statp->f_bavail = statp->f_bfree = freertx * sbp->sb_rextsize; statp->f_bavail = statp->f_bfree = xfs_rtx_to_rtb(mp, freertx);
} }
return 0; return 0;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "xfs_dquot_item.h" #include "xfs_dquot_item.h"
#include "xfs_dquot.h" #include "xfs_dquot.h"
#include "xfs_icache.h" #include "xfs_icache.h"
#include "xfs_rtbitmap.h"
struct kmem_cache *xfs_trans_cache; struct kmem_cache *xfs_trans_cache;
...@@ -655,6 +656,10 @@ xfs_trans_unreserve_and_mod_sb( ...@@ -655,6 +656,10 @@ xfs_trans_unreserve_and_mod_sb(
mp->m_sb.sb_agcount += tp->t_agcount_delta; mp->m_sb.sb_agcount += tp->t_agcount_delta;
mp->m_sb.sb_imax_pct += tp->t_imaxpct_delta; mp->m_sb.sb_imax_pct += tp->t_imaxpct_delta;
mp->m_sb.sb_rextsize += tp->t_rextsize_delta; mp->m_sb.sb_rextsize += tp->t_rextsize_delta;
if (tp->t_rextsize_delta) {
mp->m_rtxblklog = log2_if_power2(mp->m_sb.sb_rextsize);
mp->m_rtxblkmask = mask64_if_power2(mp->m_sb.sb_rextsize);
}
mp->m_sb.sb_rbmblocks += tp->t_rbmblocks_delta; mp->m_sb.sb_rbmblocks += tp->t_rbmblocks_delta;
mp->m_sb.sb_rblocks += tp->t_rblocks_delta; mp->m_sb.sb_rblocks += tp->t_rblocks_delta;
mp->m_sb.sb_rextents += tp->t_rextents_delta; mp->m_sb.sb_rextents += tp->t_rextents_delta;
...@@ -1196,7 +1201,7 @@ xfs_trans_alloc_inode( ...@@ -1196,7 +1201,7 @@ xfs_trans_alloc_inode(
retry: retry:
error = xfs_trans_alloc(mp, resv, dblocks, error = xfs_trans_alloc(mp, resv, dblocks,
rblocks / mp->m_sb.sb_rextsize, xfs_extlen_to_rtxlen(mp, rblocks),
force ? XFS_TRANS_RESERVE : 0, &tp); force ? XFS_TRANS_RESERVE : 0, &tp);
if (error) if (error)
return error; return error;
......
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