uint8_t m_blkbb_log; /* blocklog - BBSHIFT */
uint8_t m_sectbb_log; /* sectorlog - BBSHIFT */
uint8_t m_agno_log; /* log #ag's */
+ int8_t m_rtxblklog; /* log2 of rextsize, if possible */
uint m_blockmask; /* sb_blocksize-1 */
uint m_blockwsize; /* sb_blocksize in words */
uint m_blockwmask; /* blockwsize-1 */
struct radix_tree_root m_perag_tree;
uint64_t m_features; /* active filesystem features */
uint64_t m_low_space[XFS_LOWSP_MAX];
+ uint64_t m_rtxblkmask; /* rt extent block mask */
unsigned long m_opstate; /* dynamic state flags */
bool m_finobt_nores; /* no per-AG finobt resv. */
uint m_qflags; /* quota status flags */
return 0;
}
+/* If @b is a power of 2, return log2(b). Else return -1. */
+static inline int8_t log2_if_power2(unsigned long b)
+{
+ unsigned long mask = 1;
+ unsigned int i;
+ unsigned int ret = 1;
+
+ if (!is_power_of_2(b))
+ return -1;
+
+ for (i = 0; i < NBBY * sizeof(unsigned long); i++, mask <<= 1) {
+ if (b & mask)
+ ret = i;
+ }
+
+ return ret;
+}
+
+/* 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;
+}
+
/* buffer management */
#define XBF_TRYLOCK 0
#define XBF_UNMAPPED 0
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;
}
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;
}
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;
}
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;
}
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);
}
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);
}
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);
}
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;
mp->m_blockmask = sbp->sb_blocksize - 1;
mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
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[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0);