@@ -46,6 +46,13 @@ struct xfs_ag_rmap {
struct xfs_slab *ar_refcount_items;
};
+/* Only the parts of struct xfs_rmap_irec that we need to compute refcounts. */
+struct rmap_for_refcount {
+ xfs_agblock_t rm_startblock;
+ xfs_extlen_t rm_blockcount;
+ uint64_t rm_owner;
+};
+
static struct xfs_ag_rmap *ag_rmaps;
bool rmapbt_suspect;
static bool refcbt_suspect;
@@ -777,16 +784,14 @@ static void
rmap_dump(
const char *msg,
xfs_agnumber_t agno,
- struct xfs_rmap_irec *rmap)
+ const struct rmap_for_refcount *rfr)
{
- printf("%s: %p agno=%u pblk=%llu own=%lld lblk=%llu len=%u flags=0x%x\n",
- msg, rmap,
+ printf("%s: %p agno=%u agbno=%llu owner=%lld fsbcount=%u\n",
+ msg, rfr,
(unsigned int)agno,
- (unsigned long long)rmap->rm_startblock,
- (unsigned long long)rmap->rm_owner,
- (unsigned long long)rmap->rm_offset,
- (unsigned int)rmap->rm_blockcount,
- (unsigned int)rmap->rm_flags);
+ (unsigned long long)rfr->rm_startblock,
+ (unsigned long long)rfr->rm_owner,
+ (unsigned int)rfr->rm_blockcount);
}
#else
# define rmap_dump(m, a, r)
@@ -865,30 +870,33 @@ rmap_dump(
*/
static void
mark_inode_rl(
- struct xfs_mount *mp,
+ struct xfs_mount *mp,
struct xfs_bag *rmaps)
{
- xfs_agnumber_t iagno;
- struct xfs_rmap_irec *rmap;
+ struct rmap_for_refcount *rfr;
struct ino_tree_node *irec;
int off;
uint64_t idx;
- xfs_agino_t ino;
if (bag_count(rmaps) < 2)
return;
/* Reflink flag accounting */
- foreach_bag_ptr(rmaps, idx, rmap) {
- ASSERT(!XFS_RMAP_NON_INODE_OWNER(rmap->rm_owner));
- iagno = XFS_INO_TO_AGNO(mp, rmap->rm_owner);
- ino = XFS_INO_TO_AGINO(mp, rmap->rm_owner);
- pthread_mutex_lock(&ag_locks[iagno].lock);
- irec = find_inode_rec(mp, iagno, ino);
- off = get_inode_offset(mp, rmap->rm_owner, irec);
+ foreach_bag_ptr(rmaps, idx, rfr) {
+ xfs_agnumber_t agno;
+ xfs_agino_t agino;
+
+ ASSERT(!XFS_RMAP_NON_INODE_OWNER(rfr->rm_owner));
+
+ agno = XFS_INO_TO_AGNO(mp, rfr->rm_owner);
+ agino = XFS_INO_TO_AGINO(mp, rfr->rm_owner);
+
+ pthread_mutex_lock(&ag_locks[agno].lock);
+ irec = find_inode_rec(mp, agno, agino);
+ off = get_inode_offset(mp, rfr->rm_owner, irec);
/* lock here because we might go outside this ag */
set_inode_is_rl(irec, off);
- pthread_mutex_unlock(&ag_locks[iagno].lock);
+ pthread_mutex_unlock(&ag_locks[agno].lock);
}
}
@@ -996,15 +1004,15 @@ next_refcount_edge(
bool next_valid,
xfs_agblock_t *nbnop)
{
- struct xfs_rmap_irec *rmap;
+ struct rmap_for_refcount *rfr;
uint64_t idx;
xfs_agblock_t nbno = NULLAGBLOCK;
if (next_valid)
nbno = next_rmap->rm_startblock;
- foreach_bag_ptr(stack_top, idx, rmap)
- nbno = min(nbno, RMAP_NEXT(rmap));
+ foreach_bag_ptr(stack_top, idx, rfr)
+ nbno = min(nbno, RMAP_NEXT(rfr));
/*
* We should have found /something/ because either next_rrm is the next
@@ -1039,8 +1047,14 @@ refcount_push_rmaps_at(
int error;
while (*have && irec->rm_startblock == bno) {
- rmap_dump(tag, agno, irec);
- error = bag_add(stack_top, irec);
+ struct rmap_for_refcount rfr = {
+ .rm_startblock = irec->rm_startblock,
+ .rm_blockcount = irec->rm_blockcount,
+ .rm_owner = irec->rm_owner,
+ };
+
+ rmap_dump(tag, agno, &rfr);
+ error = bag_add(stack_top, &rfr);
if (error)
return error;
error = refcount_walk_rmaps(rmcur, irec, have);
@@ -1069,7 +1083,7 @@ compute_refcounts(
struct xfs_btree_cur *rmcur;
struct xfs_rmap_irec irec;
struct xfs_bag *stack_top = NULL;
- struct xfs_rmap_irec *rmap;
+ struct rmap_for_refcount *rfr;
uint64_t idx;
uint64_t old_stack_nr;
xfs_agblock_t sbno; /* first bno of this rmap set */
@@ -1085,7 +1099,7 @@ compute_refcounts(
if (error)
return error;
- error = init_bag(&stack_top, sizeof(struct xfs_rmap_irec));
+ error = init_bag(&stack_top, sizeof(struct rmap_for_refcount));
if (error)
goto out_cur;
@@ -1122,10 +1136,10 @@ compute_refcounts(
/* While stack isn't empty... */
while (bag_count(stack_top)) {
/* Pop all rmaps that end at nbno */
- foreach_bag_ptr_reverse(stack_top, idx, rmap) {
- if (RMAP_NEXT(rmap) != nbno)
+ foreach_bag_ptr_reverse(stack_top, idx, rfr) {
+ if (RMAP_NEXT(rfr) != nbno)
continue;
- rmap_dump("pop", agno, rmap);
+ rmap_dump("pop", agno, rfr);
error = bag_remove(stack_top, idx);
if (error)
goto out_bag;