summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-12-27 20:04:23 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2018-12-27 20:04:23 -0500
commit47a43f2f0ce24bb75e3e4500118000585a3b496a (patch)
tree4decf322cd12b49c3bc82d7578617bb27db0541a /fs
parente01799ac56306ab211f2edf1221a82dc57eab8f5 (diff)
parent65eed012d1f2d0f0bf0ffc036826d58147de77b8 (diff)
Merge tag 'xfs-4.21-merge-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull XFS updates from Darrick Wong: - Fix CoW remapping of extremely fragmented file areas - Fix a zero-length symlink verifier error - Constify some of the rmap owner structures for per-AG metadata - Precalculate inode geometry for later use - Fix scrub counting problems - Don't crash when rtsummary inode is null - Fix x32 ioctl operation - Fix enum->string mappings for ftrace output - Cache realtime summary information in memory * tag 'xfs-4.21-merge-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (24 commits) xfs: reallocate realtime summary cache on growfs xfs: stringify scrub types in ftrace output xfs: stringify btree cursor types in ftrace output xfs: move XFS_INODE_FORMAT_STR mappings to libxfs xfs: move XFS_AG_BTREE_CMP_FORMAT_STR mappings to libxfs xfs: fix symbolic enum printing in ftrace output xfs: fix function pointer type in ftrace format xfs: Fix x32 ioctls when cmd numbers differ from ia32. xfs: Fix bulkstat compat ioctls on x32 userspace. xfs: Align compat attrlist_by_handle with native implementation. xfs: require both realtime inodes to mount xfs: cache minimum realtime summary level xfs: count inode blocks correctly in inobt scrub xfs: precalculate cluster alignment in inodes and blocks xfs: precalculate inodes and blocks per inode cluster xfs: add a block to inode count converter xfs: remove xfs_rmap_ag_owner and friends xfs: const-ify xfs_owner_info arguments xfs: streamline defer op type handling xfs: idiotproof defer op type configuration ...
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/libxfs/xfs_ag.c9
-rw-r--r--fs/xfs/libxfs/xfs_alloc.c79
-rw-r--r--fs/xfs/libxfs/xfs_alloc.h4
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c6
-rw-r--r--fs/xfs/libxfs/xfs_bmap.h4
-rw-r--r--fs/xfs/libxfs/xfs_defer.c67
-rw-r--r--fs/xfs/libxfs/xfs_defer.h37
-rw-r--r--fs/xfs/libxfs/xfs_format.h12
-rw-r--r--fs/xfs/libxfs/xfs_ialloc.c54
-rw-r--r--fs/xfs/libxfs/xfs_ialloc_btree.c7
-rw-r--r--fs/xfs/libxfs/xfs_refcount_btree.c6
-rw-r--r--fs/xfs/libxfs/xfs_rmap.c240
-rw-r--r--fs/xfs/libxfs/xfs_rmap.h54
-rw-r--r--fs/xfs/libxfs/xfs_rtbitmap.c6
-rw-r--r--fs/xfs/libxfs/xfs_symlink_remote.c14
-rw-r--r--fs/xfs/libxfs/xfs_types.c9
-rw-r--r--fs/xfs/libxfs/xfs_types.h22
-rw-r--r--fs/xfs/scrub/agheader.c25
-rw-r--r--fs/xfs/scrub/agheader_repair.c5
-rw-r--r--fs/xfs/scrub/alloc.c4
-rw-r--r--fs/xfs/scrub/btree.c45
-rw-r--r--fs/xfs/scrub/btree.h22
-rw-r--r--fs/xfs/scrub/common.c14
-rw-r--r--fs/xfs/scrub/common.h2
-rw-r--r--fs/xfs/scrub/ialloc.c64
-rw-r--r--fs/xfs/scrub/inode.c4
-rw-r--r--fs/xfs/scrub/refcount.c16
-rw-r--r--fs/xfs/scrub/repair.c54
-rw-r--r--fs/xfs/scrub/repair.h7
-rw-r--r--fs/xfs/scrub/rmap.c35
-rw-r--r--fs/xfs/scrub/scrub.h4
-rw-r--r--fs/xfs/scrub/trace.h131
-rw-r--r--fs/xfs/xfs_aops.h3
-rw-r--r--fs/xfs/xfs_extfree_item.c5
-rw-r--r--fs/xfs/xfs_fsops.c2
-rw-r--r--fs/xfs/xfs_inode.c16
-rw-r--r--fs/xfs/xfs_ioctl32.c58
-rw-r--r--fs/xfs/xfs_itable.c14
-rw-r--r--fs/xfs/xfs_log_recover.c8
-rw-r--r--fs/xfs/xfs_mount.c4
-rw-r--r--fs/xfs/xfs_mount.h11
-rw-r--r--fs/xfs/xfs_reflink.c232
-rw-r--r--fs/xfs/xfs_rtalloc.c57
-rw-r--r--fs/xfs/xfs_super.c10
-rw-r--r--fs/xfs/xfs_symlink.c33
-rw-r--r--fs/xfs/xfs_trace.h51
-rw-r--r--fs/xfs/xfs_trans.h7
-rw-r--r--fs/xfs/xfs_trans_bmap.c11
-rw-r--r--fs/xfs/xfs_trans_extfree.c40
-rw-r--r--fs/xfs/xfs_trans_refcount.c11
-rw-r--r--fs/xfs/xfs_trans_rmap.c11
51 files changed, 932 insertions, 714 deletions
diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c
index 9345802c99f7..999ad8d00d43 100644
--- a/fs/xfs/libxfs/xfs_ag.c
+++ b/fs/xfs/libxfs/xfs_ag.c
@@ -414,7 +414,6 @@ xfs_ag_extend_space(
414 struct aghdr_init_data *id, 414 struct aghdr_init_data *id,
415 xfs_extlen_t len) 415 xfs_extlen_t len)
416{ 416{
417 struct xfs_owner_info oinfo;
418 struct xfs_buf *bp; 417 struct xfs_buf *bp;
419 struct xfs_agi *agi; 418 struct xfs_agi *agi;
420 struct xfs_agf *agf; 419 struct xfs_agf *agf;
@@ -448,17 +447,17 @@ xfs_ag_extend_space(
448 /* 447 /*
449 * Free the new space. 448 * Free the new space.
450 * 449 *
451 * XFS_RMAP_OWN_NULL is used here to tell the rmap btree that 450 * XFS_RMAP_OINFO_SKIP_UPDATE is used here to tell the rmap btree that
452 * this doesn't actually exist in the rmap btree. 451 * this doesn't actually exist in the rmap btree.
453 */ 452 */
454 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_NULL);
455 error = xfs_rmap_free(tp, bp, id->agno, 453 error = xfs_rmap_free(tp, bp, id->agno,
456 be32_to_cpu(agf->agf_length) - len, 454 be32_to_cpu(agf->agf_length) - len,
457 len, &oinfo); 455 len, &XFS_RMAP_OINFO_SKIP_UPDATE);
458 if (error) 456 if (error)
459 return error; 457 return error;
460 458
461 return xfs_free_extent(tp, XFS_AGB_TO_FSB(mp, id->agno, 459 return xfs_free_extent(tp, XFS_AGB_TO_FSB(mp, id->agno,
462 be32_to_cpu(agf->agf_length) - len), 460 be32_to_cpu(agf->agf_length) - len),
463 len, &oinfo, XFS_AG_RESV_NONE); 461 len, &XFS_RMAP_OINFO_SKIP_UPDATE,
462 XFS_AG_RESV_NONE);
464} 463}
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index e1c0c0d2f1b0..b715668886a4 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -1594,7 +1594,6 @@ xfs_alloc_ag_vextent_small(
1594 xfs_extlen_t *flenp, /* result length */ 1594 xfs_extlen_t *flenp, /* result length */
1595 int *stat) /* status: 0-freelist, 1-normal/none */ 1595 int *stat) /* status: 0-freelist, 1-normal/none */
1596{ 1596{
1597 struct xfs_owner_info oinfo;
1598 int error; 1597 int error;
1599 xfs_agblock_t fbno; 1598 xfs_agblock_t fbno;
1600 xfs_extlen_t flen; 1599 xfs_extlen_t flen;
@@ -1648,9 +1647,8 @@ xfs_alloc_ag_vextent_small(
1648 * doesn't live in the free space, we need to clear 1647 * doesn't live in the free space, we need to clear
1649 * out the OWN_AG rmap. 1648 * out the OWN_AG rmap.
1650 */ 1649 */
1651 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_AG);
1652 error = xfs_rmap_free(args->tp, args->agbp, args->agno, 1650 error = xfs_rmap_free(args->tp, args->agbp, args->agno,
1653 fbno, 1, &oinfo); 1651 fbno, 1, &XFS_RMAP_OINFO_AG);
1654 if (error) 1652 if (error)
1655 goto error0; 1653 goto error0;
1656 1654
@@ -1694,28 +1692,28 @@ error0:
1694 */ 1692 */
1695STATIC int 1693STATIC int
1696xfs_free_ag_extent( 1694xfs_free_ag_extent(
1697 xfs_trans_t *tp, 1695 struct xfs_trans *tp,
1698 xfs_buf_t *agbp, 1696 struct xfs_buf *agbp,
1699 xfs_agnumber_t agno, 1697 xfs_agnumber_t agno,
1700 xfs_agblock_t bno, 1698 xfs_agblock_t bno,
1701 xfs_extlen_t len, 1699 xfs_extlen_t len,
1702 struct xfs_owner_info *oinfo, 1700 const struct xfs_owner_info *oinfo,
1703 enum xfs_ag_resv_type type) 1701 enum xfs_ag_resv_type type)
1704{ 1702{
1705 xfs_btree_cur_t *bno_cur; /* cursor for by-block btree */ 1703 struct xfs_mount *mp;
1706 xfs_btree_cur_t *cnt_cur; /* cursor for by-size btree */ 1704 struct xfs_perag *pag;
1707 int error; /* error return value */ 1705 struct xfs_btree_cur *bno_cur;
1708 xfs_agblock_t gtbno; /* start of right neighbor block */ 1706 struct xfs_btree_cur *cnt_cur;
1709 xfs_extlen_t gtlen; /* length of right neighbor block */ 1707 xfs_agblock_t gtbno; /* start of right neighbor */
1710 int haveleft; /* have a left neighbor block */ 1708 xfs_extlen_t gtlen; /* length of right neighbor */
1711 int haveright; /* have a right neighbor block */ 1709 xfs_agblock_t ltbno; /* start of left neighbor */
1712 int i; /* temp, result code */ 1710 xfs_extlen_t ltlen; /* length of left neighbor */
1713 xfs_agblock_t ltbno; /* start of left neighbor block */ 1711 xfs_agblock_t nbno; /* new starting block of freesp */
1714 xfs_extlen_t ltlen; /* length of left neighbor block */ 1712 xfs_extlen_t nlen; /* new length of freespace */
1715 xfs_mount_t *mp; /* mount point struct for filesystem */ 1713 int haveleft; /* have a left neighbor */
1716 xfs_agblock_t nbno; /* new starting block of freespace */ 1714 int haveright; /* have a right neighbor */
1717 xfs_extlen_t nlen; /* new length of freespace */ 1715 int i;
1718 xfs_perag_t *pag; /* per allocation group data */ 1716 int error;
1719 1717
1720 bno_cur = cnt_cur = NULL; 1718 bno_cur = cnt_cur = NULL;
1721 mp = tp->t_mountp; 1719 mp = tp->t_mountp;
@@ -2314,10 +2312,11 @@ xfs_alloc_fix_freelist(
2314 * repair/rmap.c in xfsprogs for details. 2312 * repair/rmap.c in xfsprogs for details.
2315 */ 2313 */
2316 memset(&targs, 0, sizeof(targs)); 2314 memset(&targs, 0, sizeof(targs));
2315 /* struct copy below */
2317 if (flags & XFS_ALLOC_FLAG_NORMAP) 2316 if (flags & XFS_ALLOC_FLAG_NORMAP)
2318 xfs_rmap_skip_owner_update(&targs.oinfo); 2317 targs.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE;
2319 else 2318 else
2320 xfs_rmap_ag_owner(&targs.oinfo, XFS_RMAP_OWN_AG); 2319 targs.oinfo = XFS_RMAP_OINFO_AG;
2321 while (!(flags & XFS_ALLOC_FLAG_NOSHRINK) && pag->pagf_flcount > need) { 2320 while (!(flags & XFS_ALLOC_FLAG_NOSHRINK) && pag->pagf_flcount > need) {
2322 error = xfs_alloc_get_freelist(tp, agbp, &bno, 0); 2321 error = xfs_alloc_get_freelist(tp, agbp, &bno, 0);
2323 if (error) 2322 if (error)
@@ -2435,7 +2434,6 @@ xfs_alloc_get_freelist(
2435 be32_add_cpu(&agf->agf_flcount, -1); 2434 be32_add_cpu(&agf->agf_flcount, -1);
2436 xfs_trans_agflist_delta(tp, -1); 2435 xfs_trans_agflist_delta(tp, -1);
2437 pag->pagf_flcount--; 2436 pag->pagf_flcount--;
2438 xfs_perag_put(pag);
2439 2437
2440 logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT; 2438 logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT;
2441 if (btreeblk) { 2439 if (btreeblk) {
@@ -2443,6 +2441,7 @@ xfs_alloc_get_freelist(
2443 pag->pagf_btreeblks++; 2441 pag->pagf_btreeblks++;
2444 logflags |= XFS_AGF_BTREEBLKS; 2442 logflags |= XFS_AGF_BTREEBLKS;
2445 } 2443 }
2444 xfs_perag_put(pag);
2446 2445
2447 xfs_alloc_log_agf(tp, agbp, logflags); 2446 xfs_alloc_log_agf(tp, agbp, logflags);
2448 *bnop = bno; 2447 *bnop = bno;
@@ -3008,21 +3007,21 @@ out:
3008 * Just break up the extent address and hand off to xfs_free_ag_extent 3007 * Just break up the extent address and hand off to xfs_free_ag_extent
3009 * after fixing up the freelist. 3008 * after fixing up the freelist.
3010 */ 3009 */
3011int /* error */ 3010int
3012__xfs_free_extent( 3011__xfs_free_extent(
3013 struct xfs_trans *tp, /* transaction pointer */ 3012 struct xfs_trans *tp,
3014 xfs_fsblock_t bno, /* starting block number of extent */ 3013 xfs_fsblock_t bno,
3015 xfs_extlen_t len, /* length of extent */ 3014 xfs_extlen_t len,
3016 struct xfs_owner_info *oinfo, /* extent owner */ 3015 const struct xfs_owner_info *oinfo,
3017 enum xfs_ag_resv_type type, /* block reservation type */ 3016 enum xfs_ag_resv_type type,
3018 bool skip_discard) 3017 bool skip_discard)
3019{ 3018{
3020 struct xfs_mount *mp = tp->t_mountp; 3019 struct xfs_mount *mp = tp->t_mountp;
3021 struct xfs_buf *agbp; 3020 struct xfs_buf *agbp;
3022 xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, bno); 3021 xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, bno);
3023 xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, bno); 3022 xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, bno);
3024 int error; 3023 int error;
3025 unsigned int busy_flags = 0; 3024 unsigned int busy_flags = 0;
3026 3025
3027 ASSERT(len != 0); 3026 ASSERT(len != 0);
3028 ASSERT(type != XFS_AG_RESV_AGFL); 3027 ASSERT(type != XFS_AG_RESV_AGFL);
diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h
index 00cd5ec4cb6b..d6ed5d2c07c2 100644
--- a/fs/xfs/libxfs/xfs_alloc.h
+++ b/fs/xfs/libxfs/xfs_alloc.h
@@ -182,7 +182,7 @@ __xfs_free_extent(
182 struct xfs_trans *tp, /* transaction pointer */ 182 struct xfs_trans *tp, /* transaction pointer */
183 xfs_fsblock_t bno, /* starting block number of extent */ 183 xfs_fsblock_t bno, /* starting block number of extent */
184 xfs_extlen_t len, /* length of extent */ 184 xfs_extlen_t len, /* length of extent */
185 struct xfs_owner_info *oinfo, /* extent owner */ 185 const struct xfs_owner_info *oinfo, /* extent owner */
186 enum xfs_ag_resv_type type, /* block reservation type */ 186 enum xfs_ag_resv_type type, /* block reservation type */
187 bool skip_discard); 187 bool skip_discard);
188 188
@@ -191,7 +191,7 @@ xfs_free_extent(
191 struct xfs_trans *tp, 191 struct xfs_trans *tp,
192 xfs_fsblock_t bno, 192 xfs_fsblock_t bno,
193 xfs_extlen_t len, 193 xfs_extlen_t len,
194 struct xfs_owner_info *oinfo, 194 const struct xfs_owner_info *oinfo,
195 enum xfs_ag_resv_type type) 195 enum xfs_ag_resv_type type)
196{ 196{
197 return __xfs_free_extent(tp, bno, len, oinfo, type, false); 197 return __xfs_free_extent(tp, bno, len, oinfo, type, false);
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 19e921d1586f..332eefa2700b 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -536,7 +536,7 @@ __xfs_bmap_add_free(
536 struct xfs_trans *tp, 536 struct xfs_trans *tp,
537 xfs_fsblock_t bno, 537 xfs_fsblock_t bno,
538 xfs_filblks_t len, 538 xfs_filblks_t len,
539 struct xfs_owner_info *oinfo, 539 const struct xfs_owner_info *oinfo,
540 bool skip_discard) 540 bool skip_discard)
541{ 541{
542 struct xfs_extent_free_item *new; /* new element */ 542 struct xfs_extent_free_item *new; /* new element */
@@ -564,7 +564,7 @@ __xfs_bmap_add_free(
564 if (oinfo) 564 if (oinfo)
565 new->xefi_oinfo = *oinfo; 565 new->xefi_oinfo = *oinfo;
566 else 566 else
567 xfs_rmap_skip_owner_update(&new->xefi_oinfo); 567 new->xefi_oinfo = XFS_RMAP_OINFO_SKIP_UPDATE;
568 new->xefi_skip_discard = skip_discard; 568 new->xefi_skip_discard = skip_discard;
569 trace_xfs_bmap_free_defer(tp->t_mountp, 569 trace_xfs_bmap_free_defer(tp->t_mountp,
570 XFS_FSB_TO_AGNO(tp->t_mountp, bno), 0, 570 XFS_FSB_TO_AGNO(tp->t_mountp, bno), 0,
@@ -3453,7 +3453,7 @@ xfs_bmap_btalloc(
3453 args.tp = ap->tp; 3453 args.tp = ap->tp;
3454 args.mp = mp; 3454 args.mp = mp;
3455 args.fsbno = ap->blkno; 3455 args.fsbno = ap->blkno;
3456 xfs_rmap_skip_owner_update(&args.oinfo); 3456 args.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE;
3457 3457
3458 /* Trim the allocation back to the maximum an AG can fit. */ 3458 /* Trim the allocation back to the maximum an AG can fit. */
3459 args.maxlen = min(ap->length, mp->m_ag_max_usable); 3459 args.maxlen = min(ap->length, mp->m_ag_max_usable);
diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h
index 488dc8860fd7..09d3ea97cc15 100644
--- a/fs/xfs/libxfs/xfs_bmap.h
+++ b/fs/xfs/libxfs/xfs_bmap.h
@@ -186,7 +186,7 @@ int xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd);
186int xfs_bmap_set_attrforkoff(struct xfs_inode *ip, int size, int *version); 186int xfs_bmap_set_attrforkoff(struct xfs_inode *ip, int size, int *version);
187void xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork); 187void xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork);
188void __xfs_bmap_add_free(struct xfs_trans *tp, xfs_fsblock_t bno, 188void __xfs_bmap_add_free(struct xfs_trans *tp, xfs_fsblock_t bno,
189 xfs_filblks_t len, struct xfs_owner_info *oinfo, 189 xfs_filblks_t len, const struct xfs_owner_info *oinfo,
190 bool skip_discard); 190 bool skip_discard);
191void xfs_bmap_compute_maxlevels(struct xfs_mount *mp, int whichfork); 191void xfs_bmap_compute_maxlevels(struct xfs_mount *mp, int whichfork);
192int xfs_bmap_first_unused(struct xfs_trans *tp, struct xfs_inode *ip, 192int xfs_bmap_first_unused(struct xfs_trans *tp, struct xfs_inode *ip,
@@ -234,7 +234,7 @@ xfs_bmap_add_free(
234 struct xfs_trans *tp, 234 struct xfs_trans *tp,
235 xfs_fsblock_t bno, 235 xfs_fsblock_t bno,
236 xfs_filblks_t len, 236 xfs_filblks_t len,
237 struct xfs_owner_info *oinfo) 237 const struct xfs_owner_info *oinfo)
238{ 238{
239 __xfs_bmap_add_free(tp, bno, len, oinfo, false); 239 __xfs_bmap_add_free(tp, bno, len, oinfo, false);
240} 240}
diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c
index e792b167150a..94f00427de98 100644
--- a/fs/xfs/libxfs/xfs_defer.c
+++ b/fs/xfs/libxfs/xfs_defer.c
@@ -172,7 +172,13 @@
172 * reoccur. 172 * reoccur.
173 */ 173 */
174 174
175static const struct xfs_defer_op_type *defer_op_types[XFS_DEFER_OPS_TYPE_MAX]; 175static const struct xfs_defer_op_type *defer_op_types[] = {
176 [XFS_DEFER_OPS_TYPE_BMAP] = &xfs_bmap_update_defer_type,
177 [XFS_DEFER_OPS_TYPE_REFCOUNT] = &xfs_refcount_update_defer_type,
178 [XFS_DEFER_OPS_TYPE_RMAP] = &xfs_rmap_update_defer_type,
179 [XFS_DEFER_OPS_TYPE_FREE] = &xfs_extent_free_defer_type,
180 [XFS_DEFER_OPS_TYPE_AGFL_FREE] = &xfs_agfl_free_defer_type,
181};
176 182
177/* 183/*
178 * For each pending item in the intake list, log its intent item and the 184 * For each pending item in the intake list, log its intent item and the
@@ -185,15 +191,15 @@ xfs_defer_create_intents(
185{ 191{
186 struct list_head *li; 192 struct list_head *li;
187 struct xfs_defer_pending *dfp; 193 struct xfs_defer_pending *dfp;
194 const struct xfs_defer_op_type *ops;
188 195
189 list_for_each_entry(dfp, &tp->t_dfops, dfp_list) { 196 list_for_each_entry(dfp, &tp->t_dfops, dfp_list) {
190 dfp->dfp_intent = dfp->dfp_type->create_intent(tp, 197 ops = defer_op_types[dfp->dfp_type];
191 dfp->dfp_count); 198 dfp->dfp_intent = ops->create_intent(tp, dfp->dfp_count);
192 trace_xfs_defer_create_intent(tp->t_mountp, dfp); 199 trace_xfs_defer_create_intent(tp->t_mountp, dfp);
193 list_sort(tp->t_mountp, &dfp->dfp_work, 200 list_sort(tp->t_mountp, &dfp->dfp_work, ops->diff_items);
194 dfp->dfp_type->diff_items);
195 list_for_each(li, &dfp->dfp_work) 201 list_for_each(li, &dfp->dfp_work)
196 dfp->dfp_type->log_item(tp, dfp->dfp_intent, li); 202 ops->log_item(tp, dfp->dfp_intent, li);
197 } 203 }
198} 204}
199 205
@@ -204,14 +210,16 @@ xfs_defer_trans_abort(
204 struct list_head *dop_pending) 210 struct list_head *dop_pending)
205{ 211{
206 struct xfs_defer_pending *dfp; 212 struct xfs_defer_pending *dfp;
213 const struct xfs_defer_op_type *ops;
207 214
208 trace_xfs_defer_trans_abort(tp, _RET_IP_); 215 trace_xfs_defer_trans_abort(tp, _RET_IP_);
209 216
210 /* Abort intent items that don't have a done item. */ 217 /* Abort intent items that don't have a done item. */
211 list_for_each_entry(dfp, dop_pending, dfp_list) { 218 list_for_each_entry(dfp, dop_pending, dfp_list) {
219 ops = defer_op_types[dfp->dfp_type];
212 trace_xfs_defer_pending_abort(tp->t_mountp, dfp); 220 trace_xfs_defer_pending_abort(tp->t_mountp, dfp);
213 if (dfp->dfp_intent && !dfp->dfp_done) { 221 if (dfp->dfp_intent && !dfp->dfp_done) {
214 dfp->dfp_type->abort_intent(dfp->dfp_intent); 222 ops->abort_intent(dfp->dfp_intent);
215 dfp->dfp_intent = NULL; 223 dfp->dfp_intent = NULL;
216 } 224 }
217 } 225 }
@@ -315,18 +323,20 @@ xfs_defer_cancel_list(
315 struct xfs_defer_pending *pli; 323 struct xfs_defer_pending *pli;
316 struct list_head *pwi; 324 struct list_head *pwi;
317 struct list_head *n; 325 struct list_head *n;
326 const struct xfs_defer_op_type *ops;
318 327
319 /* 328 /*
320 * Free the pending items. Caller should already have arranged 329 * Free the pending items. Caller should already have arranged
321 * for the intent items to be released. 330 * for the intent items to be released.
322 */ 331 */
323 list_for_each_entry_safe(dfp, pli, dop_list, dfp_list) { 332 list_for_each_entry_safe(dfp, pli, dop_list, dfp_list) {
333 ops = defer_op_types[dfp->dfp_type];
324 trace_xfs_defer_cancel_list(mp, dfp); 334 trace_xfs_defer_cancel_list(mp, dfp);
325 list_del(&dfp->dfp_list); 335 list_del(&dfp->dfp_list);
326 list_for_each_safe(pwi, n, &dfp->dfp_work) { 336 list_for_each_safe(pwi, n, &dfp->dfp_work) {
327 list_del(pwi); 337 list_del(pwi);
328 dfp->dfp_count--; 338 dfp->dfp_count--;
329 dfp->dfp_type->cancel_item(pwi); 339 ops->cancel_item(pwi);
330 } 340 }
331 ASSERT(dfp->dfp_count == 0); 341 ASSERT(dfp->dfp_count == 0);
332 kmem_free(dfp); 342 kmem_free(dfp);
@@ -350,7 +360,7 @@ xfs_defer_finish_noroll(
350 struct list_head *n; 360 struct list_head *n;
351 void *state; 361 void *state;
352 int error = 0; 362 int error = 0;
353 void (*cleanup_fn)(struct xfs_trans *, void *, int); 363 const struct xfs_defer_op_type *ops;
354 LIST_HEAD(dop_pending); 364 LIST_HEAD(dop_pending);
355 365
356 ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); 366 ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES);
@@ -373,18 +383,18 @@ xfs_defer_finish_noroll(
373 /* Log an intent-done item for the first pending item. */ 383 /* Log an intent-done item for the first pending item. */
374 dfp = list_first_entry(&dop_pending, struct xfs_defer_pending, 384 dfp = list_first_entry(&dop_pending, struct xfs_defer_pending,
375 dfp_list); 385 dfp_list);
386 ops = defer_op_types[dfp->dfp_type];
376 trace_xfs_defer_pending_finish((*tp)->t_mountp, dfp); 387 trace_xfs_defer_pending_finish((*tp)->t_mountp, dfp);
377 dfp->dfp_done = dfp->dfp_type->create_done(*tp, dfp->dfp_intent, 388 dfp->dfp_done = ops->create_done(*tp, dfp->dfp_intent,
378 dfp->dfp_count); 389 dfp->dfp_count);
379 cleanup_fn = dfp->dfp_type->finish_cleanup;
380 390
381 /* Finish the work items. */ 391 /* Finish the work items. */
382 state = NULL; 392 state = NULL;
383 list_for_each_safe(li, n, &dfp->dfp_work) { 393 list_for_each_safe(li, n, &dfp->dfp_work) {
384 list_del(li); 394 list_del(li);
385 dfp->dfp_count--; 395 dfp->dfp_count--;
386 error = dfp->dfp_type->finish_item(*tp, li, 396 error = ops->finish_item(*tp, li, dfp->dfp_done,
387 dfp->dfp_done, &state); 397 &state);
388 if (error == -EAGAIN) { 398 if (error == -EAGAIN) {
389 /* 399 /*
390 * Caller wants a fresh transaction; 400 * Caller wants a fresh transaction;
@@ -400,8 +410,8 @@ xfs_defer_finish_noroll(
400 * xfs_defer_cancel will take care of freeing 410 * xfs_defer_cancel will take care of freeing
401 * all these lists and stuff. 411 * all these lists and stuff.
402 */ 412 */
403 if (cleanup_fn) 413 if (ops->finish_cleanup)
404 cleanup_fn(*tp, state, error); 414 ops->finish_cleanup(*tp, state, error);
405 goto out; 415 goto out;
406 } 416 }
407 } 417 }
@@ -413,20 +423,19 @@ xfs_defer_finish_noroll(
413 * a Fresh Transaction while Finishing 423 * a Fresh Transaction while Finishing
414 * Deferred Work" above. 424 * Deferred Work" above.
415 */ 425 */
416 dfp->dfp_intent = dfp->dfp_type->create_intent(*tp, 426 dfp->dfp_intent = ops->create_intent(*tp,
417 dfp->dfp_count); 427 dfp->dfp_count);
418 dfp->dfp_done = NULL; 428 dfp->dfp_done = NULL;
419 list_for_each(li, &dfp->dfp_work) 429 list_for_each(li, &dfp->dfp_work)
420 dfp->dfp_type->log_item(*tp, dfp->dfp_intent, 430 ops->log_item(*tp, dfp->dfp_intent, li);
421 li);
422 } else { 431 } else {
423 /* Done with the dfp, free it. */ 432 /* Done with the dfp, free it. */
424 list_del(&dfp->dfp_list); 433 list_del(&dfp->dfp_list);
425 kmem_free(dfp); 434 kmem_free(dfp);
426 } 435 }
427 436
428 if (cleanup_fn) 437 if (ops->finish_cleanup)
429 cleanup_fn(*tp, state, error); 438 ops->finish_cleanup(*tp, state, error);
430 } 439 }
431 440
432out: 441out:
@@ -486,8 +495,10 @@ xfs_defer_add(
486 struct list_head *li) 495 struct list_head *li)
487{ 496{
488 struct xfs_defer_pending *dfp = NULL; 497 struct xfs_defer_pending *dfp = NULL;
498 const struct xfs_defer_op_type *ops;
489 499
490 ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); 500 ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
501 BUILD_BUG_ON(ARRAY_SIZE(defer_op_types) != XFS_DEFER_OPS_TYPE_MAX);
491 502
492 /* 503 /*
493 * Add the item to a pending item at the end of the intake list. 504 * Add the item to a pending item at the end of the intake list.
@@ -497,15 +508,15 @@ xfs_defer_add(
497 if (!list_empty(&tp->t_dfops)) { 508 if (!list_empty(&tp->t_dfops)) {
498 dfp = list_last_entry(&tp->t_dfops, 509 dfp = list_last_entry(&tp->t_dfops,
499 struct xfs_defer_pending, dfp_list); 510 struct xfs_defer_pending, dfp_list);
500 if (dfp->dfp_type->type != type || 511 ops = defer_op_types[dfp->dfp_type];
501 (dfp->dfp_type->max_items && 512 if (dfp->dfp_type != type ||
502 dfp->dfp_count >= dfp->dfp_type->max_items)) 513 (ops->max_items && dfp->dfp_count >= ops->max_items))
503 dfp = NULL; 514 dfp = NULL;
504 } 515 }
505 if (!dfp) { 516 if (!dfp) {
506 dfp = kmem_alloc(sizeof(struct xfs_defer_pending), 517 dfp = kmem_alloc(sizeof(struct xfs_defer_pending),
507 KM_SLEEP | KM_NOFS); 518 KM_SLEEP | KM_NOFS);
508 dfp->dfp_type = defer_op_types[type]; 519 dfp->dfp_type = type;
509 dfp->dfp_intent = NULL; 520 dfp->dfp_intent = NULL;
510 dfp->dfp_done = NULL; 521 dfp->dfp_done = NULL;
511 dfp->dfp_count = 0; 522 dfp->dfp_count = 0;
@@ -517,14 +528,6 @@ xfs_defer_add(
517 dfp->dfp_count++; 528 dfp->dfp_count++;
518} 529}
519 530
520/* Initialize a deferred operation list. */
521void
522xfs_defer_init_op_type(
523 const struct xfs_defer_op_type *type)
524{
525 defer_op_types[type->type] = type;
526}
527
528/* 531/*
529 * Move deferred ops from one transaction to another and reset the source to 532 * Move deferred ops from one transaction to another and reset the source to
530 * initial state. This is primarily used to carry state forward across 533 * initial state. This is primarily used to carry state forward across
diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h
index 2584a5b95b0d..7c28d7608ac6 100644
--- a/fs/xfs/libxfs/xfs_defer.h
+++ b/fs/xfs/libxfs/xfs_defer.h
@@ -9,20 +9,6 @@
9struct xfs_defer_op_type; 9struct xfs_defer_op_type;
10 10
11/* 11/*
12 * Save a log intent item and a list of extents, so that we can replay
13 * whatever action had to happen to the extent list and file the log done
14 * item.
15 */
16struct xfs_defer_pending {
17 const struct xfs_defer_op_type *dfp_type; /* function pointers */
18 struct list_head dfp_list; /* pending items */
19 void *dfp_intent; /* log intent item */
20 void *dfp_done; /* log done item */
21 struct list_head dfp_work; /* work items */
22 unsigned int dfp_count; /* # extent items */
23};
24
25/*
26 * Header for deferred operation list. 12 * Header for deferred operation list.
27 */ 13 */
28enum xfs_defer_ops_type { 14enum xfs_defer_ops_type {
@@ -34,6 +20,20 @@ enum xfs_defer_ops_type {
34 XFS_DEFER_OPS_TYPE_MAX, 20 XFS_DEFER_OPS_TYPE_MAX,
35}; 21};
36 22
23/*
24 * Save a log intent item and a list of extents, so that we can replay
25 * whatever action had to happen to the extent list and file the log done
26 * item.
27 */
28struct xfs_defer_pending {
29 struct list_head dfp_list; /* pending items */
30 struct list_head dfp_work; /* work items */
31 void *dfp_intent; /* log intent item */
32 void *dfp_done; /* log done item */
33 unsigned int dfp_count; /* # extent items */
34 enum xfs_defer_ops_type dfp_type;
35};
36
37void xfs_defer_add(struct xfs_trans *tp, enum xfs_defer_ops_type type, 37void xfs_defer_add(struct xfs_trans *tp, enum xfs_defer_ops_type type,
38 struct list_head *h); 38 struct list_head *h);
39int xfs_defer_finish_noroll(struct xfs_trans **tp); 39int xfs_defer_finish_noroll(struct xfs_trans **tp);
@@ -43,8 +43,6 @@ void xfs_defer_move(struct xfs_trans *dtp, struct xfs_trans *stp);
43 43
44/* Description of a deferred type. */ 44/* Description of a deferred type. */
45struct xfs_defer_op_type { 45struct xfs_defer_op_type {
46 enum xfs_defer_ops_type type;
47 unsigned int max_items;
48 void (*abort_intent)(void *); 46 void (*abort_intent)(void *);
49 void *(*create_done)(struct xfs_trans *, void *, unsigned int); 47 void *(*create_done)(struct xfs_trans *, void *, unsigned int);
50 int (*finish_item)(struct xfs_trans *, struct list_head *, void *, 48 int (*finish_item)(struct xfs_trans *, struct list_head *, void *,
@@ -54,8 +52,13 @@ struct xfs_defer_op_type {
54 int (*diff_items)(void *, struct list_head *, struct list_head *); 52 int (*diff_items)(void *, struct list_head *, struct list_head *);
55 void *(*create_intent)(struct xfs_trans *, uint); 53 void *(*create_intent)(struct xfs_trans *, uint);
56 void (*log_item)(struct xfs_trans *, void *, struct list_head *); 54 void (*log_item)(struct xfs_trans *, void *, struct list_head *);
55 unsigned int max_items;
57}; 56};
58 57
59void xfs_defer_init_op_type(const struct xfs_defer_op_type *type); 58extern const struct xfs_defer_op_type xfs_bmap_update_defer_type;
59extern const struct xfs_defer_op_type xfs_refcount_update_defer_type;
60extern const struct xfs_defer_op_type xfs_rmap_update_defer_type;
61extern const struct xfs_defer_op_type xfs_extent_free_defer_type;
62extern const struct xfs_defer_op_type xfs_agfl_free_defer_type;
60 63
61#endif /* __XFS_DEFER_H__ */ 64#endif /* __XFS_DEFER_H__ */
diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index 9995d5ae380b..9bb3c48843ec 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -916,6 +916,9 @@ static inline uint xfs_dinode_size(int version)
916 916
917/* 917/*
918 * Values for di_format 918 * Values for di_format
919 *
920 * This enum is used in string mapping in xfs_trace.h; please keep the
921 * TRACE_DEFINE_ENUMs for it up to date.
919 */ 922 */
920typedef enum xfs_dinode_fmt { 923typedef enum xfs_dinode_fmt {
921 XFS_DINODE_FMT_DEV, /* xfs_dev_t */ 924 XFS_DINODE_FMT_DEV, /* xfs_dev_t */
@@ -925,6 +928,13 @@ typedef enum xfs_dinode_fmt {
925 XFS_DINODE_FMT_UUID /* added long ago, but never used */ 928 XFS_DINODE_FMT_UUID /* added long ago, but never used */
926} xfs_dinode_fmt_t; 929} xfs_dinode_fmt_t;
927 930
931#define XFS_INODE_FORMAT_STR \
932 { XFS_DINODE_FMT_DEV, "dev" }, \
933 { XFS_DINODE_FMT_LOCAL, "local" }, \
934 { XFS_DINODE_FMT_EXTENTS, "extent" }, \
935 { XFS_DINODE_FMT_BTREE, "btree" }, \
936 { XFS_DINODE_FMT_UUID, "uuid" }
937
928/* 938/*
929 * Inode minimum and maximum sizes. 939 * Inode minimum and maximum sizes.
930 */ 940 */
@@ -1083,6 +1093,8 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
1083 ((i) & XFS_INO_MASK(XFS_INO_OFFSET_BITS(mp))) 1093 ((i) & XFS_INO_MASK(XFS_INO_OFFSET_BITS(mp)))
1084#define XFS_OFFBNO_TO_AGINO(mp,b,o) \ 1094#define XFS_OFFBNO_TO_AGINO(mp,b,o) \
1085 ((xfs_agino_t)(((b) << XFS_INO_OFFSET_BITS(mp)) | (o))) 1095 ((xfs_agino_t)(((b) << XFS_INO_OFFSET_BITS(mp)) | (o)))
1096#define XFS_FSB_TO_INO(mp, b) ((xfs_ino_t)((b) << XFS_INO_OFFSET_BITS(mp)))
1097#define XFS_AGB_TO_AGINO(mp, b) ((xfs_agino_t)((b) << XFS_INO_OFFSET_BITS(mp)))
1086 1098
1087#define XFS_MAXINUMBER ((xfs_ino_t)((1ULL << 56) - 1ULL)) 1099#define XFS_MAXINUMBER ((xfs_ino_t)((1ULL << 56) - 1ULL))
1088#define XFS_MAXINUMBER_32 ((xfs_ino_t)((1ULL << 32) - 1ULL)) 1100#define XFS_MAXINUMBER_32 ((xfs_ino_t)((1ULL << 32) - 1ULL))
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
index a8f6db735d5d..d32152fc8a6c 100644
--- a/fs/xfs/libxfs/xfs_ialloc.c
+++ b/fs/xfs/libxfs/xfs_ialloc.c
@@ -288,7 +288,7 @@ xfs_ialloc_inode_init(
288{ 288{
289 struct xfs_buf *fbuf; 289 struct xfs_buf *fbuf;
290 struct xfs_dinode *free; 290 struct xfs_dinode *free;
291 int nbufs, blks_per_cluster, inodes_per_cluster; 291 int nbufs;
292 int version; 292 int version;
293 int i, j; 293 int i, j;
294 xfs_daddr_t d; 294 xfs_daddr_t d;
@@ -299,9 +299,7 @@ xfs_ialloc_inode_init(
299 * sizes, manipulate the inodes in buffers which are multiples of the 299 * sizes, manipulate the inodes in buffers which are multiples of the
300 * blocks size. 300 * blocks size.
301 */ 301 */
302 blks_per_cluster = xfs_icluster_size_fsb(mp); 302 nbufs = length / mp->m_blocks_per_cluster;
303 inodes_per_cluster = blks_per_cluster << mp->m_sb.sb_inopblog;
304 nbufs = length / blks_per_cluster;
305 303
306 /* 304 /*
307 * Figure out what version number to use in the inodes we create. If 305 * Figure out what version number to use in the inodes we create. If
@@ -312,7 +310,7 @@ xfs_ialloc_inode_init(
312 * 310 *
313 * For v3 inodes, we also need to write the inode number into the inode, 311 * For v3 inodes, we also need to write the inode number into the inode,
314 * so calculate the first inode number of the chunk here as 312 * so calculate the first inode number of the chunk here as
315 * XFS_OFFBNO_TO_AGINO() only works within a filesystem block, not 313 * XFS_AGB_TO_AGINO() only works within a filesystem block, not
316 * across multiple filesystem blocks (such as a cluster) and so cannot 314 * across multiple filesystem blocks (such as a cluster) and so cannot
317 * be used in the cluster buffer loop below. 315 * be used in the cluster buffer loop below.
318 * 316 *
@@ -324,8 +322,7 @@ xfs_ialloc_inode_init(
324 */ 322 */
325 if (xfs_sb_version_hascrc(&mp->m_sb)) { 323 if (xfs_sb_version_hascrc(&mp->m_sb)) {
326 version = 3; 324 version = 3;
327 ino = XFS_AGINO_TO_INO(mp, agno, 325 ino = XFS_AGINO_TO_INO(mp, agno, XFS_AGB_TO_AGINO(mp, agbno));
328 XFS_OFFBNO_TO_AGINO(mp, agbno, 0));
329 326
330 /* 327 /*
331 * log the initialisation that is about to take place as an 328 * log the initialisation that is about to take place as an
@@ -345,9 +342,10 @@ xfs_ialloc_inode_init(
345 /* 342 /*
346 * Get the block. 343 * Get the block.
347 */ 344 */
348 d = XFS_AGB_TO_DADDR(mp, agno, agbno + (j * blks_per_cluster)); 345 d = XFS_AGB_TO_DADDR(mp, agno, agbno +
346 (j * mp->m_blocks_per_cluster));
349 fbuf = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, 347 fbuf = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
350 mp->m_bsize * blks_per_cluster, 348 mp->m_bsize * mp->m_blocks_per_cluster,
351 XBF_UNMAPPED); 349 XBF_UNMAPPED);
352 if (!fbuf) 350 if (!fbuf)
353 return -ENOMEM; 351 return -ENOMEM;
@@ -355,7 +353,7 @@ xfs_ialloc_inode_init(
355 /* Initialize the inode buffers and log them appropriately. */ 353 /* Initialize the inode buffers and log them appropriately. */
356 fbuf->b_ops = &xfs_inode_buf_ops; 354 fbuf->b_ops = &xfs_inode_buf_ops;
357 xfs_buf_zero(fbuf, 0, BBTOB(fbuf->b_length)); 355 xfs_buf_zero(fbuf, 0, BBTOB(fbuf->b_length));
358 for (i = 0; i < inodes_per_cluster; i++) { 356 for (i = 0; i < mp->m_inodes_per_cluster; i++) {
359 int ioffset = i << mp->m_sb.sb_inodelog; 357 int ioffset = i << mp->m_sb.sb_inodelog;
360 uint isize = xfs_dinode_size(version); 358 uint isize = xfs_dinode_size(version);
361 359
@@ -445,7 +443,7 @@ xfs_align_sparse_ino(
445 return; 443 return;
446 444
447 /* calculate the inode offset and align startino */ 445 /* calculate the inode offset and align startino */
448 offset = mod << mp->m_sb.sb_inopblog; 446 offset = XFS_AGB_TO_AGINO(mp, mod);
449 *startino -= offset; 447 *startino -= offset;
450 448
451 /* 449 /*
@@ -641,7 +639,7 @@ xfs_ialloc_ag_alloc(
641 args.tp = tp; 639 args.tp = tp;
642 args.mp = tp->t_mountp; 640 args.mp = tp->t_mountp;
643 args.fsbno = NULLFSBLOCK; 641 args.fsbno = NULLFSBLOCK;
644 xfs_rmap_ag_owner(&args.oinfo, XFS_RMAP_OWN_INODES); 642 args.oinfo = XFS_RMAP_OINFO_INODES;
645 643
646#ifdef DEBUG 644#ifdef DEBUG
647 /* randomly do sparse inode allocations */ 645 /* randomly do sparse inode allocations */
@@ -692,7 +690,7 @@ xfs_ialloc_ag_alloc(
692 * but not to use them in the actual exact allocation. 690 * but not to use them in the actual exact allocation.
693 */ 691 */
694 args.alignment = 1; 692 args.alignment = 1;
695 args.minalignslop = xfs_ialloc_cluster_alignment(args.mp) - 1; 693 args.minalignslop = args.mp->m_cluster_align - 1;
696 694
697 /* Allow space for the inode btree to split. */ 695 /* Allow space for the inode btree to split. */
698 args.minleft = args.mp->m_in_maxlevels - 1; 696 args.minleft = args.mp->m_in_maxlevels - 1;
@@ -727,7 +725,7 @@ xfs_ialloc_ag_alloc(
727 args.alignment = args.mp->m_dalign; 725 args.alignment = args.mp->m_dalign;
728 isaligned = 1; 726 isaligned = 1;
729 } else 727 } else
730 args.alignment = xfs_ialloc_cluster_alignment(args.mp); 728 args.alignment = args.mp->m_cluster_align;
731 /* 729 /*
732 * Need to figure out where to allocate the inode blocks. 730 * Need to figure out where to allocate the inode blocks.
733 * Ideally they should be spaced out through the a.g. 731 * Ideally they should be spaced out through the a.g.
@@ -756,7 +754,7 @@ xfs_ialloc_ag_alloc(
756 args.type = XFS_ALLOCTYPE_NEAR_BNO; 754 args.type = XFS_ALLOCTYPE_NEAR_BNO;
757 args.agbno = be32_to_cpu(agi->agi_root); 755 args.agbno = be32_to_cpu(agi->agi_root);
758 args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno); 756 args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
759 args.alignment = xfs_ialloc_cluster_alignment(args.mp); 757 args.alignment = args.mp->m_cluster_align;
760 if ((error = xfs_alloc_vextent(&args))) 758 if ((error = xfs_alloc_vextent(&args)))
761 return error; 759 return error;
762 } 760 }
@@ -797,7 +795,7 @@ sparse_alloc:
797 if (error) 795 if (error)
798 return error; 796 return error;
799 797
800 newlen = args.len << args.mp->m_sb.sb_inopblog; 798 newlen = XFS_AGB_TO_AGINO(args.mp, args.len);
801 ASSERT(newlen <= XFS_INODES_PER_CHUNK); 799 ASSERT(newlen <= XFS_INODES_PER_CHUNK);
802 allocmask = (1 << (newlen / XFS_INODES_PER_HOLEMASK_BIT)) - 1; 800 allocmask = (1 << (newlen / XFS_INODES_PER_HOLEMASK_BIT)) - 1;
803 } 801 }
@@ -825,7 +823,7 @@ sparse_alloc:
825 /* 823 /*
826 * Convert the results. 824 * Convert the results.
827 */ 825 */
828 newino = XFS_OFFBNO_TO_AGINO(args.mp, args.agbno, 0); 826 newino = XFS_AGB_TO_AGINO(args.mp, args.agbno);
829 827
830 if (xfs_inobt_issparse(~allocmask)) { 828 if (xfs_inobt_issparse(~allocmask)) {
831 /* 829 /*
@@ -1019,7 +1017,7 @@ xfs_ialloc_ag_select(
1019 */ 1017 */
1020 ineed = mp->m_ialloc_min_blks; 1018 ineed = mp->m_ialloc_min_blks;
1021 if (flags && ineed > 1) 1019 if (flags && ineed > 1)
1022 ineed += xfs_ialloc_cluster_alignment(mp); 1020 ineed += mp->m_cluster_align;
1023 longest = pag->pagf_longest; 1021 longest = pag->pagf_longest;
1024 if (!longest) 1022 if (!longest)
1025 longest = pag->pagf_flcount > 0; 1023 longest = pag->pagf_flcount > 0;
@@ -1849,14 +1847,12 @@ xfs_difree_inode_chunk(
1849 int nextbit; 1847 int nextbit;
1850 xfs_agblock_t agbno; 1848 xfs_agblock_t agbno;
1851 int contigblk; 1849 int contigblk;
1852 struct xfs_owner_info oinfo;
1853 DECLARE_BITMAP(holemask, XFS_INOBT_HOLEMASK_BITS); 1850 DECLARE_BITMAP(holemask, XFS_INOBT_HOLEMASK_BITS);
1854 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INODES);
1855 1851
1856 if (!xfs_inobt_issparse(rec->ir_holemask)) { 1852 if (!xfs_inobt_issparse(rec->ir_holemask)) {
1857 /* not sparse, calculate extent info directly */ 1853 /* not sparse, calculate extent info directly */
1858 xfs_bmap_add_free(tp, XFS_AGB_TO_FSB(mp, agno, sagbno), 1854 xfs_bmap_add_free(tp, XFS_AGB_TO_FSB(mp, agno, sagbno),
1859 mp->m_ialloc_blks, &oinfo); 1855 mp->m_ialloc_blks, &XFS_RMAP_OINFO_INODES);
1860 return; 1856 return;
1861 } 1857 }
1862 1858
@@ -1900,7 +1896,7 @@ xfs_difree_inode_chunk(
1900 ASSERT(agbno % mp->m_sb.sb_spino_align == 0); 1896 ASSERT(agbno % mp->m_sb.sb_spino_align == 0);
1901 ASSERT(contigblk % mp->m_sb.sb_spino_align == 0); 1897 ASSERT(contigblk % mp->m_sb.sb_spino_align == 0);
1902 xfs_bmap_add_free(tp, XFS_AGB_TO_FSB(mp, agno, agbno), 1898 xfs_bmap_add_free(tp, XFS_AGB_TO_FSB(mp, agno, agbno),
1903 contigblk, &oinfo); 1899 contigblk, &XFS_RMAP_OINFO_INODES);
1904 1900
1905 /* reset range to current bit and carry on... */ 1901 /* reset range to current bit and carry on... */
1906 startidx = endidx = nextbit; 1902 startidx = endidx = nextbit;
@@ -2292,7 +2288,6 @@ xfs_imap(
2292 xfs_agblock_t agbno; /* block number of inode in the alloc group */ 2288 xfs_agblock_t agbno; /* block number of inode in the alloc group */
2293 xfs_agino_t agino; /* inode number within alloc group */ 2289 xfs_agino_t agino; /* inode number within alloc group */
2294 xfs_agnumber_t agno; /* allocation group number */ 2290 xfs_agnumber_t agno; /* allocation group number */
2295 int blks_per_cluster; /* num blocks per inode cluster */
2296 xfs_agblock_t chunk_agbno; /* first block in inode chunk */ 2291 xfs_agblock_t chunk_agbno; /* first block in inode chunk */
2297 xfs_agblock_t cluster_agbno; /* first block in inode cluster */ 2292 xfs_agblock_t cluster_agbno; /* first block in inode cluster */
2298 int error; /* error code */ 2293 int error; /* error code */
@@ -2338,8 +2333,6 @@ xfs_imap(
2338 return -EINVAL; 2333 return -EINVAL;
2339 } 2334 }
2340 2335
2341 blks_per_cluster = xfs_icluster_size_fsb(mp);
2342
2343 /* 2336 /*
2344 * For bulkstat and handle lookups, we have an untrusted inode number 2337 * For bulkstat and handle lookups, we have an untrusted inode number
2345 * that we have to verify is valid. We cannot do this just by reading 2338 * that we have to verify is valid. We cannot do this just by reading
@@ -2359,7 +2352,7 @@ xfs_imap(
2359 * If the inode cluster size is the same as the blocksize or 2352 * If the inode cluster size is the same as the blocksize or
2360 * smaller we get to the buffer by simple arithmetics. 2353 * smaller we get to the buffer by simple arithmetics.
2361 */ 2354 */
2362 if (blks_per_cluster == 1) { 2355 if (mp->m_blocks_per_cluster == 1) {
2363 offset = XFS_INO_TO_OFFSET(mp, ino); 2356 offset = XFS_INO_TO_OFFSET(mp, ino);
2364 ASSERT(offset < mp->m_sb.sb_inopblock); 2357 ASSERT(offset < mp->m_sb.sb_inopblock);
2365 2358
@@ -2388,12 +2381,13 @@ xfs_imap(
2388out_map: 2381out_map:
2389 ASSERT(agbno >= chunk_agbno); 2382 ASSERT(agbno >= chunk_agbno);
2390 cluster_agbno = chunk_agbno + 2383 cluster_agbno = chunk_agbno +
2391 ((offset_agbno / blks_per_cluster) * blks_per_cluster); 2384 ((offset_agbno / mp->m_blocks_per_cluster) *
2385 mp->m_blocks_per_cluster);
2392 offset = ((agbno - cluster_agbno) * mp->m_sb.sb_inopblock) + 2386 offset = ((agbno - cluster_agbno) * mp->m_sb.sb_inopblock) +
2393 XFS_INO_TO_OFFSET(mp, ino); 2387 XFS_INO_TO_OFFSET(mp, ino);
2394 2388
2395 imap->im_blkno = XFS_AGB_TO_DADDR(mp, agno, cluster_agbno); 2389 imap->im_blkno = XFS_AGB_TO_DADDR(mp, agno, cluster_agbno);
2396 imap->im_len = XFS_FSB_TO_BB(mp, blks_per_cluster); 2390 imap->im_len = XFS_FSB_TO_BB(mp, mp->m_blocks_per_cluster);
2397 imap->im_boffset = (unsigned short)(offset << mp->m_sb.sb_inodelog); 2391 imap->im_boffset = (unsigned short)(offset << mp->m_sb.sb_inodelog);
2398 2392
2399 /* 2393 /*
@@ -2726,8 +2720,8 @@ xfs_ialloc_has_inodes_at_extent(
2726 xfs_agino_t low; 2720 xfs_agino_t low;
2727 xfs_agino_t high; 2721 xfs_agino_t high;
2728 2722
2729 low = XFS_OFFBNO_TO_AGINO(cur->bc_mp, bno, 0); 2723 low = XFS_AGB_TO_AGINO(cur->bc_mp, bno);
2730 high = XFS_OFFBNO_TO_AGINO(cur->bc_mp, bno + len, 0) - 1; 2724 high = XFS_AGB_TO_AGINO(cur->bc_mp, bno + len) - 1;
2731 2725
2732 return xfs_ialloc_has_inode_record(cur, low, high, exists); 2726 return xfs_ialloc_has_inode_record(cur, low, high, exists);
2733} 2727}
diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c
index 7fbf8af0b159..9b25e7a0df47 100644
--- a/fs/xfs/libxfs/xfs_ialloc_btree.c
+++ b/fs/xfs/libxfs/xfs_ialloc_btree.c
@@ -84,7 +84,7 @@ __xfs_inobt_alloc_block(
84 memset(&args, 0, sizeof(args)); 84 memset(&args, 0, sizeof(args));
85 args.tp = cur->bc_tp; 85 args.tp = cur->bc_tp;
86 args.mp = cur->bc_mp; 86 args.mp = cur->bc_mp;
87 xfs_rmap_ag_owner(&args.oinfo, XFS_RMAP_OWN_INOBT); 87 args.oinfo = XFS_RMAP_OINFO_INOBT;
88 args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, sbno); 88 args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, sbno);
89 args.minlen = 1; 89 args.minlen = 1;
90 args.maxlen = 1; 90 args.maxlen = 1;
@@ -136,12 +136,9 @@ __xfs_inobt_free_block(
136 struct xfs_buf *bp, 136 struct xfs_buf *bp,
137 enum xfs_ag_resv_type resv) 137 enum xfs_ag_resv_type resv)
138{ 138{
139 struct xfs_owner_info oinfo;
140
141 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INOBT);
142 return xfs_free_extent(cur->bc_tp, 139 return xfs_free_extent(cur->bc_tp,
143 XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(bp)), 1, 140 XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(bp)), 1,
144 &oinfo, resv); 141 &XFS_RMAP_OINFO_INOBT, resv);
145} 142}
146 143
147STATIC int 144STATIC int
diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c
index 1aaa01c97517..d9eab657b63e 100644
--- a/fs/xfs/libxfs/xfs_refcount_btree.c
+++ b/fs/xfs/libxfs/xfs_refcount_btree.c
@@ -70,7 +70,7 @@ xfs_refcountbt_alloc_block(
70 args.type = XFS_ALLOCTYPE_NEAR_BNO; 70 args.type = XFS_ALLOCTYPE_NEAR_BNO;
71 args.fsbno = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_private.a.agno, 71 args.fsbno = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_private.a.agno,
72 xfs_refc_block(args.mp)); 72 xfs_refc_block(args.mp));
73 xfs_rmap_ag_owner(&args.oinfo, XFS_RMAP_OWN_REFC); 73 args.oinfo = XFS_RMAP_OINFO_REFC;
74 args.minlen = args.maxlen = args.prod = 1; 74 args.minlen = args.maxlen = args.prod = 1;
75 args.resv = XFS_AG_RESV_METADATA; 75 args.resv = XFS_AG_RESV_METADATA;
76 76
@@ -106,15 +106,13 @@ xfs_refcountbt_free_block(
106 struct xfs_buf *agbp = cur->bc_private.a.agbp; 106 struct xfs_buf *agbp = cur->bc_private.a.agbp;
107 struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); 107 struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp);
108 xfs_fsblock_t fsbno = XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(bp)); 108 xfs_fsblock_t fsbno = XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(bp));
109 struct xfs_owner_info oinfo;
110 int error; 109 int error;
111 110
112 trace_xfs_refcountbt_free_block(cur->bc_mp, cur->bc_private.a.agno, 111 trace_xfs_refcountbt_free_block(cur->bc_mp, cur->bc_private.a.agno,
113 XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno), 1); 112 XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno), 1);
114 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_REFC);
115 be32_add_cpu(&agf->agf_refcount_blocks, -1); 113 be32_add_cpu(&agf->agf_refcount_blocks, -1);
116 xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_REFCOUNT_BLOCKS); 114 xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_REFCOUNT_BLOCKS);
117 error = xfs_free_extent(cur->bc_tp, fsbno, 1, &oinfo, 115 error = xfs_free_extent(cur->bc_tp, fsbno, 1, &XFS_RMAP_OINFO_REFC,
118 XFS_AG_RESV_METADATA); 116 XFS_AG_RESV_METADATA);
119 if (error) 117 if (error)
120 return error; 118 return error;
diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c
index 245af452840e..8ed885507dd8 100644
--- a/fs/xfs/libxfs/xfs_rmap.c
+++ b/fs/xfs/libxfs/xfs_rmap.c
@@ -458,21 +458,21 @@ out:
458 */ 458 */
459STATIC int 459STATIC int
460xfs_rmap_unmap( 460xfs_rmap_unmap(
461 struct xfs_btree_cur *cur, 461 struct xfs_btree_cur *cur,
462 xfs_agblock_t bno, 462 xfs_agblock_t bno,
463 xfs_extlen_t len, 463 xfs_extlen_t len,
464 bool unwritten, 464 bool unwritten,
465 struct xfs_owner_info *oinfo) 465 const struct xfs_owner_info *oinfo)
466{ 466{
467 struct xfs_mount *mp = cur->bc_mp; 467 struct xfs_mount *mp = cur->bc_mp;
468 struct xfs_rmap_irec ltrec; 468 struct xfs_rmap_irec ltrec;
469 uint64_t ltoff; 469 uint64_t ltoff;
470 int error = 0; 470 int error = 0;
471 int i; 471 int i;
472 uint64_t owner; 472 uint64_t owner;
473 uint64_t offset; 473 uint64_t offset;
474 unsigned int flags; 474 unsigned int flags;
475 bool ignore_off; 475 bool ignore_off;
476 476
477 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags); 477 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
478 ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) || 478 ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) ||
@@ -653,16 +653,16 @@ out_error:
653 */ 653 */
654int 654int
655xfs_rmap_free( 655xfs_rmap_free(
656 struct xfs_trans *tp, 656 struct xfs_trans *tp,
657 struct xfs_buf *agbp, 657 struct xfs_buf *agbp,
658 xfs_agnumber_t agno, 658 xfs_agnumber_t agno,
659 xfs_agblock_t bno, 659 xfs_agblock_t bno,
660 xfs_extlen_t len, 660 xfs_extlen_t len,
661 struct xfs_owner_info *oinfo) 661 const struct xfs_owner_info *oinfo)
662{ 662{
663 struct xfs_mount *mp = tp->t_mountp; 663 struct xfs_mount *mp = tp->t_mountp;
664 struct xfs_btree_cur *cur; 664 struct xfs_btree_cur *cur;
665 int error; 665 int error;
666 666
667 if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) 667 if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
668 return 0; 668 return 0;
@@ -710,23 +710,23 @@ xfs_rmap_is_mergeable(
710 */ 710 */
711STATIC int 711STATIC int
712xfs_rmap_map( 712xfs_rmap_map(
713 struct xfs_btree_cur *cur, 713 struct xfs_btree_cur *cur,
714 xfs_agblock_t bno, 714 xfs_agblock_t bno,
715 xfs_extlen_t len, 715 xfs_extlen_t len,
716 bool unwritten, 716 bool unwritten,
717 struct xfs_owner_info *oinfo) 717 const struct xfs_owner_info *oinfo)
718{ 718{
719 struct xfs_mount *mp = cur->bc_mp; 719 struct xfs_mount *mp = cur->bc_mp;
720 struct xfs_rmap_irec ltrec; 720 struct xfs_rmap_irec ltrec;
721 struct xfs_rmap_irec gtrec; 721 struct xfs_rmap_irec gtrec;
722 int have_gt; 722 int have_gt;
723 int have_lt; 723 int have_lt;
724 int error = 0; 724 int error = 0;
725 int i; 725 int i;
726 uint64_t owner; 726 uint64_t owner;
727 uint64_t offset; 727 uint64_t offset;
728 unsigned int flags = 0; 728 unsigned int flags = 0;
729 bool ignore_off; 729 bool ignore_off;
730 730
731 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags); 731 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
732 ASSERT(owner != 0); 732 ASSERT(owner != 0);
@@ -890,16 +890,16 @@ out_error:
890 */ 890 */
891int 891int
892xfs_rmap_alloc( 892xfs_rmap_alloc(
893 struct xfs_trans *tp, 893 struct xfs_trans *tp,
894 struct xfs_buf *agbp, 894 struct xfs_buf *agbp,
895 xfs_agnumber_t agno, 895 xfs_agnumber_t agno,
896 xfs_agblock_t bno, 896 xfs_agblock_t bno,
897 xfs_extlen_t len, 897 xfs_extlen_t len,
898 struct xfs_owner_info *oinfo) 898 const struct xfs_owner_info *oinfo)
899{ 899{
900 struct xfs_mount *mp = tp->t_mountp; 900 struct xfs_mount *mp = tp->t_mountp;
901 struct xfs_btree_cur *cur; 901 struct xfs_btree_cur *cur;
902 int error; 902 int error;
903 903
904 if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) 904 if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
905 return 0; 905 return 0;
@@ -929,16 +929,16 @@ xfs_rmap_alloc(
929 */ 929 */
930STATIC int 930STATIC int
931xfs_rmap_convert( 931xfs_rmap_convert(
932 struct xfs_btree_cur *cur, 932 struct xfs_btree_cur *cur,
933 xfs_agblock_t bno, 933 xfs_agblock_t bno,
934 xfs_extlen_t len, 934 xfs_extlen_t len,
935 bool unwritten, 935 bool unwritten,
936 struct xfs_owner_info *oinfo) 936 const struct xfs_owner_info *oinfo)
937{ 937{
938 struct xfs_mount *mp = cur->bc_mp; 938 struct xfs_mount *mp = cur->bc_mp;
939 struct xfs_rmap_irec r[4]; /* neighbor extent entries */ 939 struct xfs_rmap_irec r[4]; /* neighbor extent entries */
940 /* left is 0, right is 1, prev is 2 */ 940 /* left is 0, right is 1, */
941 /* new is 3 */ 941 /* prev is 2, new is 3 */
942 uint64_t owner; 942 uint64_t owner;
943 uint64_t offset; 943 uint64_t offset;
944 uint64_t new_endoff; 944 uint64_t new_endoff;
@@ -1354,16 +1354,16 @@ done:
1354 */ 1354 */
1355STATIC int 1355STATIC int
1356xfs_rmap_convert_shared( 1356xfs_rmap_convert_shared(
1357 struct xfs_btree_cur *cur, 1357 struct xfs_btree_cur *cur,
1358 xfs_agblock_t bno, 1358 xfs_agblock_t bno,
1359 xfs_extlen_t len, 1359 xfs_extlen_t len,
1360 bool unwritten, 1360 bool unwritten,
1361 struct xfs_owner_info *oinfo) 1361 const struct xfs_owner_info *oinfo)
1362{ 1362{
1363 struct xfs_mount *mp = cur->bc_mp; 1363 struct xfs_mount *mp = cur->bc_mp;
1364 struct xfs_rmap_irec r[4]; /* neighbor extent entries */ 1364 struct xfs_rmap_irec r[4]; /* neighbor extent entries */
1365 /* left is 0, right is 1, prev is 2 */ 1365 /* left is 0, right is 1, */
1366 /* new is 3 */ 1366 /* prev is 2, new is 3 */
1367 uint64_t owner; 1367 uint64_t owner;
1368 uint64_t offset; 1368 uint64_t offset;
1369 uint64_t new_endoff; 1369 uint64_t new_endoff;
@@ -1743,20 +1743,20 @@ done:
1743 */ 1743 */
1744STATIC int 1744STATIC int
1745xfs_rmap_unmap_shared( 1745xfs_rmap_unmap_shared(
1746 struct xfs_btree_cur *cur, 1746 struct xfs_btree_cur *cur,
1747 xfs_agblock_t bno, 1747 xfs_agblock_t bno,
1748 xfs_extlen_t len, 1748 xfs_extlen_t len,
1749 bool unwritten, 1749 bool unwritten,
1750 struct xfs_owner_info *oinfo) 1750 const struct xfs_owner_info *oinfo)
1751{ 1751{
1752 struct xfs_mount *mp = cur->bc_mp; 1752 struct xfs_mount *mp = cur->bc_mp;
1753 struct xfs_rmap_irec ltrec; 1753 struct xfs_rmap_irec ltrec;
1754 uint64_t ltoff; 1754 uint64_t ltoff;
1755 int error = 0; 1755 int error = 0;
1756 int i; 1756 int i;
1757 uint64_t owner; 1757 uint64_t owner;
1758 uint64_t offset; 1758 uint64_t offset;
1759 unsigned int flags; 1759 unsigned int flags;
1760 1760
1761 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags); 1761 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
1762 if (unwritten) 1762 if (unwritten)
@@ -1905,22 +1905,22 @@ out_error:
1905 */ 1905 */
1906STATIC int 1906STATIC int
1907xfs_rmap_map_shared( 1907xfs_rmap_map_shared(
1908 struct xfs_btree_cur *cur, 1908 struct xfs_btree_cur *cur,
1909 xfs_agblock_t bno, 1909 xfs_agblock_t bno,
1910 xfs_extlen_t len, 1910 xfs_extlen_t len,
1911 bool unwritten, 1911 bool unwritten,
1912 struct xfs_owner_info *oinfo) 1912 const struct xfs_owner_info *oinfo)
1913{ 1913{
1914 struct xfs_mount *mp = cur->bc_mp; 1914 struct xfs_mount *mp = cur->bc_mp;
1915 struct xfs_rmap_irec ltrec; 1915 struct xfs_rmap_irec ltrec;
1916 struct xfs_rmap_irec gtrec; 1916 struct xfs_rmap_irec gtrec;
1917 int have_gt; 1917 int have_gt;
1918 int have_lt; 1918 int have_lt;
1919 int error = 0; 1919 int error = 0;
1920 int i; 1920 int i;
1921 uint64_t owner; 1921 uint64_t owner;
1922 uint64_t offset; 1922 uint64_t offset;
1923 unsigned int flags = 0; 1923 unsigned int flags = 0;
1924 1924
1925 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags); 1925 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
1926 if (unwritten) 1926 if (unwritten)
@@ -2459,18 +2459,18 @@ xfs_rmap_has_record(
2459 */ 2459 */
2460int 2460int
2461xfs_rmap_record_exists( 2461xfs_rmap_record_exists(
2462 struct xfs_btree_cur *cur, 2462 struct xfs_btree_cur *cur,
2463 xfs_agblock_t bno, 2463 xfs_agblock_t bno,
2464 xfs_extlen_t len, 2464 xfs_extlen_t len,
2465 struct xfs_owner_info *oinfo, 2465 const struct xfs_owner_info *oinfo,
2466 bool *has_rmap) 2466 bool *has_rmap)
2467{ 2467{
2468 uint64_t owner; 2468 uint64_t owner;
2469 uint64_t offset; 2469 uint64_t offset;
2470 unsigned int flags; 2470 unsigned int flags;
2471 int has_record; 2471 int has_record;
2472 struct xfs_rmap_irec irec; 2472 struct xfs_rmap_irec irec;
2473 int error; 2473 int error;
2474 2474
2475 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags); 2475 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
2476 ASSERT(XFS_RMAP_NON_INODE_OWNER(owner) || 2476 ASSERT(XFS_RMAP_NON_INODE_OWNER(owner) ||
@@ -2530,7 +2530,7 @@ xfs_rmap_has_other_keys(
2530 struct xfs_btree_cur *cur, 2530 struct xfs_btree_cur *cur,
2531 xfs_agblock_t bno, 2531 xfs_agblock_t bno,
2532 xfs_extlen_t len, 2532 xfs_extlen_t len,
2533 struct xfs_owner_info *oinfo, 2533 const struct xfs_owner_info *oinfo,
2534 bool *has_rmap) 2534 bool *has_rmap)
2535{ 2535{
2536 struct xfs_rmap_irec low = {0}; 2536 struct xfs_rmap_irec low = {0};
@@ -2550,3 +2550,31 @@ xfs_rmap_has_other_keys(
2550 *has_rmap = rks.has_rmap; 2550 *has_rmap = rks.has_rmap;
2551 return error; 2551 return error;
2552} 2552}
2553
2554const struct xfs_owner_info XFS_RMAP_OINFO_SKIP_UPDATE = {
2555 .oi_owner = XFS_RMAP_OWN_NULL,
2556};
2557const struct xfs_owner_info XFS_RMAP_OINFO_ANY_OWNER = {
2558 .oi_owner = XFS_RMAP_OWN_UNKNOWN,
2559};
2560const struct xfs_owner_info XFS_RMAP_OINFO_FS = {
2561 .oi_owner = XFS_RMAP_OWN_FS,
2562};
2563const struct xfs_owner_info XFS_RMAP_OINFO_LOG = {
2564 .oi_owner = XFS_RMAP_OWN_LOG,
2565};
2566const struct xfs_owner_info XFS_RMAP_OINFO_AG = {
2567 .oi_owner = XFS_RMAP_OWN_AG,
2568};
2569const struct xfs_owner_info XFS_RMAP_OINFO_INOBT = {
2570 .oi_owner = XFS_RMAP_OWN_INOBT,
2571};
2572const struct xfs_owner_info XFS_RMAP_OINFO_INODES = {
2573 .oi_owner = XFS_RMAP_OWN_INODES,
2574};
2575const struct xfs_owner_info XFS_RMAP_OINFO_REFC = {
2576 .oi_owner = XFS_RMAP_OWN_REFC,
2577};
2578const struct xfs_owner_info XFS_RMAP_OINFO_COW = {
2579 .oi_owner = XFS_RMAP_OWN_COW,
2580};
diff --git a/fs/xfs/libxfs/xfs_rmap.h b/fs/xfs/libxfs/xfs_rmap.h
index 157dc722ad35..e21ed0294e5c 100644
--- a/fs/xfs/libxfs/xfs_rmap.h
+++ b/fs/xfs/libxfs/xfs_rmap.h
@@ -7,16 +7,6 @@
7#define __XFS_RMAP_H__ 7#define __XFS_RMAP_H__
8 8
9static inline void 9static inline void
10xfs_rmap_ag_owner(
11 struct xfs_owner_info *oi,
12 uint64_t owner)
13{
14 oi->oi_owner = owner;
15 oi->oi_offset = 0;
16 oi->oi_flags = 0;
17}
18
19static inline void
20xfs_rmap_ino_bmbt_owner( 10xfs_rmap_ino_bmbt_owner(
21 struct xfs_owner_info *oi, 11 struct xfs_owner_info *oi,
22 xfs_ino_t ino, 12 xfs_ino_t ino,
@@ -43,27 +33,13 @@ xfs_rmap_ino_owner(
43 oi->oi_flags |= XFS_OWNER_INFO_ATTR_FORK; 33 oi->oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
44} 34}
45 35
46static inline void
47xfs_rmap_skip_owner_update(
48 struct xfs_owner_info *oi)
49{
50 xfs_rmap_ag_owner(oi, XFS_RMAP_OWN_NULL);
51}
52
53static inline bool 36static inline bool
54xfs_rmap_should_skip_owner_update( 37xfs_rmap_should_skip_owner_update(
55 struct xfs_owner_info *oi) 38 const struct xfs_owner_info *oi)
56{ 39{
57 return oi->oi_owner == XFS_RMAP_OWN_NULL; 40 return oi->oi_owner == XFS_RMAP_OWN_NULL;
58} 41}
59 42
60static inline void
61xfs_rmap_any_owner_update(
62 struct xfs_owner_info *oi)
63{
64 xfs_rmap_ag_owner(oi, XFS_RMAP_OWN_UNKNOWN);
65}
66
67/* Reverse mapping functions. */ 43/* Reverse mapping functions. */
68 44
69struct xfs_buf; 45struct xfs_buf;
@@ -103,12 +79,12 @@ xfs_rmap_irec_offset_unpack(
103 79
104static inline void 80static inline void
105xfs_owner_info_unpack( 81xfs_owner_info_unpack(
106 struct xfs_owner_info *oinfo, 82 const struct xfs_owner_info *oinfo,
107 uint64_t *owner, 83 uint64_t *owner,
108 uint64_t *offset, 84 uint64_t *offset,
109 unsigned int *flags) 85 unsigned int *flags)
110{ 86{
111 unsigned int r = 0; 87 unsigned int r = 0;
112 88
113 *owner = oinfo->oi_owner; 89 *owner = oinfo->oi_owner;
114 *offset = oinfo->oi_offset; 90 *offset = oinfo->oi_offset;
@@ -137,10 +113,10 @@ xfs_owner_info_pack(
137 113
138int xfs_rmap_alloc(struct xfs_trans *tp, struct xfs_buf *agbp, 114int xfs_rmap_alloc(struct xfs_trans *tp, struct xfs_buf *agbp,
139 xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, 115 xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len,
140 struct xfs_owner_info *oinfo); 116 const struct xfs_owner_info *oinfo);
141int xfs_rmap_free(struct xfs_trans *tp, struct xfs_buf *agbp, 117int xfs_rmap_free(struct xfs_trans *tp, struct xfs_buf *agbp,
142 xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, 118 xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len,
143 struct xfs_owner_info *oinfo); 119 const struct xfs_owner_info *oinfo);
144 120
145int xfs_rmap_lookup_le(struct xfs_btree_cur *cur, xfs_agblock_t bno, 121int xfs_rmap_lookup_le(struct xfs_btree_cur *cur, xfs_agblock_t bno,
146 xfs_extlen_t len, uint64_t owner, uint64_t offset, 122 xfs_extlen_t len, uint64_t owner, uint64_t offset,
@@ -218,11 +194,21 @@ int xfs_rmap_btrec_to_irec(union xfs_btree_rec *rec,
218int xfs_rmap_has_record(struct xfs_btree_cur *cur, xfs_agblock_t bno, 194int xfs_rmap_has_record(struct xfs_btree_cur *cur, xfs_agblock_t bno,
219 xfs_extlen_t len, bool *exists); 195 xfs_extlen_t len, bool *exists);
220int xfs_rmap_record_exists(struct xfs_btree_cur *cur, xfs_agblock_t bno, 196int xfs_rmap_record_exists(struct xfs_btree_cur *cur, xfs_agblock_t bno,
221 xfs_extlen_t len, struct xfs_owner_info *oinfo, 197 xfs_extlen_t len, const struct xfs_owner_info *oinfo,
222 bool *has_rmap); 198 bool *has_rmap);
223int xfs_rmap_has_other_keys(struct xfs_btree_cur *cur, xfs_agblock_t bno, 199int xfs_rmap_has_other_keys(struct xfs_btree_cur *cur, xfs_agblock_t bno,
224 xfs_extlen_t len, struct xfs_owner_info *oinfo, 200 xfs_extlen_t len, const struct xfs_owner_info *oinfo,
225 bool *has_rmap); 201 bool *has_rmap);
226int xfs_rmap_map_raw(struct xfs_btree_cur *cur, struct xfs_rmap_irec *rmap); 202int xfs_rmap_map_raw(struct xfs_btree_cur *cur, struct xfs_rmap_irec *rmap);
227 203
204extern const struct xfs_owner_info XFS_RMAP_OINFO_SKIP_UPDATE;
205extern const struct xfs_owner_info XFS_RMAP_OINFO_ANY_OWNER;
206extern const struct xfs_owner_info XFS_RMAP_OINFO_FS;
207extern const struct xfs_owner_info XFS_RMAP_OINFO_LOG;
208extern const struct xfs_owner_info XFS_RMAP_OINFO_AG;
209extern const struct xfs_owner_info XFS_RMAP_OINFO_INOBT;
210extern const struct xfs_owner_info XFS_RMAP_OINFO_INODES;
211extern const struct xfs_owner_info XFS_RMAP_OINFO_REFC;
212extern const struct xfs_owner_info XFS_RMAP_OINFO_COW;
213
228#endif /* __XFS_RMAP_H__ */ 214#endif /* __XFS_RMAP_H__ */
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index b228c821bae6..eaaff67e9626 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -505,6 +505,12 @@ xfs_rtmodify_summary_int(
505 uint first = (uint)((char *)sp - (char *)bp->b_addr); 505 uint first = (uint)((char *)sp - (char *)bp->b_addr);
506 506
507 *sp += delta; 507 *sp += delta;
508 if (mp->m_rsum_cache) {
509 if (*sp == 0 && log == mp->m_rsum_cache[bbno])
510 mp->m_rsum_cache[bbno]++;
511 if (*sp != 0 && log < mp->m_rsum_cache[bbno])
512 mp->m_rsum_cache[bbno] = log;
513 }
508 xfs_trans_log_buf(tp, bp, first, first + sizeof(*sp) - 1); 514 xfs_trans_log_buf(tp, bp, first, first + sizeof(*sp) - 1);
509 } 515 }
510 if (sum) 516 if (sum)
diff --git a/fs/xfs/libxfs/xfs_symlink_remote.c b/fs/xfs/libxfs/xfs_symlink_remote.c
index 95374ab2dee7..77d80106f989 100644
--- a/fs/xfs/libxfs/xfs_symlink_remote.c
+++ b/fs/xfs/libxfs/xfs_symlink_remote.c
@@ -199,7 +199,10 @@ xfs_symlink_local_to_remote(
199 ifp->if_bytes - 1); 199 ifp->if_bytes - 1);
200} 200}
201 201
202/* Verify the consistency of an inline symlink. */ 202/*
203 * Verify the in-memory consistency of an inline symlink data fork. This
204 * does not do on-disk format checks.
205 */
203xfs_failaddr_t 206xfs_failaddr_t
204xfs_symlink_shortform_verify( 207xfs_symlink_shortform_verify(
205 struct xfs_inode *ip) 208 struct xfs_inode *ip)
@@ -215,9 +218,12 @@ xfs_symlink_shortform_verify(
215 size = ifp->if_bytes; 218 size = ifp->if_bytes;
216 endp = sfp + size; 219 endp = sfp + size;
217 220
218 /* Zero length symlinks can exist while we're deleting a remote one. */ 221 /*
219 if (size == 0) 222 * Zero length symlinks should never occur in memory as they are
220 return NULL; 223 * never alllowed to exist on disk.
224 */
225 if (!size)
226 return __this_address;
221 227
222 /* No negative sizes or overly long symlink targets. */ 228 /* No negative sizes or overly long symlink targets. */
223 if (size < 0 || size > XFS_SYMLINK_MAXLEN) 229 if (size < 0 || size > XFS_SYMLINK_MAXLEN)
diff --git a/fs/xfs/libxfs/xfs_types.c b/fs/xfs/libxfs/xfs_types.c
index 33a5ca346baf..3306fc42cfad 100644
--- a/fs/xfs/libxfs/xfs_types.c
+++ b/fs/xfs/libxfs/xfs_types.c
@@ -87,16 +87,15 @@ xfs_agino_range(
87 * Calculate the first inode, which will be in the first 87 * Calculate the first inode, which will be in the first
88 * cluster-aligned block after the AGFL. 88 * cluster-aligned block after the AGFL.
89 */ 89 */
90 bno = round_up(XFS_AGFL_BLOCK(mp) + 1, 90 bno = round_up(XFS_AGFL_BLOCK(mp) + 1, mp->m_cluster_align);
91 xfs_ialloc_cluster_alignment(mp)); 91 *first = XFS_AGB_TO_AGINO(mp, bno);
92 *first = XFS_OFFBNO_TO_AGINO(mp, bno, 0);
93 92
94 /* 93 /*
95 * Calculate the last inode, which will be at the end of the 94 * Calculate the last inode, which will be at the end of the
96 * last (aligned) cluster that can be allocated in the AG. 95 * last (aligned) cluster that can be allocated in the AG.
97 */ 96 */
98 bno = round_down(eoag, xfs_ialloc_cluster_alignment(mp)); 97 bno = round_down(eoag, mp->m_cluster_align);
99 *last = XFS_OFFBNO_TO_AGINO(mp, bno, 0) - 1; 98 *last = XFS_AGB_TO_AGINO(mp, bno) - 1;
100} 99}
101 100
102/* 101/*
diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h
index b9e6c89284c3..8f02855a019a 100644
--- a/fs/xfs/libxfs/xfs_types.h
+++ b/fs/xfs/libxfs/xfs_types.h
@@ -100,15 +100,37 @@ typedef void * xfs_failaddr_t;
100 */ 100 */
101#define MAXNAMELEN 256 101#define MAXNAMELEN 256
102 102
103/*
104 * This enum is used in string mapping in xfs_trace.h; please keep the
105 * TRACE_DEFINE_ENUMs for it up to date.
106 */
103typedef enum { 107typedef enum {
104 XFS_LOOKUP_EQi, XFS_LOOKUP_LEi, XFS_LOOKUP_GEi 108 XFS_LOOKUP_EQi, XFS_LOOKUP_LEi, XFS_LOOKUP_GEi
105} xfs_lookup_t; 109} xfs_lookup_t;
106 110
111#define XFS_AG_BTREE_CMP_FORMAT_STR \
112 { XFS_LOOKUP_EQi, "eq" }, \
113 { XFS_LOOKUP_LEi, "le" }, \
114 { XFS_LOOKUP_GEi, "ge" }
115
116/*
117 * This enum is used in string mapping in xfs_trace.h and scrub/trace.h;
118 * please keep the TRACE_DEFINE_ENUMs for it up to date.
119 */
107typedef enum { 120typedef enum {
108 XFS_BTNUM_BNOi, XFS_BTNUM_CNTi, XFS_BTNUM_RMAPi, XFS_BTNUM_BMAPi, 121 XFS_BTNUM_BNOi, XFS_BTNUM_CNTi, XFS_BTNUM_RMAPi, XFS_BTNUM_BMAPi,
109 XFS_BTNUM_INOi, XFS_BTNUM_FINOi, XFS_BTNUM_REFCi, XFS_BTNUM_MAX 122 XFS_BTNUM_INOi, XFS_BTNUM_FINOi, XFS_BTNUM_REFCi, XFS_BTNUM_MAX
110} xfs_btnum_t; 123} xfs_btnum_t;
111 124
125#define XFS_BTNUM_STRINGS \
126 { XFS_BTNUM_BNOi, "bnobt" }, \
127 { XFS_BTNUM_CNTi, "cntbt" }, \
128 { XFS_BTNUM_RMAPi, "rmapbt" }, \
129 { XFS_BTNUM_BMAPi, "bmbt" }, \
130 { XFS_BTNUM_INOi, "inobt" }, \
131 { XFS_BTNUM_FINOi, "finobt" }, \
132 { XFS_BTNUM_REFCi, "refcbt" }
133
112struct xfs_name { 134struct xfs_name {
113 const unsigned char *name; 135 const unsigned char *name;
114 int len; 136 int len;
diff --git a/fs/xfs/scrub/agheader.c b/fs/xfs/scrub/agheader.c
index 3068a9382feb..90955ab1e895 100644
--- a/fs/xfs/scrub/agheader.c
+++ b/fs/xfs/scrub/agheader.c
@@ -32,7 +32,6 @@ xchk_superblock_xref(
32 struct xfs_scrub *sc, 32 struct xfs_scrub *sc,
33 struct xfs_buf *bp) 33 struct xfs_buf *bp)
34{ 34{
35 struct xfs_owner_info oinfo;
36 struct xfs_mount *mp = sc->mp; 35 struct xfs_mount *mp = sc->mp;
37 xfs_agnumber_t agno = sc->sm->sm_agno; 36 xfs_agnumber_t agno = sc->sm->sm_agno;
38 xfs_agblock_t agbno; 37 xfs_agblock_t agbno;
@@ -49,8 +48,7 @@ xchk_superblock_xref(
49 48
50 xchk_xref_is_used_space(sc, agbno, 1); 49 xchk_xref_is_used_space(sc, agbno, 1);
51 xchk_xref_is_not_inode_chunk(sc, agbno, 1); 50 xchk_xref_is_not_inode_chunk(sc, agbno, 1);
52 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_FS); 51 xchk_xref_is_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_FS);
53 xchk_xref_is_owned_by(sc, agbno, 1, &oinfo);
54 xchk_xref_is_not_shared(sc, agbno, 1); 52 xchk_xref_is_not_shared(sc, agbno, 1);
55 53
56 /* scrub teardown will take care of sc->sa for us */ 54 /* scrub teardown will take care of sc->sa for us */
@@ -484,7 +482,6 @@ STATIC void
484xchk_agf_xref( 482xchk_agf_xref(
485 struct xfs_scrub *sc) 483 struct xfs_scrub *sc)
486{ 484{
487 struct xfs_owner_info oinfo;
488 struct xfs_mount *mp = sc->mp; 485 struct xfs_mount *mp = sc->mp;
489 xfs_agblock_t agbno; 486 xfs_agblock_t agbno;
490 int error; 487 int error;
@@ -502,8 +499,7 @@ xchk_agf_xref(
502 xchk_agf_xref_freeblks(sc); 499 xchk_agf_xref_freeblks(sc);
503 xchk_agf_xref_cntbt(sc); 500 xchk_agf_xref_cntbt(sc);
504 xchk_xref_is_not_inode_chunk(sc, agbno, 1); 501 xchk_xref_is_not_inode_chunk(sc, agbno, 1);
505 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_FS); 502 xchk_xref_is_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_FS);
506 xchk_xref_is_owned_by(sc, agbno, 1, &oinfo);
507 xchk_agf_xref_btreeblks(sc); 503 xchk_agf_xref_btreeblks(sc);
508 xchk_xref_is_not_shared(sc, agbno, 1); 504 xchk_xref_is_not_shared(sc, agbno, 1);
509 xchk_agf_xref_refcblks(sc); 505 xchk_agf_xref_refcblks(sc);
@@ -598,7 +594,6 @@ out:
598/* AGFL */ 594/* AGFL */
599 595
600struct xchk_agfl_info { 596struct xchk_agfl_info {
601 struct xfs_owner_info oinfo;
602 unsigned int sz_entries; 597 unsigned int sz_entries;
603 unsigned int nr_entries; 598 unsigned int nr_entries;
604 xfs_agblock_t *entries; 599 xfs_agblock_t *entries;
@@ -609,15 +604,14 @@ struct xchk_agfl_info {
609STATIC void 604STATIC void
610xchk_agfl_block_xref( 605xchk_agfl_block_xref(
611 struct xfs_scrub *sc, 606 struct xfs_scrub *sc,
612 xfs_agblock_t agbno, 607 xfs_agblock_t agbno)
613 struct xfs_owner_info *oinfo)
614{ 608{
615 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 609 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
616 return; 610 return;
617 611
618 xchk_xref_is_used_space(sc, agbno, 1); 612 xchk_xref_is_used_space(sc, agbno, 1);
619 xchk_xref_is_not_inode_chunk(sc, agbno, 1); 613 xchk_xref_is_not_inode_chunk(sc, agbno, 1);
620 xchk_xref_is_owned_by(sc, agbno, 1, oinfo); 614 xchk_xref_is_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_AG);
621 xchk_xref_is_not_shared(sc, agbno, 1); 615 xchk_xref_is_not_shared(sc, agbno, 1);
622} 616}
623 617
@@ -638,7 +632,7 @@ xchk_agfl_block(
638 else 632 else
639 xchk_block_set_corrupt(sc, sc->sa.agfl_bp); 633 xchk_block_set_corrupt(sc, sc->sa.agfl_bp);
640 634
641 xchk_agfl_block_xref(sc, agbno, priv); 635 xchk_agfl_block_xref(sc, agbno);
642 636
643 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 637 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
644 return XFS_BTREE_QUERY_RANGE_ABORT; 638 return XFS_BTREE_QUERY_RANGE_ABORT;
@@ -662,7 +656,6 @@ STATIC void
662xchk_agfl_xref( 656xchk_agfl_xref(
663 struct xfs_scrub *sc) 657 struct xfs_scrub *sc)
664{ 658{
665 struct xfs_owner_info oinfo;
666 struct xfs_mount *mp = sc->mp; 659 struct xfs_mount *mp = sc->mp;
667 xfs_agblock_t agbno; 660 xfs_agblock_t agbno;
668 int error; 661 int error;
@@ -678,8 +671,7 @@ xchk_agfl_xref(
678 671
679 xchk_xref_is_used_space(sc, agbno, 1); 672 xchk_xref_is_used_space(sc, agbno, 1);
680 xchk_xref_is_not_inode_chunk(sc, agbno, 1); 673 xchk_xref_is_not_inode_chunk(sc, agbno, 1);
681 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_FS); 674 xchk_xref_is_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_FS);
682 xchk_xref_is_owned_by(sc, agbno, 1, &oinfo);
683 xchk_xref_is_not_shared(sc, agbno, 1); 675 xchk_xref_is_not_shared(sc, agbno, 1);
684 676
685 /* 677 /*
@@ -732,7 +724,6 @@ xchk_agfl(
732 } 724 }
733 725
734 /* Check the blocks in the AGFL. */ 726 /* Check the blocks in the AGFL. */
735 xfs_rmap_ag_owner(&sai.oinfo, XFS_RMAP_OWN_AG);
736 error = xfs_agfl_walk(sc->mp, XFS_BUF_TO_AGF(sc->sa.agf_bp), 727 error = xfs_agfl_walk(sc->mp, XFS_BUF_TO_AGF(sc->sa.agf_bp),
737 sc->sa.agfl_bp, xchk_agfl_block, &sai); 728 sc->sa.agfl_bp, xchk_agfl_block, &sai);
738 if (error == XFS_BTREE_QUERY_RANGE_ABORT) { 729 if (error == XFS_BTREE_QUERY_RANGE_ABORT) {
@@ -791,7 +782,6 @@ STATIC void
791xchk_agi_xref( 782xchk_agi_xref(
792 struct xfs_scrub *sc) 783 struct xfs_scrub *sc)
793{ 784{
794 struct xfs_owner_info oinfo;
795 struct xfs_mount *mp = sc->mp; 785 struct xfs_mount *mp = sc->mp;
796 xfs_agblock_t agbno; 786 xfs_agblock_t agbno;
797 int error; 787 int error;
@@ -808,8 +798,7 @@ xchk_agi_xref(
808 xchk_xref_is_used_space(sc, agbno, 1); 798 xchk_xref_is_used_space(sc, agbno, 1);
809 xchk_xref_is_not_inode_chunk(sc, agbno, 1); 799 xchk_xref_is_not_inode_chunk(sc, agbno, 1);
810 xchk_agi_xref_icounts(sc); 800 xchk_agi_xref_icounts(sc);
811 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_FS); 801 xchk_xref_is_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_FS);
812 xchk_xref_is_owned_by(sc, agbno, 1, &oinfo);
813 xchk_xref_is_not_shared(sc, agbno, 1); 802 xchk_xref_is_not_shared(sc, agbno, 1);
814 803
815 /* scrub teardown will take care of sc->sa for us */ 804 /* scrub teardown will take care of sc->sa for us */
diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c
index f7568a4b5fe5..03d1e15cceba 100644
--- a/fs/xfs/scrub/agheader_repair.c
+++ b/fs/xfs/scrub/agheader_repair.c
@@ -646,7 +646,6 @@ int
646xrep_agfl( 646xrep_agfl(
647 struct xfs_scrub *sc) 647 struct xfs_scrub *sc)
648{ 648{
649 struct xfs_owner_info oinfo;
650 struct xfs_bitmap agfl_extents; 649 struct xfs_bitmap agfl_extents;
651 struct xfs_mount *mp = sc->mp; 650 struct xfs_mount *mp = sc->mp;
652 struct xfs_buf *agf_bp; 651 struct xfs_buf *agf_bp;
@@ -708,8 +707,8 @@ xrep_agfl(
708 goto err; 707 goto err;
709 708
710 /* Dump any AGFL overflow. */ 709 /* Dump any AGFL overflow. */
711 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_AG); 710 return xrep_reap_extents(sc, &agfl_extents, &XFS_RMAP_OINFO_AG,
712 return xrep_reap_extents(sc, &agfl_extents, &oinfo, XFS_AG_RESV_AGFL); 711 XFS_AG_RESV_AGFL);
713err: 712err:
714 xfs_bitmap_destroy(&agfl_extents); 713 xfs_bitmap_destroy(&agfl_extents);
715 return error; 714 return error;
diff --git a/fs/xfs/scrub/alloc.c b/fs/xfs/scrub/alloc.c
index 376bcb585ae6..44883e9112ad 100644
--- a/fs/xfs/scrub/alloc.c
+++ b/fs/xfs/scrub/alloc.c
@@ -125,12 +125,10 @@ xchk_allocbt(
125 struct xfs_scrub *sc, 125 struct xfs_scrub *sc,
126 xfs_btnum_t which) 126 xfs_btnum_t which)
127{ 127{
128 struct xfs_owner_info oinfo;
129 struct xfs_btree_cur *cur; 128 struct xfs_btree_cur *cur;
130 129
131 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_AG);
132 cur = which == XFS_BTNUM_BNO ? sc->sa.bno_cur : sc->sa.cnt_cur; 130 cur = which == XFS_BTNUM_BNO ? sc->sa.bno_cur : sc->sa.cnt_cur;
133 return xchk_btree(sc, cur, xchk_allocbt_rec, &oinfo, NULL); 131 return xchk_btree(sc, cur, xchk_allocbt_rec, &XFS_RMAP_OINFO_AG, NULL);
134} 132}
135 133
136int 134int
diff --git a/fs/xfs/scrub/btree.c b/fs/xfs/scrub/btree.c
index 4ae959f7ad2c..6f94d1f7322d 100644
--- a/fs/xfs/scrub/btree.c
+++ b/fs/xfs/scrub/btree.c
@@ -583,31 +583,32 @@ xchk_btree_block_keys(
583 */ 583 */
584int 584int
585xchk_btree( 585xchk_btree(
586 struct xfs_scrub *sc, 586 struct xfs_scrub *sc,
587 struct xfs_btree_cur *cur, 587 struct xfs_btree_cur *cur,
588 xchk_btree_rec_fn scrub_fn, 588 xchk_btree_rec_fn scrub_fn,
589 struct xfs_owner_info *oinfo, 589 const struct xfs_owner_info *oinfo,
590 void *private) 590 void *private)
591{ 591{
592 struct xchk_btree bs = { NULL }; 592 struct xchk_btree bs = {
593 union xfs_btree_ptr ptr; 593 .cur = cur,
594 union xfs_btree_ptr *pp; 594 .scrub_rec = scrub_fn,
595 union xfs_btree_rec *recp; 595 .oinfo = oinfo,
596 struct xfs_btree_block *block; 596 .firstrec = true,
597 int level; 597 .private = private,
598 struct xfs_buf *bp; 598 .sc = sc,
599 struct check_owner *co; 599 };
600 struct check_owner *n; 600 union xfs_btree_ptr ptr;
601 int i; 601 union xfs_btree_ptr *pp;
602 int error = 0; 602 union xfs_btree_rec *recp;
603 struct xfs_btree_block *block;
604 int level;
605 struct xfs_buf *bp;
606 struct check_owner *co;
607 struct check_owner *n;
608 int i;
609 int error = 0;
603 610
604 /* Initialize scrub state */ 611 /* Initialize scrub state */
605 bs.cur = cur;
606 bs.scrub_rec = scrub_fn;
607 bs.oinfo = oinfo;
608 bs.firstrec = true;
609 bs.private = private;
610 bs.sc = sc;
611 for (i = 0; i < XFS_BTREE_MAXLEVELS; i++) 612 for (i = 0; i < XFS_BTREE_MAXLEVELS; i++)
612 bs.firstkey[i] = true; 613 bs.firstkey[i] = true;
613 INIT_LIST_HEAD(&bs.to_check); 614 INIT_LIST_HEAD(&bs.to_check);
diff --git a/fs/xfs/scrub/btree.h b/fs/xfs/scrub/btree.h
index aada763cd006..5572e475f8ed 100644
--- a/fs/xfs/scrub/btree.h
+++ b/fs/xfs/scrub/btree.h
@@ -31,21 +31,21 @@ typedef int (*xchk_btree_rec_fn)(
31 31
32struct xchk_btree { 32struct xchk_btree {
33 /* caller-provided scrub state */ 33 /* caller-provided scrub state */
34 struct xfs_scrub *sc; 34 struct xfs_scrub *sc;
35 struct xfs_btree_cur *cur; 35 struct xfs_btree_cur *cur;
36 xchk_btree_rec_fn scrub_rec; 36 xchk_btree_rec_fn scrub_rec;
37 struct xfs_owner_info *oinfo; 37 const struct xfs_owner_info *oinfo;
38 void *private; 38 void *private;
39 39
40 /* internal scrub state */ 40 /* internal scrub state */
41 union xfs_btree_rec lastrec; 41 union xfs_btree_rec lastrec;
42 bool firstrec; 42 bool firstrec;
43 union xfs_btree_key lastkey[XFS_BTREE_MAXLEVELS]; 43 union xfs_btree_key lastkey[XFS_BTREE_MAXLEVELS];
44 bool firstkey[XFS_BTREE_MAXLEVELS]; 44 bool firstkey[XFS_BTREE_MAXLEVELS];
45 struct list_head to_check; 45 struct list_head to_check;
46}; 46};
47int xchk_btree(struct xfs_scrub *sc, struct xfs_btree_cur *cur, 47int xchk_btree(struct xfs_scrub *sc, struct xfs_btree_cur *cur,
48 xchk_btree_rec_fn scrub_fn, struct xfs_owner_info *oinfo, 48 xchk_btree_rec_fn scrub_fn, const struct xfs_owner_info *oinfo,
49 void *private); 49 void *private);
50 50
51#endif /* __XFS_SCRUB_BTREE_H__ */ 51#endif /* __XFS_SCRUB_BTREE_H__ */
diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c
index 346b02abccf7..0c54ff55b901 100644
--- a/fs/xfs/scrub/common.c
+++ b/fs/xfs/scrub/common.c
@@ -313,8 +313,8 @@ xchk_set_incomplete(
313 */ 313 */
314 314
315struct xchk_rmap_ownedby_info { 315struct xchk_rmap_ownedby_info {
316 struct xfs_owner_info *oinfo; 316 const struct xfs_owner_info *oinfo;
317 xfs_filblks_t *blocks; 317 xfs_filblks_t *blocks;
318}; 318};
319 319
320STATIC int 320STATIC int
@@ -347,15 +347,15 @@ int
347xchk_count_rmap_ownedby_ag( 347xchk_count_rmap_ownedby_ag(
348 struct xfs_scrub *sc, 348 struct xfs_scrub *sc,
349 struct xfs_btree_cur *cur, 349 struct xfs_btree_cur *cur,
350 struct xfs_owner_info *oinfo, 350 const struct xfs_owner_info *oinfo,
351 xfs_filblks_t *blocks) 351 xfs_filblks_t *blocks)
352{ 352{
353 struct xchk_rmap_ownedby_info sroi; 353 struct xchk_rmap_ownedby_info sroi = {
354 .oinfo = oinfo,
355 .blocks = blocks,
356 };
354 357
355 sroi.oinfo = oinfo;
356 *blocks = 0; 358 *blocks = 0;
357 sroi.blocks = blocks;
358
359 return xfs_rmap_query_all(cur, xchk_count_rmap_ownedby_irec, 359 return xfs_rmap_query_all(cur, xchk_count_rmap_ownedby_irec,
360 &sroi); 360 &sroi);
361} 361}
diff --git a/fs/xfs/scrub/common.h b/fs/xfs/scrub/common.h
index 2d4324d12f9a..e26a430bd466 100644
--- a/fs/xfs/scrub/common.h
+++ b/fs/xfs/scrub/common.h
@@ -116,7 +116,7 @@ int xchk_ag_read_headers(struct xfs_scrub *sc, xfs_agnumber_t agno,
116void xchk_ag_btcur_free(struct xchk_ag *sa); 116void xchk_ag_btcur_free(struct xchk_ag *sa);
117int xchk_ag_btcur_init(struct xfs_scrub *sc, struct xchk_ag *sa); 117int xchk_ag_btcur_init(struct xfs_scrub *sc, struct xchk_ag *sa);
118int xchk_count_rmap_ownedby_ag(struct xfs_scrub *sc, struct xfs_btree_cur *cur, 118int xchk_count_rmap_ownedby_ag(struct xfs_scrub *sc, struct xfs_btree_cur *cur,
119 struct xfs_owner_info *oinfo, xfs_filblks_t *blocks); 119 const struct xfs_owner_info *oinfo, xfs_filblks_t *blocks);
120 120
121int xchk_setup_ag_btree(struct xfs_scrub *sc, struct xfs_inode *ip, 121int xchk_setup_ag_btree(struct xfs_scrub *sc, struct xfs_inode *ip,
122 bool force_log); 122 bool force_log);
diff --git a/fs/xfs/scrub/ialloc.c b/fs/xfs/scrub/ialloc.c
index 224dba937492..882dc56c5c21 100644
--- a/fs/xfs/scrub/ialloc.c
+++ b/fs/xfs/scrub/ialloc.c
@@ -44,6 +44,11 @@ xchk_setup_ag_iallocbt(
44 44
45/* Inode btree scrubber. */ 45/* Inode btree scrubber. */
46 46
47struct xchk_iallocbt {
48 /* Number of inodes we see while scanning inobt. */
49 unsigned long long inodes;
50};
51
47/* 52/*
48 * If we're checking the finobt, cross-reference with the inobt. 53 * If we're checking the finobt, cross-reference with the inobt.
49 * Otherwise we're checking the inobt; if there is an finobt, make sure 54 * Otherwise we're checking the inobt; if there is an finobt, make sure
@@ -82,15 +87,12 @@ xchk_iallocbt_chunk_xref(
82 xfs_agblock_t agbno, 87 xfs_agblock_t agbno,
83 xfs_extlen_t len) 88 xfs_extlen_t len)
84{ 89{
85 struct xfs_owner_info oinfo;
86
87 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 90 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
88 return; 91 return;
89 92
90 xchk_xref_is_used_space(sc, agbno, len); 93 xchk_xref_is_used_space(sc, agbno, len);
91 xchk_iallocbt_chunk_xref_other(sc, irec, agino); 94 xchk_iallocbt_chunk_xref_other(sc, irec, agino);
92 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INODES); 95 xchk_xref_is_owned_by(sc, agbno, len, &XFS_RMAP_OINFO_INODES);
93 xchk_xref_is_owned_by(sc, agbno, len, &oinfo);
94 xchk_xref_is_not_shared(sc, agbno, len); 96 xchk_xref_is_not_shared(sc, agbno, len);
95} 97}
96 98
@@ -186,7 +188,6 @@ xchk_iallocbt_check_freemask(
186 struct xchk_btree *bs, 188 struct xchk_btree *bs,
187 struct xfs_inobt_rec_incore *irec) 189 struct xfs_inobt_rec_incore *irec)
188{ 190{
189 struct xfs_owner_info oinfo;
190 struct xfs_imap imap; 191 struct xfs_imap imap;
191 struct xfs_mount *mp = bs->cur->bc_mp; 192 struct xfs_mount *mp = bs->cur->bc_mp;
192 struct xfs_dinode *dip; 193 struct xfs_dinode *dip;
@@ -197,19 +198,16 @@ xchk_iallocbt_check_freemask(
197 xfs_agino_t chunkino; 198 xfs_agino_t chunkino;
198 xfs_agino_t clusterino; 199 xfs_agino_t clusterino;
199 xfs_agblock_t agbno; 200 xfs_agblock_t agbno;
200 int blks_per_cluster;
201 uint16_t holemask; 201 uint16_t holemask;
202 uint16_t ir_holemask; 202 uint16_t ir_holemask;
203 int error = 0; 203 int error = 0;
204 204
205 /* Make sure the freemask matches the inode records. */ 205 /* Make sure the freemask matches the inode records. */
206 blks_per_cluster = xfs_icluster_size_fsb(mp); 206 nr_inodes = mp->m_inodes_per_cluster;
207 nr_inodes = XFS_OFFBNO_TO_AGINO(mp, blks_per_cluster, 0);
208 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INODES);
209 207
210 for (agino = irec->ir_startino; 208 for (agino = irec->ir_startino;
211 agino < irec->ir_startino + XFS_INODES_PER_CHUNK; 209 agino < irec->ir_startino + XFS_INODES_PER_CHUNK;
212 agino += blks_per_cluster * mp->m_sb.sb_inopblock) { 210 agino += mp->m_inodes_per_cluster) {
213 fsino = XFS_AGINO_TO_INO(mp, bs->cur->bc_private.a.agno, agino); 211 fsino = XFS_AGINO_TO_INO(mp, bs->cur->bc_private.a.agno, agino);
214 chunkino = agino - irec->ir_startino; 212 chunkino = agino - irec->ir_startino;
215 agbno = XFS_AGINO_TO_AGBNO(mp, agino); 213 agbno = XFS_AGINO_TO_AGBNO(mp, agino);
@@ -230,17 +228,18 @@ xchk_iallocbt_check_freemask(
230 /* If any part of this is a hole, skip it. */ 228 /* If any part of this is a hole, skip it. */
231 if (ir_holemask) { 229 if (ir_holemask) {
232 xchk_xref_is_not_owned_by(bs->sc, agbno, 230 xchk_xref_is_not_owned_by(bs->sc, agbno,
233 blks_per_cluster, &oinfo); 231 mp->m_blocks_per_cluster,
232 &XFS_RMAP_OINFO_INODES);
234 continue; 233 continue;
235 } 234 }
236 235
237 xchk_xref_is_owned_by(bs->sc, agbno, blks_per_cluster, 236 xchk_xref_is_owned_by(bs->sc, agbno, mp->m_blocks_per_cluster,
238 &oinfo); 237 &XFS_RMAP_OINFO_INODES);
239 238
240 /* Grab the inode cluster buffer. */ 239 /* Grab the inode cluster buffer. */
241 imap.im_blkno = XFS_AGB_TO_DADDR(mp, bs->cur->bc_private.a.agno, 240 imap.im_blkno = XFS_AGB_TO_DADDR(mp, bs->cur->bc_private.a.agno,
242 agbno); 241 agbno);
243 imap.im_len = XFS_FSB_TO_BB(mp, blks_per_cluster); 242 imap.im_len = XFS_FSB_TO_BB(mp, mp->m_blocks_per_cluster);
244 imap.im_boffset = 0; 243 imap.im_boffset = 0;
245 244
246 error = xfs_imap_to_bp(mp, bs->cur->bc_tp, &imap, 245 error = xfs_imap_to_bp(mp, bs->cur->bc_tp, &imap,
@@ -272,7 +271,7 @@ xchk_iallocbt_rec(
272 union xfs_btree_rec *rec) 271 union xfs_btree_rec *rec)
273{ 272{
274 struct xfs_mount *mp = bs->cur->bc_mp; 273 struct xfs_mount *mp = bs->cur->bc_mp;
275 xfs_filblks_t *inode_blocks = bs->private; 274 struct xchk_iallocbt *iabt = bs->private;
276 struct xfs_inobt_rec_incore irec; 275 struct xfs_inobt_rec_incore irec;
277 uint64_t holes; 276 uint64_t holes;
278 xfs_agnumber_t agno = bs->cur->bc_private.a.agno; 277 xfs_agnumber_t agno = bs->cur->bc_private.a.agno;
@@ -306,12 +305,11 @@ xchk_iallocbt_rec(
306 305
307 /* Make sure this record is aligned to cluster and inoalignmnt size. */ 306 /* Make sure this record is aligned to cluster and inoalignmnt size. */
308 agbno = XFS_AGINO_TO_AGBNO(mp, irec.ir_startino); 307 agbno = XFS_AGINO_TO_AGBNO(mp, irec.ir_startino);
309 if ((agbno & (xfs_ialloc_cluster_alignment(mp) - 1)) || 308 if ((agbno & (mp->m_cluster_align - 1)) ||
310 (agbno & (xfs_icluster_size_fsb(mp) - 1))) 309 (agbno & (mp->m_blocks_per_cluster - 1)))
311 xchk_btree_set_corrupt(bs->sc, bs->cur, 0); 310 xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
312 311
313 *inode_blocks += XFS_B_TO_FSB(mp, 312 iabt->inodes += irec.ir_count;
314 irec.ir_count * mp->m_sb.sb_inodesize);
315 313
316 /* Handle non-sparse inodes */ 314 /* Handle non-sparse inodes */
317 if (!xfs_inobt_issparse(irec.ir_holemask)) { 315 if (!xfs_inobt_issparse(irec.ir_holemask)) {
@@ -366,7 +364,6 @@ xchk_iallocbt_xref_rmap_btreeblks(
366 struct xfs_scrub *sc, 364 struct xfs_scrub *sc,
367 int which) 365 int which)
368{ 366{
369 struct xfs_owner_info oinfo;
370 xfs_filblks_t blocks; 367 xfs_filblks_t blocks;
371 xfs_extlen_t inobt_blocks = 0; 368 xfs_extlen_t inobt_blocks = 0;
372 xfs_extlen_t finobt_blocks = 0; 369 xfs_extlen_t finobt_blocks = 0;
@@ -388,9 +385,8 @@ xchk_iallocbt_xref_rmap_btreeblks(
388 return; 385 return;
389 } 386 }
390 387
391 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INOBT); 388 error = xchk_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur,
392 error = xchk_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur, &oinfo, 389 &XFS_RMAP_OINFO_INOBT, &blocks);
393 &blocks);
394 if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur)) 390 if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur))
395 return; 391 return;
396 if (blocks != inobt_blocks + finobt_blocks) 392 if (blocks != inobt_blocks + finobt_blocks)
@@ -405,21 +401,21 @@ STATIC void
405xchk_iallocbt_xref_rmap_inodes( 401xchk_iallocbt_xref_rmap_inodes(
406 struct xfs_scrub *sc, 402 struct xfs_scrub *sc,
407 int which, 403 int which,
408 xfs_filblks_t inode_blocks) 404 unsigned long long inodes)
409{ 405{
410 struct xfs_owner_info oinfo;
411 xfs_filblks_t blocks; 406 xfs_filblks_t blocks;
407 xfs_filblks_t inode_blocks;
412 int error; 408 int error;
413 409
414 if (!sc->sa.rmap_cur || xchk_skip_xref(sc->sm)) 410 if (!sc->sa.rmap_cur || xchk_skip_xref(sc->sm))
415 return; 411 return;
416 412
417 /* Check that we saw as many inode blocks as the rmap knows about. */ 413 /* Check that we saw as many inode blocks as the rmap knows about. */
418 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INODES); 414 error = xchk_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur,
419 error = xchk_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur, &oinfo, 415 &XFS_RMAP_OINFO_INODES, &blocks);
420 &blocks);
421 if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur)) 416 if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur))
422 return; 417 return;
418 inode_blocks = XFS_B_TO_FSB(sc->mp, inodes * sc->mp->m_sb.sb_inodesize);
423 if (blocks != inode_blocks) 419 if (blocks != inode_blocks)
424 xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0); 420 xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0);
425} 421}
@@ -431,14 +427,14 @@ xchk_iallocbt(
431 xfs_btnum_t which) 427 xfs_btnum_t which)
432{ 428{
433 struct xfs_btree_cur *cur; 429 struct xfs_btree_cur *cur;
434 struct xfs_owner_info oinfo; 430 struct xchk_iallocbt iabt = {
435 xfs_filblks_t inode_blocks = 0; 431 .inodes = 0,
432 };
436 int error; 433 int error;
437 434
438 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INOBT);
439 cur = which == XFS_BTNUM_INO ? sc->sa.ino_cur : sc->sa.fino_cur; 435 cur = which == XFS_BTNUM_INO ? sc->sa.ino_cur : sc->sa.fino_cur;
440 error = xchk_btree(sc, cur, xchk_iallocbt_rec, &oinfo, 436 error = xchk_btree(sc, cur, xchk_iallocbt_rec, &XFS_RMAP_OINFO_INOBT,
441 &inode_blocks); 437 &iabt);
442 if (error) 438 if (error)
443 return error; 439 return error;
444 440
@@ -452,7 +448,7 @@ xchk_iallocbt(
452 * to inode chunks with free inodes. 448 * to inode chunks with free inodes.
453 */ 449 */
454 if (which == XFS_BTNUM_INO) 450 if (which == XFS_BTNUM_INO)
455 xchk_iallocbt_xref_rmap_inodes(sc, which, inode_blocks); 451 xchk_iallocbt_xref_rmap_inodes(sc, which, iabt.inodes);
456 452
457 return error; 453 return error;
458} 454}
diff --git a/fs/xfs/scrub/inode.c b/fs/xfs/scrub/inode.c
index e386c9b0b4ab..e213efc194a1 100644
--- a/fs/xfs/scrub/inode.c
+++ b/fs/xfs/scrub/inode.c
@@ -509,7 +509,6 @@ xchk_inode_xref(
509 xfs_ino_t ino, 509 xfs_ino_t ino,
510 struct xfs_dinode *dip) 510 struct xfs_dinode *dip)
511{ 511{
512 struct xfs_owner_info oinfo;
513 xfs_agnumber_t agno; 512 xfs_agnumber_t agno;
514 xfs_agblock_t agbno; 513 xfs_agblock_t agbno;
515 int error; 514 int error;
@@ -526,8 +525,7 @@ xchk_inode_xref(
526 525
527 xchk_xref_is_used_space(sc, agbno, 1); 526 xchk_xref_is_used_space(sc, agbno, 1);
528 xchk_inode_xref_finobt(sc, ino); 527 xchk_inode_xref_finobt(sc, ino);
529 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INODES); 528 xchk_xref_is_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_INODES);
530 xchk_xref_is_owned_by(sc, agbno, 1, &oinfo);
531 xchk_xref_is_not_shared(sc, agbno, 1); 529 xchk_xref_is_not_shared(sc, agbno, 1);
532 xchk_inode_xref_bmap(sc, dip); 530 xchk_inode_xref_bmap(sc, dip);
533 531
diff --git a/fs/xfs/scrub/refcount.c b/fs/xfs/scrub/refcount.c
index e8c82b026083..708b4158eb90 100644
--- a/fs/xfs/scrub/refcount.c
+++ b/fs/xfs/scrub/refcount.c
@@ -383,7 +383,6 @@ xchk_refcountbt_rec(
383STATIC void 383STATIC void
384xchk_refcount_xref_rmap( 384xchk_refcount_xref_rmap(
385 struct xfs_scrub *sc, 385 struct xfs_scrub *sc,
386 struct xfs_owner_info *oinfo,
387 xfs_filblks_t cow_blocks) 386 xfs_filblks_t cow_blocks)
388{ 387{
389 xfs_extlen_t refcbt_blocks = 0; 388 xfs_extlen_t refcbt_blocks = 0;
@@ -397,17 +396,16 @@ xchk_refcount_xref_rmap(
397 error = xfs_btree_count_blocks(sc->sa.refc_cur, &refcbt_blocks); 396 error = xfs_btree_count_blocks(sc->sa.refc_cur, &refcbt_blocks);
398 if (!xchk_btree_process_error(sc, sc->sa.refc_cur, 0, &error)) 397 if (!xchk_btree_process_error(sc, sc->sa.refc_cur, 0, &error))
399 return; 398 return;
400 error = xchk_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur, oinfo, 399 error = xchk_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur,
401 &blocks); 400 &XFS_RMAP_OINFO_REFC, &blocks);
402 if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur)) 401 if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur))
403 return; 402 return;
404 if (blocks != refcbt_blocks) 403 if (blocks != refcbt_blocks)
405 xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0); 404 xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0);
406 405
407 /* Check that we saw as many cow blocks as the rmap knows about. */ 406 /* Check that we saw as many cow blocks as the rmap knows about. */
408 xfs_rmap_ag_owner(oinfo, XFS_RMAP_OWN_COW); 407 error = xchk_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur,
409 error = xchk_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur, oinfo, 408 &XFS_RMAP_OINFO_COW, &blocks);
410 &blocks);
411 if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur)) 409 if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur))
412 return; 410 return;
413 if (blocks != cow_blocks) 411 if (blocks != cow_blocks)
@@ -419,17 +417,15 @@ int
419xchk_refcountbt( 417xchk_refcountbt(
420 struct xfs_scrub *sc) 418 struct xfs_scrub *sc)
421{ 419{
422 struct xfs_owner_info oinfo;
423 xfs_agblock_t cow_blocks = 0; 420 xfs_agblock_t cow_blocks = 0;
424 int error; 421 int error;
425 422
426 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_REFC);
427 error = xchk_btree(sc, sc->sa.refc_cur, xchk_refcountbt_rec, 423 error = xchk_btree(sc, sc->sa.refc_cur, xchk_refcountbt_rec,
428 &oinfo, &cow_blocks); 424 &XFS_RMAP_OINFO_REFC, &cow_blocks);
429 if (error) 425 if (error)
430 return error; 426 return error;
431 427
432 xchk_refcount_xref_rmap(sc, &oinfo, cow_blocks); 428 xchk_refcount_xref_rmap(sc, cow_blocks);
433 429
434 return 0; 430 return 0;
435} 431}
diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c
index 4fc0a5ea7673..1c8eecfe52b8 100644
--- a/fs/xfs/scrub/repair.c
+++ b/fs/xfs/scrub/repair.c
@@ -299,14 +299,14 @@ xrep_calc_ag_resblks(
299/* Allocate a block in an AG. */ 299/* Allocate a block in an AG. */
300int 300int
301xrep_alloc_ag_block( 301xrep_alloc_ag_block(
302 struct xfs_scrub *sc, 302 struct xfs_scrub *sc,
303 struct xfs_owner_info *oinfo, 303 const struct xfs_owner_info *oinfo,
304 xfs_fsblock_t *fsbno, 304 xfs_fsblock_t *fsbno,
305 enum xfs_ag_resv_type resv) 305 enum xfs_ag_resv_type resv)
306{ 306{
307 struct xfs_alloc_arg args = {0}; 307 struct xfs_alloc_arg args = {0};
308 xfs_agblock_t bno; 308 xfs_agblock_t bno;
309 int error; 309 int error;
310 310
311 switch (resv) { 311 switch (resv) {
312 case XFS_AG_RESV_AGFL: 312 case XFS_AG_RESV_AGFL:
@@ -505,7 +505,6 @@ xrep_put_freelist(
505 struct xfs_scrub *sc, 505 struct xfs_scrub *sc,
506 xfs_agblock_t agbno) 506 xfs_agblock_t agbno)
507{ 507{
508 struct xfs_owner_info oinfo;
509 int error; 508 int error;
510 509
511 /* Make sure there's space on the freelist. */ 510 /* Make sure there's space on the freelist. */
@@ -518,9 +517,8 @@ xrep_put_freelist(
518 * create an rmap for the block prior to merging it or else other 517 * create an rmap for the block prior to merging it or else other
519 * parts will break. 518 * parts will break.
520 */ 519 */
521 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_AG);
522 error = xfs_rmap_alloc(sc->tp, sc->sa.agf_bp, sc->sa.agno, agbno, 1, 520 error = xfs_rmap_alloc(sc->tp, sc->sa.agf_bp, sc->sa.agno, agbno, 1,
523 &oinfo); 521 &XFS_RMAP_OINFO_AG);
524 if (error) 522 if (error)
525 return error; 523 return error;
526 524
@@ -538,17 +536,17 @@ xrep_put_freelist(
538/* Dispose of a single block. */ 536/* Dispose of a single block. */
539STATIC int 537STATIC int
540xrep_reap_block( 538xrep_reap_block(
541 struct xfs_scrub *sc, 539 struct xfs_scrub *sc,
542 xfs_fsblock_t fsbno, 540 xfs_fsblock_t fsbno,
543 struct xfs_owner_info *oinfo, 541 const struct xfs_owner_info *oinfo,
544 enum xfs_ag_resv_type resv) 542 enum xfs_ag_resv_type resv)
545{ 543{
546 struct xfs_btree_cur *cur; 544 struct xfs_btree_cur *cur;
547 struct xfs_buf *agf_bp = NULL; 545 struct xfs_buf *agf_bp = NULL;
548 xfs_agnumber_t agno; 546 xfs_agnumber_t agno;
549 xfs_agblock_t agbno; 547 xfs_agblock_t agbno;
550 bool has_other_rmap; 548 bool has_other_rmap;
551 int error; 549 int error;
552 550
553 agno = XFS_FSB_TO_AGNO(sc->mp, fsbno); 551 agno = XFS_FSB_TO_AGNO(sc->mp, fsbno);
554 agbno = XFS_FSB_TO_AGBNO(sc->mp, fsbno); 552 agbno = XFS_FSB_TO_AGBNO(sc->mp, fsbno);
@@ -612,15 +610,15 @@ out_free:
612/* Dispose of every block of every extent in the bitmap. */ 610/* Dispose of every block of every extent in the bitmap. */
613int 611int
614xrep_reap_extents( 612xrep_reap_extents(
615 struct xfs_scrub *sc, 613 struct xfs_scrub *sc,
616 struct xfs_bitmap *bitmap, 614 struct xfs_bitmap *bitmap,
617 struct xfs_owner_info *oinfo, 615 const struct xfs_owner_info *oinfo,
618 enum xfs_ag_resv_type type) 616 enum xfs_ag_resv_type type)
619{ 617{
620 struct xfs_bitmap_range *bmr; 618 struct xfs_bitmap_range *bmr;
621 struct xfs_bitmap_range *n; 619 struct xfs_bitmap_range *n;
622 xfs_fsblock_t fsbno; 620 xfs_fsblock_t fsbno;
623 int error = 0; 621 int error = 0;
624 622
625 ASSERT(xfs_sb_version_hasrmapbt(&sc->mp->m_sb)); 623 ASSERT(xfs_sb_version_hasrmapbt(&sc->mp->m_sb));
626 624
diff --git a/fs/xfs/scrub/repair.h b/fs/xfs/scrub/repair.h
index 9de321eee4ab..f2fc18bb7605 100644
--- a/fs/xfs/scrub/repair.h
+++ b/fs/xfs/scrub/repair.h
@@ -21,8 +21,9 @@ int xrep_roll_ag_trans(struct xfs_scrub *sc);
21bool xrep_ag_has_space(struct xfs_perag *pag, xfs_extlen_t nr_blocks, 21bool xrep_ag_has_space(struct xfs_perag *pag, xfs_extlen_t nr_blocks,
22 enum xfs_ag_resv_type type); 22 enum xfs_ag_resv_type type);
23xfs_extlen_t xrep_calc_ag_resblks(struct xfs_scrub *sc); 23xfs_extlen_t xrep_calc_ag_resblks(struct xfs_scrub *sc);
24int xrep_alloc_ag_block(struct xfs_scrub *sc, struct xfs_owner_info *oinfo, 24int xrep_alloc_ag_block(struct xfs_scrub *sc,
25 xfs_fsblock_t *fsbno, enum xfs_ag_resv_type resv); 25 const struct xfs_owner_info *oinfo, xfs_fsblock_t *fsbno,
26 enum xfs_ag_resv_type resv);
26int xrep_init_btblock(struct xfs_scrub *sc, xfs_fsblock_t fsb, 27int xrep_init_btblock(struct xfs_scrub *sc, xfs_fsblock_t fsb,
27 struct xfs_buf **bpp, xfs_btnum_t btnum, 28 struct xfs_buf **bpp, xfs_btnum_t btnum,
28 const struct xfs_buf_ops *ops); 29 const struct xfs_buf_ops *ops);
@@ -32,7 +33,7 @@ struct xfs_bitmap;
32int xrep_fix_freelist(struct xfs_scrub *sc, bool can_shrink); 33int xrep_fix_freelist(struct xfs_scrub *sc, bool can_shrink);
33int xrep_invalidate_blocks(struct xfs_scrub *sc, struct xfs_bitmap *btlist); 34int xrep_invalidate_blocks(struct xfs_scrub *sc, struct xfs_bitmap *btlist);
34int xrep_reap_extents(struct xfs_scrub *sc, struct xfs_bitmap *exlist, 35int xrep_reap_extents(struct xfs_scrub *sc, struct xfs_bitmap *exlist,
35 struct xfs_owner_info *oinfo, enum xfs_ag_resv_type type); 36 const struct xfs_owner_info *oinfo, enum xfs_ag_resv_type type);
36 37
37struct xrep_find_ag_btree { 38struct xrep_find_ag_btree {
38 /* in: rmap owner of the btree we're looking for */ 39 /* in: rmap owner of the btree we're looking for */
diff --git a/fs/xfs/scrub/rmap.c b/fs/xfs/scrub/rmap.c
index 5e293c129813..92a140c5b55e 100644
--- a/fs/xfs/scrub/rmap.c
+++ b/fs/xfs/scrub/rmap.c
@@ -174,24 +174,21 @@ int
174xchk_rmapbt( 174xchk_rmapbt(
175 struct xfs_scrub *sc) 175 struct xfs_scrub *sc)
176{ 176{
177 struct xfs_owner_info oinfo;
178
179 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_AG);
180 return xchk_btree(sc, sc->sa.rmap_cur, xchk_rmapbt_rec, 177 return xchk_btree(sc, sc->sa.rmap_cur, xchk_rmapbt_rec,
181 &oinfo, NULL); 178 &XFS_RMAP_OINFO_AG, NULL);
182} 179}
183 180
184/* xref check that the extent is owned by a given owner */ 181/* xref check that the extent is owned by a given owner */
185static inline void 182static inline void
186xchk_xref_check_owner( 183xchk_xref_check_owner(
187 struct xfs_scrub *sc, 184 struct xfs_scrub *sc,
188 xfs_agblock_t bno, 185 xfs_agblock_t bno,
189 xfs_extlen_t len, 186 xfs_extlen_t len,
190 struct xfs_owner_info *oinfo, 187 const struct xfs_owner_info *oinfo,
191 bool should_have_rmap) 188 bool should_have_rmap)
192{ 189{
193 bool has_rmap; 190 bool has_rmap;
194 int error; 191 int error;
195 192
196 if (!sc->sa.rmap_cur || xchk_skip_xref(sc->sm)) 193 if (!sc->sa.rmap_cur || xchk_skip_xref(sc->sm))
197 return; 194 return;
@@ -207,10 +204,10 @@ xchk_xref_check_owner(
207/* xref check that the extent is owned by a given owner */ 204/* xref check that the extent is owned by a given owner */
208void 205void
209xchk_xref_is_owned_by( 206xchk_xref_is_owned_by(
210 struct xfs_scrub *sc, 207 struct xfs_scrub *sc,
211 xfs_agblock_t bno, 208 xfs_agblock_t bno,
212 xfs_extlen_t len, 209 xfs_extlen_t len,
213 struct xfs_owner_info *oinfo) 210 const struct xfs_owner_info *oinfo)
214{ 211{
215 xchk_xref_check_owner(sc, bno, len, oinfo, true); 212 xchk_xref_check_owner(sc, bno, len, oinfo, true);
216} 213}
@@ -218,10 +215,10 @@ xchk_xref_is_owned_by(
218/* xref check that the extent is not owned by a given owner */ 215/* xref check that the extent is not owned by a given owner */
219void 216void
220xchk_xref_is_not_owned_by( 217xchk_xref_is_not_owned_by(
221 struct xfs_scrub *sc, 218 struct xfs_scrub *sc,
222 xfs_agblock_t bno, 219 xfs_agblock_t bno,
223 xfs_extlen_t len, 220 xfs_extlen_t len,
224 struct xfs_owner_info *oinfo) 221 const struct xfs_owner_info *oinfo)
225{ 222{
226 xchk_xref_check_owner(sc, bno, len, oinfo, false); 223 xchk_xref_check_owner(sc, bno, len, oinfo, false);
227} 224}
diff --git a/fs/xfs/scrub/scrub.h b/fs/xfs/scrub/scrub.h
index af323b229c4b..22f754fba8e5 100644
--- a/fs/xfs/scrub/scrub.h
+++ b/fs/xfs/scrub/scrub.h
@@ -122,9 +122,9 @@ void xchk_xref_is_not_inode_chunk(struct xfs_scrub *sc, xfs_agblock_t agbno,
122void xchk_xref_is_inode_chunk(struct xfs_scrub *sc, xfs_agblock_t agbno, 122void xchk_xref_is_inode_chunk(struct xfs_scrub *sc, xfs_agblock_t agbno,
123 xfs_extlen_t len); 123 xfs_extlen_t len);
124void xchk_xref_is_owned_by(struct xfs_scrub *sc, xfs_agblock_t agbno, 124void xchk_xref_is_owned_by(struct xfs_scrub *sc, xfs_agblock_t agbno,
125 xfs_extlen_t len, struct xfs_owner_info *oinfo); 125 xfs_extlen_t len, const struct xfs_owner_info *oinfo);
126void xchk_xref_is_not_owned_by(struct xfs_scrub *sc, xfs_agblock_t agbno, 126void xchk_xref_is_not_owned_by(struct xfs_scrub *sc, xfs_agblock_t agbno,
127 xfs_extlen_t len, struct xfs_owner_info *oinfo); 127 xfs_extlen_t len, const struct xfs_owner_info *oinfo);
128void xchk_xref_has_no_owner(struct xfs_scrub *sc, xfs_agblock_t agbno, 128void xchk_xref_has_no_owner(struct xfs_scrub *sc, xfs_agblock_t agbno,
129 xfs_extlen_t len); 129 xfs_extlen_t len);
130void xchk_xref_is_cow_staging(struct xfs_scrub *sc, xfs_agblock_t bno, 130void xchk_xref_is_cow_staging(struct xfs_scrub *sc, xfs_agblock_t bno,
diff --git a/fs/xfs/scrub/trace.h b/fs/xfs/scrub/trace.h
index 4e20f0e48232..8344b14031ef 100644
--- a/fs/xfs/scrub/trace.h
+++ b/fs/xfs/scrub/trace.h
@@ -12,6 +12,71 @@
12#include <linux/tracepoint.h> 12#include <linux/tracepoint.h>
13#include "xfs_bit.h" 13#include "xfs_bit.h"
14 14
15/*
16 * ftrace's __print_symbolic requires that all enum values be wrapped in the
17 * TRACE_DEFINE_ENUM macro so that the enum value can be encoded in the ftrace
18 * ring buffer. Somehow this was only worth mentioning in the ftrace sample
19 * code.
20 */
21TRACE_DEFINE_ENUM(XFS_BTNUM_BNOi);
22TRACE_DEFINE_ENUM(XFS_BTNUM_CNTi);
23TRACE_DEFINE_ENUM(XFS_BTNUM_BMAPi);
24TRACE_DEFINE_ENUM(XFS_BTNUM_INOi);
25TRACE_DEFINE_ENUM(XFS_BTNUM_FINOi);
26TRACE_DEFINE_ENUM(XFS_BTNUM_RMAPi);
27TRACE_DEFINE_ENUM(XFS_BTNUM_REFCi);
28
29TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_PROBE);
30TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_SB);
31TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_AGF);
32TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_AGFL);
33TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_AGI);
34TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_BNOBT);
35TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_CNTBT);
36TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_INOBT);
37TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_FINOBT);
38TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_RMAPBT);
39TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_REFCNTBT);
40TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_INODE);
41TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_BMBTD);
42TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_BMBTA);
43TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_BMBTC);
44TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_DIR);
45TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_XATTR);
46TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_SYMLINK);
47TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_PARENT);
48TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_RTBITMAP);
49TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_RTSUM);
50TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_UQUOTA);
51TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_GQUOTA);
52TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_PQUOTA);
53
54#define XFS_SCRUB_TYPE_STRINGS \
55 { XFS_SCRUB_TYPE_PROBE, "probe" }, \
56 { XFS_SCRUB_TYPE_SB, "sb" }, \
57 { XFS_SCRUB_TYPE_AGF, "agf" }, \
58 { XFS_SCRUB_TYPE_AGFL, "agfl" }, \
59 { XFS_SCRUB_TYPE_AGI, "agi" }, \
60 { XFS_SCRUB_TYPE_BNOBT, "bnobt" }, \
61 { XFS_SCRUB_TYPE_CNTBT, "cntbt" }, \
62 { XFS_SCRUB_TYPE_INOBT, "inobt" }, \
63 { XFS_SCRUB_TYPE_FINOBT, "finobt" }, \
64 { XFS_SCRUB_TYPE_RMAPBT, "rmapbt" }, \
65 { XFS_SCRUB_TYPE_REFCNTBT, "refcountbt" }, \
66 { XFS_SCRUB_TYPE_INODE, "inode" }, \
67 { XFS_SCRUB_TYPE_BMBTD, "bmapbtd" }, \
68 { XFS_SCRUB_TYPE_BMBTA, "bmapbta" }, \
69 { XFS_SCRUB_TYPE_BMBTC, "bmapbtc" }, \
70 { XFS_SCRUB_TYPE_DIR, "directory" }, \
71 { XFS_SCRUB_TYPE_XATTR, "xattr" }, \
72 { XFS_SCRUB_TYPE_SYMLINK, "symlink" }, \
73 { XFS_SCRUB_TYPE_PARENT, "parent" }, \
74 { XFS_SCRUB_TYPE_RTBITMAP, "rtbitmap" }, \
75 { XFS_SCRUB_TYPE_RTSUM, "rtsummary" }, \
76 { XFS_SCRUB_TYPE_UQUOTA, "usrquota" }, \
77 { XFS_SCRUB_TYPE_GQUOTA, "grpquota" }, \
78 { XFS_SCRUB_TYPE_PQUOTA, "prjquota" }
79
15DECLARE_EVENT_CLASS(xchk_class, 80DECLARE_EVENT_CLASS(xchk_class,
16 TP_PROTO(struct xfs_inode *ip, struct xfs_scrub_metadata *sm, 81 TP_PROTO(struct xfs_inode *ip, struct xfs_scrub_metadata *sm,
17 int error), 82 int error),
@@ -36,10 +101,10 @@ DECLARE_EVENT_CLASS(xchk_class,
36 __entry->flags = sm->sm_flags; 101 __entry->flags = sm->sm_flags;
37 __entry->error = error; 102 __entry->error = error;
38 ), 103 ),
39 TP_printk("dev %d:%d ino 0x%llx type %u agno %u inum %llu gen %u flags 0x%x error %d", 104 TP_printk("dev %d:%d ino 0x%llx type %s agno %u inum %llu gen %u flags 0x%x error %d",
40 MAJOR(__entry->dev), MINOR(__entry->dev), 105 MAJOR(__entry->dev), MINOR(__entry->dev),
41 __entry->ino, 106 __entry->ino,
42 __entry->type, 107 __print_symbolic(__entry->type, XFS_SCRUB_TYPE_STRINGS),
43 __entry->agno, 108 __entry->agno,
44 __entry->inum, 109 __entry->inum,
45 __entry->gen, 110 __entry->gen,
@@ -78,9 +143,9 @@ TRACE_EVENT(xchk_op_error,
78 __entry->error = error; 143 __entry->error = error;
79 __entry->ret_ip = ret_ip; 144 __entry->ret_ip = ret_ip;
80 ), 145 ),
81 TP_printk("dev %d:%d type %u agno %u agbno %u error %d ret_ip %pS", 146 TP_printk("dev %d:%d type %s agno %u agbno %u error %d ret_ip %pS",
82 MAJOR(__entry->dev), MINOR(__entry->dev), 147 MAJOR(__entry->dev), MINOR(__entry->dev),
83 __entry->type, 148 __print_symbolic(__entry->type, XFS_SCRUB_TYPE_STRINGS),
84 __entry->agno, 149 __entry->agno,
85 __entry->bno, 150 __entry->bno,
86 __entry->error, 151 __entry->error,
@@ -109,11 +174,11 @@ TRACE_EVENT(xchk_file_op_error,
109 __entry->error = error; 174 __entry->error = error;
110 __entry->ret_ip = ret_ip; 175 __entry->ret_ip = ret_ip;
111 ), 176 ),
112 TP_printk("dev %d:%d ino 0x%llx fork %d type %u offset %llu error %d ret_ip %pS", 177 TP_printk("dev %d:%d ino 0x%llx fork %d type %s offset %llu error %d ret_ip %pS",
113 MAJOR(__entry->dev), MINOR(__entry->dev), 178 MAJOR(__entry->dev), MINOR(__entry->dev),
114 __entry->ino, 179 __entry->ino,
115 __entry->whichfork, 180 __entry->whichfork,
116 __entry->type, 181 __print_symbolic(__entry->type, XFS_SCRUB_TYPE_STRINGS),
117 __entry->offset, 182 __entry->offset,
118 __entry->error, 183 __entry->error,
119 __entry->ret_ip) 184 __entry->ret_ip)
@@ -144,9 +209,9 @@ DECLARE_EVENT_CLASS(xchk_block_error_class,
144 __entry->bno = bno; 209 __entry->bno = bno;
145 __entry->ret_ip = ret_ip; 210 __entry->ret_ip = ret_ip;
146 ), 211 ),
147 TP_printk("dev %d:%d type %u agno %u agbno %u ret_ip %pS", 212 TP_printk("dev %d:%d type %s agno %u agbno %u ret_ip %pS",
148 MAJOR(__entry->dev), MINOR(__entry->dev), 213 MAJOR(__entry->dev), MINOR(__entry->dev),
149 __entry->type, 214 __print_symbolic(__entry->type, XFS_SCRUB_TYPE_STRINGS),
150 __entry->agno, 215 __entry->agno,
151 __entry->bno, 216 __entry->bno,
152 __entry->ret_ip) 217 __entry->ret_ip)
@@ -176,10 +241,10 @@ DECLARE_EVENT_CLASS(xchk_ino_error_class,
176 __entry->type = sc->sm->sm_type; 241 __entry->type = sc->sm->sm_type;
177 __entry->ret_ip = ret_ip; 242 __entry->ret_ip = ret_ip;
178 ), 243 ),
179 TP_printk("dev %d:%d ino 0x%llx type %u ret_ip %pS", 244 TP_printk("dev %d:%d ino 0x%llx type %s ret_ip %pS",
180 MAJOR(__entry->dev), MINOR(__entry->dev), 245 MAJOR(__entry->dev), MINOR(__entry->dev),
181 __entry->ino, 246 __entry->ino,
182 __entry->type, 247 __print_symbolic(__entry->type, XFS_SCRUB_TYPE_STRINGS),
183 __entry->ret_ip) 248 __entry->ret_ip)
184) 249)
185 250
@@ -213,11 +278,11 @@ DECLARE_EVENT_CLASS(xchk_fblock_error_class,
213 __entry->offset = offset; 278 __entry->offset = offset;
214 __entry->ret_ip = ret_ip; 279 __entry->ret_ip = ret_ip;
215 ), 280 ),
216 TP_printk("dev %d:%d ino 0x%llx fork %d type %u offset %llu ret_ip %pS", 281 TP_printk("dev %d:%d ino 0x%llx fork %d type %s offset %llu ret_ip %pS",
217 MAJOR(__entry->dev), MINOR(__entry->dev), 282 MAJOR(__entry->dev), MINOR(__entry->dev),
218 __entry->ino, 283 __entry->ino,
219 __entry->whichfork, 284 __entry->whichfork,
220 __entry->type, 285 __print_symbolic(__entry->type, XFS_SCRUB_TYPE_STRINGS),
221 __entry->offset, 286 __entry->offset,
222 __entry->ret_ip) 287 __entry->ret_ip)
223); 288);
@@ -244,9 +309,9 @@ TRACE_EVENT(xchk_incomplete,
244 __entry->type = sc->sm->sm_type; 309 __entry->type = sc->sm->sm_type;
245 __entry->ret_ip = ret_ip; 310 __entry->ret_ip = ret_ip;
246 ), 311 ),
247 TP_printk("dev %d:%d type %u ret_ip %pS", 312 TP_printk("dev %d:%d type %s ret_ip %pS",
248 MAJOR(__entry->dev), MINOR(__entry->dev), 313 MAJOR(__entry->dev), MINOR(__entry->dev),
249 __entry->type, 314 __print_symbolic(__entry->type, XFS_SCRUB_TYPE_STRINGS),
250 __entry->ret_ip) 315 __entry->ret_ip)
251); 316);
252 317
@@ -278,10 +343,10 @@ TRACE_EVENT(xchk_btree_op_error,
278 __entry->error = error; 343 __entry->error = error;
279 __entry->ret_ip = ret_ip; 344 __entry->ret_ip = ret_ip;
280 ), 345 ),
281 TP_printk("dev %d:%d type %u btnum %d level %d ptr %d agno %u agbno %u error %d ret_ip %pS", 346 TP_printk("dev %d:%d type %s btree %s level %d ptr %d agno %u agbno %u error %d ret_ip %pS",
282 MAJOR(__entry->dev), MINOR(__entry->dev), 347 MAJOR(__entry->dev), MINOR(__entry->dev),
283 __entry->type, 348 __print_symbolic(__entry->type, XFS_SCRUB_TYPE_STRINGS),
284 __entry->btnum, 349 __print_symbolic(__entry->btnum, XFS_BTNUM_STRINGS),
285 __entry->level, 350 __entry->level,
286 __entry->ptr, 351 __entry->ptr,
287 __entry->agno, 352 __entry->agno,
@@ -321,12 +386,12 @@ TRACE_EVENT(xchk_ifork_btree_op_error,
321 __entry->error = error; 386 __entry->error = error;
322 __entry->ret_ip = ret_ip; 387 __entry->ret_ip = ret_ip;
323 ), 388 ),
324 TP_printk("dev %d:%d ino 0x%llx fork %d type %u btnum %d level %d ptr %d agno %u agbno %u error %d ret_ip %pS", 389 TP_printk("dev %d:%d ino 0x%llx fork %d type %s btree %s level %d ptr %d agno %u agbno %u error %d ret_ip %pS",
325 MAJOR(__entry->dev), MINOR(__entry->dev), 390 MAJOR(__entry->dev), MINOR(__entry->dev),
326 __entry->ino, 391 __entry->ino,
327 __entry->whichfork, 392 __entry->whichfork,
328 __entry->type, 393 __print_symbolic(__entry->type, XFS_SCRUB_TYPE_STRINGS),
329 __entry->btnum, 394 __print_symbolic(__entry->btnum, XFS_BTNUM_STRINGS),
330 __entry->level, 395 __entry->level,
331 __entry->ptr, 396 __entry->ptr,
332 __entry->agno, 397 __entry->agno,
@@ -360,10 +425,10 @@ TRACE_EVENT(xchk_btree_error,
360 __entry->ptr = cur->bc_ptrs[level]; 425 __entry->ptr = cur->bc_ptrs[level];
361 __entry->ret_ip = ret_ip; 426 __entry->ret_ip = ret_ip;
362 ), 427 ),
363 TP_printk("dev %d:%d type %u btnum %d level %d ptr %d agno %u agbno %u ret_ip %pS", 428 TP_printk("dev %d:%d type %s btree %s level %d ptr %d agno %u agbno %u ret_ip %pS",
364 MAJOR(__entry->dev), MINOR(__entry->dev), 429 MAJOR(__entry->dev), MINOR(__entry->dev),
365 __entry->type, 430 __print_symbolic(__entry->type, XFS_SCRUB_TYPE_STRINGS),
366 __entry->btnum, 431 __print_symbolic(__entry->btnum, XFS_BTNUM_STRINGS),
367 __entry->level, 432 __entry->level,
368 __entry->ptr, 433 __entry->ptr,
369 __entry->agno, 434 __entry->agno,
@@ -400,12 +465,12 @@ TRACE_EVENT(xchk_ifork_btree_error,
400 __entry->ptr = cur->bc_ptrs[level]; 465 __entry->ptr = cur->bc_ptrs[level];
401 __entry->ret_ip = ret_ip; 466 __entry->ret_ip = ret_ip;
402 ), 467 ),
403 TP_printk("dev %d:%d ino 0x%llx fork %d type %u btnum %d level %d ptr %d agno %u agbno %u ret_ip %pS", 468 TP_printk("dev %d:%d ino 0x%llx fork %d type %s btree %s level %d ptr %d agno %u agbno %u ret_ip %pS",
404 MAJOR(__entry->dev), MINOR(__entry->dev), 469 MAJOR(__entry->dev), MINOR(__entry->dev),
405 __entry->ino, 470 __entry->ino,
406 __entry->whichfork, 471 __entry->whichfork,
407 __entry->type, 472 __print_symbolic(__entry->type, XFS_SCRUB_TYPE_STRINGS),
408 __entry->btnum, 473 __print_symbolic(__entry->btnum, XFS_BTNUM_STRINGS),
409 __entry->level, 474 __entry->level,
410 __entry->ptr, 475 __entry->ptr,
411 __entry->agno, 476 __entry->agno,
@@ -439,10 +504,10 @@ DECLARE_EVENT_CLASS(xchk_sbtree_class,
439 __entry->nlevels = cur->bc_nlevels; 504 __entry->nlevels = cur->bc_nlevels;
440 __entry->ptr = cur->bc_ptrs[level]; 505 __entry->ptr = cur->bc_ptrs[level];
441 ), 506 ),
442 TP_printk("dev %d:%d type %u btnum %d agno %u agbno %u level %d nlevels %d ptr %d", 507 TP_printk("dev %d:%d type %s btree %s agno %u agbno %u level %d nlevels %d ptr %d",
443 MAJOR(__entry->dev), MINOR(__entry->dev), 508 MAJOR(__entry->dev), MINOR(__entry->dev),
444 __entry->type, 509 __print_symbolic(__entry->type, XFS_SCRUB_TYPE_STRINGS),
445 __entry->btnum, 510 __print_symbolic(__entry->btnum, XFS_BTNUM_STRINGS),
446 __entry->agno, 511 __entry->agno,
447 __entry->bno, 512 __entry->bno,
448 __entry->level, 513 __entry->level,
@@ -473,9 +538,9 @@ TRACE_EVENT(xchk_xref_error,
473 __entry->error = error; 538 __entry->error = error;
474 __entry->ret_ip = ret_ip; 539 __entry->ret_ip = ret_ip;
475 ), 540 ),
476 TP_printk("dev %d:%d type %u xref error %d ret_ip %pF", 541 TP_printk("dev %d:%d type %s xref error %d ret_ip %pS",
477 MAJOR(__entry->dev), MINOR(__entry->dev), 542 MAJOR(__entry->dev), MINOR(__entry->dev),
478 __entry->type, 543 __print_symbolic(__entry->type, XFS_SCRUB_TYPE_STRINGS),
479 __entry->error, 544 __entry->error,
480 __entry->ret_ip) 545 __entry->ret_ip)
481); 546);
@@ -598,11 +663,11 @@ TRACE_EVENT(xrep_init_btblock,
598 __entry->agbno = agbno; 663 __entry->agbno = agbno;
599 __entry->btnum = btnum; 664 __entry->btnum = btnum;
600 ), 665 ),
601 TP_printk("dev %d:%d agno %u agbno %u btnum %d", 666 TP_printk("dev %d:%d agno %u agbno %u btree %s",
602 MAJOR(__entry->dev), MINOR(__entry->dev), 667 MAJOR(__entry->dev), MINOR(__entry->dev),
603 __entry->agno, 668 __entry->agno,
604 __entry->agbno, 669 __entry->agbno,
605 __entry->btnum) 670 __print_symbolic(__entry->btnum, XFS_BTNUM_STRINGS))
606) 671)
607TRACE_EVENT(xrep_findroot_block, 672TRACE_EVENT(xrep_findroot_block,
608 TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agblock_t agbno, 673 TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agblock_t agbno,
diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h
index 494b4338446e..e5c23948a8ab 100644
--- a/fs/xfs/xfs_aops.h
+++ b/fs/xfs/xfs_aops.h
@@ -10,6 +10,9 @@ extern struct bio_set xfs_ioend_bioset;
10 10
11/* 11/*
12 * Types of I/O for bmap clustering and I/O completion tracking. 12 * Types of I/O for bmap clustering and I/O completion tracking.
13 *
14 * This enum is used in string mapping in xfs_trace.h; please keep the
15 * TRACE_DEFINE_ENUMs for it up to date.
13 */ 16 */
14enum { 17enum {
15 XFS_IO_HOLE, /* covers region without any block allocation */ 18 XFS_IO_HOLE, /* covers region without any block allocation */
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index d9da66c718bb..74ddf66f4cfe 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -494,7 +494,6 @@ xfs_efi_recover(
494 int error = 0; 494 int error = 0;
495 xfs_extent_t *extp; 495 xfs_extent_t *extp;
496 xfs_fsblock_t startblock_fsb; 496 xfs_fsblock_t startblock_fsb;
497 struct xfs_owner_info oinfo;
498 497
499 ASSERT(!test_bit(XFS_EFI_RECOVERED, &efip->efi_flags)); 498 ASSERT(!test_bit(XFS_EFI_RECOVERED, &efip->efi_flags));
500 499
@@ -526,11 +525,11 @@ xfs_efi_recover(
526 return error; 525 return error;
527 efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents); 526 efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents);
528 527
529 xfs_rmap_any_owner_update(&oinfo);
530 for (i = 0; i < efip->efi_format.efi_nextents; i++) { 528 for (i = 0; i < efip->efi_format.efi_nextents; i++) {
531 extp = &efip->efi_format.efi_extents[i]; 529 extp = &efip->efi_format.efi_extents[i];
532 error = xfs_trans_free_extent(tp, efdp, extp->ext_start, 530 error = xfs_trans_free_extent(tp, efdp, extp->ext_start,
533 extp->ext_len, &oinfo, false); 531 extp->ext_len,
532 &XFS_RMAP_OINFO_ANY_OWNER, false);
534 if (error) 533 if (error)
535 goto abort_error; 534 goto abort_error;
536 535
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 093c2b8d7e20..ec2e63a7963b 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -252,7 +252,7 @@ xfs_growfs_data(
252 if (mp->m_sb.sb_imax_pct) { 252 if (mp->m_sb.sb_imax_pct) {
253 uint64_t icount = mp->m_sb.sb_dblocks * mp->m_sb.sb_imax_pct; 253 uint64_t icount = mp->m_sb.sb_dblocks * mp->m_sb.sb_imax_pct;
254 do_div(icount, 100); 254 do_div(icount, 100);
255 mp->m_maxicount = icount << mp->m_sb.sb_inopblog; 255 mp->m_maxicount = XFS_FSB_TO_INO(mp, icount);
256 } else 256 } else
257 mp->m_maxicount = 0; 257 mp->m_maxicount = 0;
258 258
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 05db9540e459..ae667ba74a1c 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2184,8 +2184,6 @@ xfs_ifree_cluster(
2184 struct xfs_icluster *xic) 2184 struct xfs_icluster *xic)
2185{ 2185{
2186 xfs_mount_t *mp = free_ip->i_mount; 2186 xfs_mount_t *mp = free_ip->i_mount;
2187 int blks_per_cluster;
2188 int inodes_per_cluster;
2189 int nbufs; 2187 int nbufs;
2190 int i, j; 2188 int i, j;
2191 int ioffset; 2189 int ioffset;
@@ -2199,11 +2197,9 @@ xfs_ifree_cluster(
2199 2197
2200 inum = xic->first_ino; 2198 inum = xic->first_ino;
2201 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, inum)); 2199 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, inum));
2202 blks_per_cluster = xfs_icluster_size_fsb(mp); 2200 nbufs = mp->m_ialloc_blks / mp->m_blocks_per_cluster;
2203 inodes_per_cluster = blks_per_cluster << mp->m_sb.sb_inopblog;
2204 nbufs = mp->m_ialloc_blks / blks_per_cluster;
2205 2201
2206 for (j = 0; j < nbufs; j++, inum += inodes_per_cluster) { 2202 for (j = 0; j < nbufs; j++, inum += mp->m_inodes_per_cluster) {
2207 /* 2203 /*
2208 * The allocation bitmap tells us which inodes of the chunk were 2204 * The allocation bitmap tells us which inodes of the chunk were
2209 * physically allocated. Skip the cluster if an inode falls into 2205 * physically allocated. Skip the cluster if an inode falls into
@@ -2211,7 +2207,7 @@ xfs_ifree_cluster(
2211 */ 2207 */
2212 ioffset = inum - xic->first_ino; 2208 ioffset = inum - xic->first_ino;
2213 if ((xic->alloc & XFS_INOBT_MASK(ioffset)) == 0) { 2209 if ((xic->alloc & XFS_INOBT_MASK(ioffset)) == 0) {
2214 ASSERT(ioffset % inodes_per_cluster == 0); 2210 ASSERT(ioffset % mp->m_inodes_per_cluster == 0);
2215 continue; 2211 continue;
2216 } 2212 }
2217 2213
@@ -2227,7 +2223,7 @@ xfs_ifree_cluster(
2227 * to mark all the active inodes on the buffer stale. 2223 * to mark all the active inodes on the buffer stale.
2228 */ 2224 */
2229 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno, 2225 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno,
2230 mp->m_bsize * blks_per_cluster, 2226 mp->m_bsize * mp->m_blocks_per_cluster,
2231 XBF_UNMAPPED); 2227 XBF_UNMAPPED);
2232 2228
2233 if (!bp) 2229 if (!bp)
@@ -2242,7 +2238,7 @@ xfs_ifree_cluster(
2242 * want it to fail. We can acheive this by adding a write 2238 * want it to fail. We can acheive this by adding a write
2243 * verifier to the buffer. 2239 * verifier to the buffer.
2244 */ 2240 */
2245 bp->b_ops = &xfs_inode_buf_ops; 2241 bp->b_ops = &xfs_inode_buf_ops;
2246 2242
2247 /* 2243 /*
2248 * Walk the inodes already attached to the buffer and mark them 2244 * Walk the inodes already attached to the buffer and mark them
@@ -2274,7 +2270,7 @@ xfs_ifree_cluster(
2274 * transaction stale above, which means there is no point in 2270 * transaction stale above, which means there is no point in
2275 * even trying to lock them. 2271 * even trying to lock them.
2276 */ 2272 */
2277 for (i = 0; i < inodes_per_cluster; i++) { 2273 for (i = 0; i < mp->m_inodes_per_cluster; i++) {
2278retry: 2274retry:
2279 rcu_read_lock(); 2275 rcu_read_lock();
2280 ip = radix_tree_lookup(&pag->pag_ici_root, 2276 ip = radix_tree_lookup(&pag->pag_ici_root,
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index fba115f4103a..5001dca361e9 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -241,6 +241,32 @@ xfs_compat_ioc_bulkstat(
241 int done; 241 int done;
242 int error; 242 int error;
243 243
244 /*
245 * Output structure handling functions. Depending on the command,
246 * either the xfs_bstat and xfs_inogrp structures are written out
247 * to userpace memory via bulkreq.ubuffer. Normally the compat
248 * functions and structure size are the correct ones to use ...
249 */
250 inumbers_fmt_pf inumbers_func = xfs_inumbers_fmt_compat;
251 bulkstat_one_pf bs_one_func = xfs_bulkstat_one_compat;
252 size_t bs_one_size = sizeof(struct compat_xfs_bstat);
253
254#ifdef CONFIG_X86_X32
255 if (in_x32_syscall()) {
256 /*
257 * ... but on x32 the input xfs_fsop_bulkreq has pointers
258 * which must be handled in the "compat" (32-bit) way, while
259 * the xfs_bstat and xfs_inogrp structures follow native 64-
260 * bit layout convention. So adjust accordingly, otherwise
261 * the data written out in compat layout will not match what
262 * x32 userspace expects.
263 */
264 inumbers_func = xfs_inumbers_fmt;
265 bs_one_func = xfs_bulkstat_one;
266 bs_one_size = sizeof(struct xfs_bstat);
267 }
268#endif
269
244 /* done = 1 if there are more stats to get and if bulkstat */ 270 /* done = 1 if there are more stats to get and if bulkstat */
245 /* should be called again (unused here, but used in dmapi) */ 271 /* should be called again (unused here, but used in dmapi) */
246 272
@@ -272,15 +298,15 @@ xfs_compat_ioc_bulkstat(
272 298
273 if (cmd == XFS_IOC_FSINUMBERS_32) { 299 if (cmd == XFS_IOC_FSINUMBERS_32) {
274 error = xfs_inumbers(mp, &inlast, &count, 300 error = xfs_inumbers(mp, &inlast, &count,
275 bulkreq.ubuffer, xfs_inumbers_fmt_compat); 301 bulkreq.ubuffer, inumbers_func);
276 } else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE_32) { 302 } else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE_32) {
277 int res; 303 int res;
278 304
279 error = xfs_bulkstat_one_compat(mp, inlast, bulkreq.ubuffer, 305 error = bs_one_func(mp, inlast, bulkreq.ubuffer,
280 sizeof(compat_xfs_bstat_t), NULL, &res); 306 bs_one_size, NULL, &res);
281 } else if (cmd == XFS_IOC_FSBULKSTAT_32) { 307 } else if (cmd == XFS_IOC_FSBULKSTAT_32) {
282 error = xfs_bulkstat(mp, &inlast, &count, 308 error = xfs_bulkstat(mp, &inlast, &count,
283 xfs_bulkstat_one_compat, sizeof(compat_xfs_bstat_t), 309 bs_one_func, bs_one_size,
284 bulkreq.ubuffer, &done); 310 bulkreq.ubuffer, &done);
285 } else 311 } else
286 error = -EINVAL; 312 error = -EINVAL;
@@ -336,6 +362,7 @@ xfs_compat_attrlist_by_handle(
336{ 362{
337 int error; 363 int error;
338 attrlist_cursor_kern_t *cursor; 364 attrlist_cursor_kern_t *cursor;
365 compat_xfs_fsop_attrlist_handlereq_t __user *p = arg;
339 compat_xfs_fsop_attrlist_handlereq_t al_hreq; 366 compat_xfs_fsop_attrlist_handlereq_t al_hreq;
340 struct dentry *dentry; 367 struct dentry *dentry;
341 char *kbuf; 368 char *kbuf;
@@ -370,6 +397,11 @@ xfs_compat_attrlist_by_handle(
370 if (error) 397 if (error)
371 goto out_kfree; 398 goto out_kfree;
372 399
400 if (copy_to_user(&p->pos, cursor, sizeof(attrlist_cursor_kern_t))) {
401 error = -EFAULT;
402 goto out_kfree;
403 }
404
373 if (copy_to_user(compat_ptr(al_hreq.buffer), kbuf, al_hreq.buflen)) 405 if (copy_to_user(compat_ptr(al_hreq.buffer), kbuf, al_hreq.buflen))
374 error = -EFAULT; 406 error = -EFAULT;
375 407
@@ -547,8 +579,12 @@ xfs_file_compat_ioctl(
547 case FS_IOC_GETFSMAP: 579 case FS_IOC_GETFSMAP:
548 case XFS_IOC_SCRUB_METADATA: 580 case XFS_IOC_SCRUB_METADATA:
549 return xfs_file_ioctl(filp, cmd, p); 581 return xfs_file_ioctl(filp, cmd, p);
550#ifndef BROKEN_X86_ALIGNMENT 582#if !defined(BROKEN_X86_ALIGNMENT) || defined(CONFIG_X86_X32)
551 /* These are handled fine if no alignment issues */ 583 /*
584 * These are handled fine if no alignment issues. To support x32
585 * which uses native 64-bit alignment we must emit these cases in
586 * addition to the ia-32 compat set below.
587 */
552 case XFS_IOC_ALLOCSP: 588 case XFS_IOC_ALLOCSP:
553 case XFS_IOC_FREESP: 589 case XFS_IOC_FREESP:
554 case XFS_IOC_RESVSP: 590 case XFS_IOC_RESVSP:
@@ -561,8 +597,16 @@ xfs_file_compat_ioctl(
561 case XFS_IOC_FSGROWFSDATA: 597 case XFS_IOC_FSGROWFSDATA:
562 case XFS_IOC_FSGROWFSRT: 598 case XFS_IOC_FSGROWFSRT:
563 case XFS_IOC_ZERO_RANGE: 599 case XFS_IOC_ZERO_RANGE:
600#ifdef CONFIG_X86_X32
601 /*
602 * x32 special: this gets a different cmd number from the ia-32 compat
603 * case below; the associated data will match native 64-bit alignment.
604 */
605 case XFS_IOC_SWAPEXT:
606#endif
564 return xfs_file_ioctl(filp, cmd, p); 607 return xfs_file_ioctl(filp, cmd, p);
565#else 608#endif
609#if defined(BROKEN_X86_ALIGNMENT)
566 case XFS_IOC_ALLOCSP_32: 610 case XFS_IOC_ALLOCSP_32:
567 case XFS_IOC_FREESP_32: 611 case XFS_IOC_FREESP_32:
568 case XFS_IOC_ALLOCSP64_32: 612 case XFS_IOC_ALLOCSP64_32:
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index e9508ba01ed1..942e4aa5e729 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -167,20 +167,18 @@ xfs_bulkstat_ichunk_ra(
167{ 167{
168 xfs_agblock_t agbno; 168 xfs_agblock_t agbno;
169 struct blk_plug plug; 169 struct blk_plug plug;
170 int blks_per_cluster;
171 int inodes_per_cluster;
172 int i; /* inode chunk index */ 170 int i; /* inode chunk index */
173 171
174 agbno = XFS_AGINO_TO_AGBNO(mp, irec->ir_startino); 172 agbno = XFS_AGINO_TO_AGBNO(mp, irec->ir_startino);
175 blks_per_cluster = xfs_icluster_size_fsb(mp);
176 inodes_per_cluster = blks_per_cluster << mp->m_sb.sb_inopblog;
177 173
178 blk_start_plug(&plug); 174 blk_start_plug(&plug);
179 for (i = 0; i < XFS_INODES_PER_CHUNK; 175 for (i = 0; i < XFS_INODES_PER_CHUNK;
180 i += inodes_per_cluster, agbno += blks_per_cluster) { 176 i += mp->m_inodes_per_cluster, agbno += mp->m_blocks_per_cluster) {
181 if (xfs_inobt_maskn(i, inodes_per_cluster) & ~irec->ir_free) { 177 if (xfs_inobt_maskn(i, mp->m_inodes_per_cluster) &
182 xfs_btree_reada_bufs(mp, agno, agbno, blks_per_cluster, 178 ~irec->ir_free) {
183 &xfs_inode_buf_ops); 179 xfs_btree_reada_bufs(mp, agno, agbno,
180 mp->m_blocks_per_cluster,
181 &xfs_inode_buf_ops);
184 } 182 }
185 } 183 }
186 blk_finish_plug(&plug); 184 blk_finish_plug(&plug);
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 1fc9e9042e0e..9fe88d125f0a 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -3850,7 +3850,6 @@ xlog_recover_do_icreate_pass2(
3850 unsigned int count; 3850 unsigned int count;
3851 unsigned int isize; 3851 unsigned int isize;
3852 xfs_agblock_t length; 3852 xfs_agblock_t length;
3853 int blks_per_cluster;
3854 int bb_per_cluster; 3853 int bb_per_cluster;
3855 int cancel_count; 3854 int cancel_count;
3856 int nbufs; 3855 int nbufs;
@@ -3918,14 +3917,13 @@ xlog_recover_do_icreate_pass2(
3918 * buffers for cancellation so we don't overwrite anything written after 3917 * buffers for cancellation so we don't overwrite anything written after
3919 * a cancellation. 3918 * a cancellation.
3920 */ 3919 */
3921 blks_per_cluster = xfs_icluster_size_fsb(mp); 3920 bb_per_cluster = XFS_FSB_TO_BB(mp, mp->m_blocks_per_cluster);
3922 bb_per_cluster = XFS_FSB_TO_BB(mp, blks_per_cluster); 3921 nbufs = length / mp->m_blocks_per_cluster;
3923 nbufs = length / blks_per_cluster;
3924 for (i = 0, cancel_count = 0; i < nbufs; i++) { 3922 for (i = 0, cancel_count = 0; i < nbufs; i++) {
3925 xfs_daddr_t daddr; 3923 xfs_daddr_t daddr;
3926 3924
3927 daddr = XFS_AGB_TO_DADDR(mp, agno, 3925 daddr = XFS_AGB_TO_DADDR(mp, agno,
3928 agbno + i * blks_per_cluster); 3926 agbno + i * mp->m_blocks_per_cluster);
3929 if (xlog_check_buffer_cancelled(log, daddr, bb_per_cluster, 0)) 3927 if (xlog_check_buffer_cancelled(log, daddr, bb_per_cluster, 0))
3930 cancel_count++; 3928 cancel_count++;
3931 } 3929 }
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 02d15098dbee..b4d8c318be3c 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -798,6 +798,10 @@ xfs_mountfs(
798 if (mp->m_sb.sb_inoalignmt >= XFS_B_TO_FSBT(mp, new_size)) 798 if (mp->m_sb.sb_inoalignmt >= XFS_B_TO_FSBT(mp, new_size))
799 mp->m_inode_cluster_size = new_size; 799 mp->m_inode_cluster_size = new_size;
800 } 800 }
801 mp->m_blocks_per_cluster = xfs_icluster_size_fsb(mp);
802 mp->m_inodes_per_cluster = XFS_FSB_TO_INO(mp, mp->m_blocks_per_cluster);
803 mp->m_cluster_align = xfs_ialloc_cluster_alignment(mp);
804 mp->m_cluster_align_inodes = XFS_FSB_TO_INO(mp, mp->m_cluster_align);
801 805
802 /* 806 /*
803 * If enabled, sparse inode chunk alignment is expected to match the 807 * If enabled, sparse inode chunk alignment is expected to match the
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 7964513c3128..7daafe064af8 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -89,6 +89,13 @@ typedef struct xfs_mount {
89 int m_logbsize; /* size of each log buffer */ 89 int m_logbsize; /* size of each log buffer */
90 uint m_rsumlevels; /* rt summary levels */ 90 uint m_rsumlevels; /* rt summary levels */
91 uint m_rsumsize; /* size of rt summary, bytes */ 91 uint m_rsumsize; /* size of rt summary, bytes */
92 /*
93 * Optional cache of rt summary level per bitmap block with the
94 * invariant that m_rsum_cache[bbno] <= the minimum i for which
95 * rsum[i][bbno] != 0. Reads and writes are serialized by the rsumip
96 * inode lock.
97 */
98 uint8_t *m_rsum_cache;
92 struct xfs_inode *m_rbmip; /* pointer to bitmap inode */ 99 struct xfs_inode *m_rbmip; /* pointer to bitmap inode */
93 struct xfs_inode *m_rsumip; /* pointer to summary inode */ 100 struct xfs_inode *m_rsumip; /* pointer to summary inode */
94 struct xfs_inode *m_rootip; /* pointer to root directory */ 101 struct xfs_inode *m_rootip; /* pointer to root directory */
@@ -101,6 +108,10 @@ typedef struct xfs_mount {
101 uint8_t m_agno_log; /* log #ag's */ 108 uint8_t m_agno_log; /* log #ag's */
102 uint8_t m_agino_log; /* #bits for agino in inum */ 109 uint8_t m_agino_log; /* #bits for agino in inum */
103 uint m_inode_cluster_size;/* min inode buf size */ 110 uint m_inode_cluster_size;/* min inode buf size */
111 unsigned int m_inodes_per_cluster;
112 unsigned int m_blocks_per_cluster;
113 unsigned int m_cluster_align;
114 unsigned int m_cluster_align_inodes;
104 uint m_blockmask; /* sb_blocksize-1 */ 115 uint m_blockmask; /* sb_blocksize-1 */
105 uint m_blockwsize; /* sb_blocksize in words */ 116 uint m_blockwsize; /* sb_blocksize in words */
106 uint m_blockwmask; /* blockwsize-1 */ 117 uint m_blockwmask; /* blockwsize-1 */
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index 322a852ce284..c5b4fa004ca4 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -623,54 +623,47 @@ out:
623} 623}
624 624
625/* 625/*
626 * Remap parts of a file's data fork after a successful CoW. 626 * Remap part of the CoW fork into the data fork.
627 *
628 * We aim to remap the range starting at @offset_fsb and ending at @end_fsb
629 * into the data fork; this function will remap what it can (at the end of the
630 * range) and update @end_fsb appropriately. Each remap gets its own
631 * transaction because we can end up merging and splitting bmbt blocks for
632 * every remap operation and we'd like to keep the block reservation
633 * requirements as low as possible.
627 */ 634 */
628int 635STATIC int
629xfs_reflink_end_cow( 636xfs_reflink_end_cow_extent(
630 struct xfs_inode *ip, 637 struct xfs_inode *ip,
631 xfs_off_t offset, 638 xfs_fileoff_t offset_fsb,
632 xfs_off_t count) 639 xfs_fileoff_t *end_fsb)
633{ 640{
634 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK); 641 struct xfs_bmbt_irec got, del;
635 struct xfs_bmbt_irec got, del; 642 struct xfs_iext_cursor icur;
636 struct xfs_trans *tp; 643 struct xfs_mount *mp = ip->i_mount;
637 xfs_fileoff_t offset_fsb; 644 struct xfs_trans *tp;
638 xfs_fileoff_t end_fsb; 645 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
639 int error; 646 xfs_filblks_t rlen;
640 unsigned int resblks; 647 unsigned int resblks;
641 xfs_filblks_t rlen; 648 int error;
642 struct xfs_iext_cursor icur;
643
644 trace_xfs_reflink_end_cow(ip, offset, count);
645 649
646 /* No COW extents? That's easy! */ 650 /* No COW extents? That's easy! */
647 if (ifp->if_bytes == 0) 651 if (ifp->if_bytes == 0) {
652 *end_fsb = offset_fsb;
648 return 0; 653 return 0;
654 }
649 655
650 offset_fsb = XFS_B_TO_FSBT(ip->i_mount, offset); 656 resblks = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK);
651 end_fsb = XFS_B_TO_FSB(ip->i_mount, offset + count); 657 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0,
658 XFS_TRANS_RESERVE | XFS_TRANS_NOFS, &tp);
659 if (error)
660 return error;
652 661
653 /* 662 /*
654 * Start a rolling transaction to switch the mappings. We're 663 * Lock the inode. We have to ijoin without automatic unlock because
655 * unlikely ever to have to remap 16T worth of single-block 664 * the lead transaction is the refcountbt record deletion; the data
656 * extents, so just cap the worst case extent count to 2^32-1. 665 * fork update follows as a deferred log item.
657 * Stick a warning in just in case, and avoid 64-bit division.
658 */ 666 */
659 BUILD_BUG_ON(MAX_RW_COUNT > UINT_MAX);
660 if (end_fsb - offset_fsb > UINT_MAX) {
661 error = -EFSCORRUPTED;
662 xfs_force_shutdown(ip->i_mount, SHUTDOWN_CORRUPT_INCORE);
663 ASSERT(0);
664 goto out;
665 }
666 resblks = XFS_NEXTENTADD_SPACE_RES(ip->i_mount,
667 (unsigned int)(end_fsb - offset_fsb),
668 XFS_DATA_FORK);
669 error = xfs_trans_alloc(ip->i_mount, &M_RES(ip->i_mount)->tr_write,
670 resblks, 0, XFS_TRANS_RESERVE | XFS_TRANS_NOFS, &tp);
671 if (error)
672 goto out;
673
674 xfs_ilock(ip, XFS_ILOCK_EXCL); 667 xfs_ilock(ip, XFS_ILOCK_EXCL);
675 xfs_trans_ijoin(tp, ip, 0); 668 xfs_trans_ijoin(tp, ip, 0);
676 669
@@ -679,80 +672,131 @@ xfs_reflink_end_cow(
679 * left by the time I/O completes for the loser of the race. In that 672 * left by the time I/O completes for the loser of the race. In that
680 * case we are done. 673 * case we are done.
681 */ 674 */
682 if (!xfs_iext_lookup_extent_before(ip, ifp, &end_fsb, &icur, &got)) 675 if (!xfs_iext_lookup_extent_before(ip, ifp, end_fsb, &icur, &got) ||
676 got.br_startoff + got.br_blockcount <= offset_fsb) {
677 *end_fsb = offset_fsb;
683 goto out_cancel; 678 goto out_cancel;
679 }
684 680
685 /* Walk backwards until we're out of the I/O range... */ 681 /*
686 while (got.br_startoff + got.br_blockcount > offset_fsb) { 682 * Structure copy @got into @del, then trim @del to the range that we
687 del = got; 683 * were asked to remap. We preserve @got for the eventual CoW fork
688 xfs_trim_extent(&del, offset_fsb, end_fsb - offset_fsb); 684 * deletion; from now on @del represents the mapping that we're
689 685 * actually remapping.
690 /* Extent delete may have bumped ext forward */ 686 */
691 if (!del.br_blockcount) 687 del = got;
692 goto prev_extent; 688 xfs_trim_extent(&del, offset_fsb, *end_fsb - offset_fsb);
693 689
694 /* 690 ASSERT(del.br_blockcount > 0);
695 * Only remap real extent that contain data. With AIO
696 * speculatively preallocations can leak into the range we
697 * are called upon, and we need to skip them.
698 */
699 if (!xfs_bmap_is_real_extent(&got))
700 goto prev_extent;
701 691
702 /* Unmap the old blocks in the data fork. */ 692 /*
703 ASSERT(tp->t_firstblock == NULLFSBLOCK); 693 * Only remap real extents that contain data. With AIO, speculative
704 rlen = del.br_blockcount; 694 * preallocations can leak into the range we are called upon, and we
705 error = __xfs_bunmapi(tp, ip, del.br_startoff, &rlen, 0, 1); 695 * need to skip them.
706 if (error) 696 */
707 goto out_cancel; 697 if (!xfs_bmap_is_real_extent(&got)) {
698 *end_fsb = del.br_startoff;
699 goto out_cancel;
700 }
708 701
709 /* Trim the extent to whatever got unmapped. */ 702 /* Unmap the old blocks in the data fork. */
710 if (rlen) { 703 rlen = del.br_blockcount;
711 xfs_trim_extent(&del, del.br_startoff + rlen, 704 error = __xfs_bunmapi(tp, ip, del.br_startoff, &rlen, 0, 1);
712 del.br_blockcount - rlen); 705 if (error)
713 } 706 goto out_cancel;
714 trace_xfs_reflink_cow_remap(ip, &del);
715 707
716 /* Free the CoW orphan record. */ 708 /* Trim the extent to whatever got unmapped. */
717 error = xfs_refcount_free_cow_extent(tp, del.br_startblock, 709 xfs_trim_extent(&del, del.br_startoff + rlen, del.br_blockcount - rlen);
718 del.br_blockcount); 710 trace_xfs_reflink_cow_remap(ip, &del);
719 if (error)
720 goto out_cancel;
721 711
722 /* Map the new blocks into the data fork. */ 712 /* Free the CoW orphan record. */
723 error = xfs_bmap_map_extent(tp, ip, &del); 713 error = xfs_refcount_free_cow_extent(tp, del.br_startblock,
724 if (error) 714 del.br_blockcount);
725 goto out_cancel; 715 if (error)
716 goto out_cancel;
726 717
727 /* Charge this new data fork mapping to the on-disk quota. */ 718 /* Map the new blocks into the data fork. */
728 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_DELBCOUNT, 719 error = xfs_bmap_map_extent(tp, ip, &del);
729 (long)del.br_blockcount); 720 if (error)
721 goto out_cancel;
730 722
731 /* Remove the mapping from the CoW fork. */ 723 /* Charge this new data fork mapping to the on-disk quota. */
732 xfs_bmap_del_extent_cow(ip, &icur, &got, &del); 724 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_DELBCOUNT,
725 (long)del.br_blockcount);
733 726
734 error = xfs_defer_finish(&tp); 727 /* Remove the mapping from the CoW fork. */
735 if (error) 728 xfs_bmap_del_extent_cow(ip, &icur, &got, &del);
736 goto out_cancel;
737 if (!xfs_iext_get_extent(ifp, &icur, &got))
738 break;
739 continue;
740prev_extent:
741 if (!xfs_iext_prev_extent(ifp, &icur, &got))
742 break;
743 }
744 729
745 error = xfs_trans_commit(tp); 730 error = xfs_trans_commit(tp);
746 xfs_iunlock(ip, XFS_ILOCK_EXCL); 731 xfs_iunlock(ip, XFS_ILOCK_EXCL);
747 if (error) 732 if (error)
748 goto out; 733 return error;
734
735 /* Update the caller about how much progress we made. */
736 *end_fsb = del.br_startoff;
749 return 0; 737 return 0;
750 738
751out_cancel: 739out_cancel:
752 xfs_trans_cancel(tp); 740 xfs_trans_cancel(tp);
753 xfs_iunlock(ip, XFS_ILOCK_EXCL); 741 xfs_iunlock(ip, XFS_ILOCK_EXCL);
754out: 742 return error;
755 trace_xfs_reflink_end_cow_error(ip, error, _RET_IP_); 743}
744
745/*
746 * Remap parts of a file's data fork after a successful CoW.
747 */
748int
749xfs_reflink_end_cow(
750 struct xfs_inode *ip,
751 xfs_off_t offset,
752 xfs_off_t count)
753{
754 xfs_fileoff_t offset_fsb;
755 xfs_fileoff_t end_fsb;
756 int error = 0;
757
758 trace_xfs_reflink_end_cow(ip, offset, count);
759
760 offset_fsb = XFS_B_TO_FSBT(ip->i_mount, offset);
761 end_fsb = XFS_B_TO_FSB(ip->i_mount, offset + count);
762
763 /*
764 * Walk backwards until we're out of the I/O range. The loop function
765 * repeatedly cycles the ILOCK to allocate one transaction per remapped
766 * extent.
767 *
768 * If we're being called by writeback then the the pages will still
769 * have PageWriteback set, which prevents races with reflink remapping
770 * and truncate. Reflink remapping prevents races with writeback by
771 * taking the iolock and mmaplock before flushing the pages and
772 * remapping, which means there won't be any further writeback or page
773 * cache dirtying until the reflink completes.
774 *
775 * We should never have two threads issuing writeback for the same file
776 * region. There are also have post-eof checks in the writeback
777 * preparation code so that we don't bother writing out pages that are
778 * about to be truncated.
779 *
780 * If we're being called as part of directio write completion, the dio
781 * count is still elevated, which reflink and truncate will wait for.
782 * Reflink remapping takes the iolock and mmaplock and waits for
783 * pending dio to finish, which should prevent any directio until the
784 * remap completes. Multiple concurrent directio writes to the same
785 * region are handled by end_cow processing only occurring for the
786 * threads which succeed; the outcome of multiple overlapping direct
787 * writes is not well defined anyway.
788 *
789 * It's possible that a buffered write and a direct write could collide
790 * here (the buffered write stumbles in after the dio flushes and
791 * invalidates the page cache and immediately queues writeback), but we
792 * have never supported this 100%. If either disk write succeeds the
793 * blocks will be remapped.
794 */
795 while (end_fsb > offset_fsb && !error)
796 error = xfs_reflink_end_cow_extent(ip, offset_fsb, &end_fsb);
797
798 if (error)
799 trace_xfs_reflink_end_cow_error(ip, error, _RET_IP_);
756 return error; 800 return error;
757} 801}
758 802
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 926ed314ffba..ac0fcdad0c4e 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -64,8 +64,12 @@ xfs_rtany_summary(
64 int log; /* loop counter, log2 of ext. size */ 64 int log; /* loop counter, log2 of ext. size */
65 xfs_suminfo_t sum; /* summary data */ 65 xfs_suminfo_t sum; /* summary data */
66 66
67 /* There are no extents at levels < m_rsum_cache[bbno]. */
68 if (mp->m_rsum_cache && low < mp->m_rsum_cache[bbno])
69 low = mp->m_rsum_cache[bbno];
70
67 /* 71 /*
68 * Loop over logs of extent sizes. Order is irrelevant. 72 * Loop over logs of extent sizes.
69 */ 73 */
70 for (log = low; log <= high; log++) { 74 for (log = low; log <= high; log++) {
71 /* 75 /*
@@ -80,13 +84,17 @@ xfs_rtany_summary(
80 */ 84 */
81 if (sum) { 85 if (sum) {
82 *stat = 1; 86 *stat = 1;
83 return 0; 87 goto out;
84 } 88 }
85 } 89 }
86 /* 90 /*
87 * Found nothing, return failure. 91 * Found nothing, return failure.
88 */ 92 */
89 *stat = 0; 93 *stat = 0;
94out:
95 /* There were no extents at levels < log. */
96 if (mp->m_rsum_cache && log > mp->m_rsum_cache[bbno])
97 mp->m_rsum_cache[bbno] = log;
90 return 0; 98 return 0;
91} 99}
92 100
@@ -853,6 +861,21 @@ out_trans_cancel:
853 return error; 861 return error;
854} 862}
855 863
864static void
865xfs_alloc_rsum_cache(
866 xfs_mount_t *mp, /* file system mount structure */
867 xfs_extlen_t rbmblocks) /* number of rt bitmap blocks */
868{
869 /*
870 * The rsum cache is initialized to all zeroes, which is trivially a
871 * lower bound on the minimum level with any free extents. We can
872 * continue without the cache if it couldn't be allocated.
873 */
874 mp->m_rsum_cache = kmem_zalloc_large(rbmblocks, KM_SLEEP);
875 if (!mp->m_rsum_cache)
876 xfs_warn(mp, "could not allocate realtime summary cache");
877}
878
856/* 879/*
857 * Visible (exported) functions. 880 * Visible (exported) functions.
858 */ 881 */
@@ -881,6 +904,7 @@ xfs_growfs_rt(
881 xfs_extlen_t rsumblocks; /* current number of rt summary blks */ 904 xfs_extlen_t rsumblocks; /* current number of rt summary blks */
882 xfs_sb_t *sbp; /* old superblock */ 905 xfs_sb_t *sbp; /* old superblock */
883 xfs_fsblock_t sumbno; /* summary block number */ 906 xfs_fsblock_t sumbno; /* summary block number */
907 uint8_t *rsum_cache; /* old summary cache */
884 908
885 sbp = &mp->m_sb; 909 sbp = &mp->m_sb;
886 /* 910 /*
@@ -937,6 +961,11 @@ xfs_growfs_rt(
937 error = xfs_growfs_rt_alloc(mp, rsumblocks, nrsumblocks, mp->m_rsumip); 961 error = xfs_growfs_rt_alloc(mp, rsumblocks, nrsumblocks, mp->m_rsumip);
938 if (error) 962 if (error)
939 return error; 963 return error;
964
965 rsum_cache = mp->m_rsum_cache;
966 if (nrbmblocks != sbp->sb_rbmblocks)
967 xfs_alloc_rsum_cache(mp, nrbmblocks);
968
940 /* 969 /*
941 * Allocate a new (fake) mount/sb. 970 * Allocate a new (fake) mount/sb.
942 */ 971 */
@@ -1062,6 +1091,20 @@ error_cancel:
1062 */ 1091 */
1063 kmem_free(nmp); 1092 kmem_free(nmp);
1064 1093
1094 /*
1095 * If we had to allocate a new rsum_cache, we either need to free the
1096 * old one (if we succeeded) or free the new one and restore the old one
1097 * (if there was an error).
1098 */
1099 if (rsum_cache != mp->m_rsum_cache) {
1100 if (error) {
1101 kmem_free(mp->m_rsum_cache);
1102 mp->m_rsum_cache = rsum_cache;
1103 } else {
1104 kmem_free(rsum_cache);
1105 }
1106 }
1107
1065 return error; 1108 return error;
1066} 1109}
1067 1110
@@ -1187,8 +1230,8 @@ xfs_rtmount_init(
1187} 1230}
1188 1231
1189/* 1232/*
1190 * Get the bitmap and summary inodes into the mount structure 1233 * Get the bitmap and summary inodes and the summary cache into the mount
1191 * at mount time. 1234 * structure at mount time.
1192 */ 1235 */
1193int /* error */ 1236int /* error */
1194xfs_rtmount_inodes( 1237xfs_rtmount_inodes(
@@ -1198,19 +1241,18 @@ xfs_rtmount_inodes(
1198 xfs_sb_t *sbp; 1241 xfs_sb_t *sbp;
1199 1242
1200 sbp = &mp->m_sb; 1243 sbp = &mp->m_sb;
1201 if (sbp->sb_rbmino == NULLFSINO)
1202 return 0;
1203 error = xfs_iget(mp, NULL, sbp->sb_rbmino, 0, 0, &mp->m_rbmip); 1244 error = xfs_iget(mp, NULL, sbp->sb_rbmino, 0, 0, &mp->m_rbmip);
1204 if (error) 1245 if (error)
1205 return error; 1246 return error;
1206 ASSERT(mp->m_rbmip != NULL); 1247 ASSERT(mp->m_rbmip != NULL);
1207 ASSERT(sbp->sb_rsumino != NULLFSINO); 1248
1208 error = xfs_iget(mp, NULL, sbp->sb_rsumino, 0, 0, &mp->m_rsumip); 1249 error = xfs_iget(mp, NULL, sbp->sb_rsumino, 0, 0, &mp->m_rsumip);
1209 if (error) { 1250 if (error) {
1210 xfs_irele(mp->m_rbmip); 1251 xfs_irele(mp->m_rbmip);
1211 return error; 1252 return error;
1212 } 1253 }
1213 ASSERT(mp->m_rsumip != NULL); 1254 ASSERT(mp->m_rsumip != NULL);
1255 xfs_alloc_rsum_cache(mp, sbp->sb_rbmblocks);
1214 return 0; 1256 return 0;
1215} 1257}
1216 1258
@@ -1218,6 +1260,7 @@ void
1218xfs_rtunmount_inodes( 1260xfs_rtunmount_inodes(
1219 struct xfs_mount *mp) 1261 struct xfs_mount *mp)
1220{ 1262{
1263 kmem_free(mp->m_rsum_cache);
1221 if (mp->m_rbmip) 1264 if (mp->m_rbmip)
1222 xfs_irele(mp->m_rbmip); 1265 xfs_irele(mp->m_rbmip);
1223 if (mp->m_rsumip) 1266 if (mp->m_rsumip)
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index d3e6cd063688..c9097cb0b955 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -38,6 +38,7 @@
38#include "xfs_refcount_item.h" 38#include "xfs_refcount_item.h"
39#include "xfs_bmap_item.h" 39#include "xfs_bmap_item.h"
40#include "xfs_reflink.h" 40#include "xfs_reflink.h"
41#include "xfs_defer.h"
41 42
42#include <linux/namei.h> 43#include <linux/namei.h>
43#include <linux/dax.h> 44#include <linux/dax.h>
@@ -607,7 +608,7 @@ xfs_set_inode_alloc(
607 } 608 }
608 609
609 /* Get the last possible inode in the filesystem */ 610 /* Get the last possible inode in the filesystem */
610 agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0); 611 agino = XFS_AGB_TO_AGINO(mp, sbp->sb_agblocks - 1);
611 ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino); 612 ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);
612 613
613 /* 614 /*
@@ -1149,7 +1150,7 @@ xfs_fs_statfs(
1149 statp->f_bfree = fdblocks - mp->m_alloc_set_aside; 1150 statp->f_bfree = fdblocks - mp->m_alloc_set_aside;
1150 statp->f_bavail = statp->f_bfree; 1151 statp->f_bavail = statp->f_bfree;
1151 1152
1152 fakeinos = statp->f_bfree << sbp->sb_inopblog; 1153 fakeinos = XFS_FSB_TO_INO(mp, statp->f_bfree);
1153 statp->f_files = min(icount + fakeinos, (uint64_t)XFS_MAXINUMBER); 1154 statp->f_files = min(icount + fakeinos, (uint64_t)XFS_MAXINUMBER);
1154 if (mp->m_maxicount) 1155 if (mp->m_maxicount)
1155 statp->f_files = min_t(typeof(statp->f_files), 1156 statp->f_files = min_t(typeof(statp->f_files),
@@ -2085,11 +2086,6 @@ init_xfs_fs(void)
2085 printk(KERN_INFO XFS_VERSION_STRING " with " 2086 printk(KERN_INFO XFS_VERSION_STRING " with "
2086 XFS_BUILD_OPTIONS " enabled\n"); 2087 XFS_BUILD_OPTIONS " enabled\n");
2087 2088
2088 xfs_extent_free_init_defer_op();
2089 xfs_rmap_update_init_defer_op();
2090 xfs_refcount_update_init_defer_op();
2091 xfs_bmap_update_init_defer_op();
2092
2093 xfs_dir_startup(); 2089 xfs_dir_startup();
2094 2090
2095 error = xfs_init_zones(); 2091 error = xfs_init_zones();
diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c
index a3e98c64b6e3..b2c1177c717f 100644
--- a/fs/xfs/xfs_symlink.c
+++ b/fs/xfs/xfs_symlink.c
@@ -192,6 +192,7 @@ xfs_symlink(
192 pathlen = strlen(target_path); 192 pathlen = strlen(target_path);
193 if (pathlen >= XFS_SYMLINK_MAXLEN) /* total string too long */ 193 if (pathlen >= XFS_SYMLINK_MAXLEN) /* total string too long */
194 return -ENAMETOOLONG; 194 return -ENAMETOOLONG;
195 ASSERT(pathlen > 0);
195 196
196 udqp = gdqp = NULL; 197 udqp = gdqp = NULL;
197 prid = xfs_get_initial_prid(dp); 198 prid = xfs_get_initial_prid(dp);
@@ -378,6 +379,12 @@ out_release_inode:
378 379
379/* 380/*
380 * Free a symlink that has blocks associated with it. 381 * Free a symlink that has blocks associated with it.
382 *
383 * Note: zero length symlinks are not allowed to exist. When we set the size to
384 * zero, also change it to a regular file so that it does not get written to
385 * disk as a zero length symlink. The inode is on the unlinked list already, so
386 * userspace cannot find this inode anymore, so this change is not user visible
387 * but allows us to catch corrupt zero-length symlinks in the verifiers.
381 */ 388 */
382STATIC int 389STATIC int
383xfs_inactive_symlink_rmt( 390xfs_inactive_symlink_rmt(
@@ -412,13 +419,14 @@ xfs_inactive_symlink_rmt(
412 xfs_trans_ijoin(tp, ip, 0); 419 xfs_trans_ijoin(tp, ip, 0);
413 420
414 /* 421 /*
415 * Lock the inode, fix the size, and join it to the transaction. 422 * Lock the inode, fix the size, turn it into a regular file and join it
416 * Hold it so in the normal path, we still have it locked for 423 * to the transaction. Hold it so in the normal path, we still have it
417 * the second transaction. In the error paths we need it 424 * locked for the second transaction. In the error paths we need it
418 * held so the cancel won't rele it, see below. 425 * held so the cancel won't rele it, see below.
419 */ 426 */
420 size = (int)ip->i_d.di_size; 427 size = (int)ip->i_d.di_size;
421 ip->i_d.di_size = 0; 428 ip->i_d.di_size = 0;
429 VFS_I(ip)->i_mode = (VFS_I(ip)->i_mode & ~S_IFMT) | S_IFREG;
422 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 430 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
423 /* 431 /*
424 * Find the block(s) so we can inval and unmap them. 432 * Find the block(s) so we can inval and unmap them.
@@ -494,17 +502,10 @@ xfs_inactive_symlink(
494 return -EIO; 502 return -EIO;
495 503
496 xfs_ilock(ip, XFS_ILOCK_EXCL); 504 xfs_ilock(ip, XFS_ILOCK_EXCL);
497
498 /*
499 * Zero length symlinks _can_ exist.
500 */
501 pathlen = (int)ip->i_d.di_size; 505 pathlen = (int)ip->i_d.di_size;
502 if (!pathlen) { 506 ASSERT(pathlen);
503 xfs_iunlock(ip, XFS_ILOCK_EXCL);
504 return 0;
505 }
506 507
507 if (pathlen < 0 || pathlen > XFS_SYMLINK_MAXLEN) { 508 if (pathlen <= 0 || pathlen > XFS_SYMLINK_MAXLEN) {
508 xfs_alert(mp, "%s: inode (0x%llx) bad symlink length (%d)", 509 xfs_alert(mp, "%s: inode (0x%llx) bad symlink length (%d)",
509 __func__, (unsigned long long)ip->i_ino, pathlen); 510 __func__, (unsigned long long)ip->i_ino, pathlen);
510 xfs_iunlock(ip, XFS_ILOCK_EXCL); 511 xfs_iunlock(ip, XFS_ILOCK_EXCL);
@@ -512,12 +513,12 @@ xfs_inactive_symlink(
512 return -EFSCORRUPTED; 513 return -EFSCORRUPTED;
513 } 514 }
514 515
516 /*
517 * Inline fork state gets removed by xfs_difree() so we have nothing to
518 * do here in that case.
519 */
515 if (ip->i_df.if_flags & XFS_IFINLINE) { 520 if (ip->i_df.if_flags & XFS_IFINLINE) {
516 if (ip->i_df.if_bytes > 0)
517 xfs_idata_realloc(ip, -(ip->i_df.if_bytes),
518 XFS_DATA_FORK);
519 xfs_iunlock(ip, XFS_ILOCK_EXCL); 521 xfs_iunlock(ip, XFS_ILOCK_EXCL);
520 ASSERT(ip->i_df.if_bytes == 0);
521 return 0; 522 return 0;
522 } 523 }
523 524
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 8a6532aae779..6fcc893dfc91 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -640,6 +640,16 @@ DEFINE_INODE_EVENT(xfs_inode_set_cowblocks_tag);
640DEFINE_INODE_EVENT(xfs_inode_clear_cowblocks_tag); 640DEFINE_INODE_EVENT(xfs_inode_clear_cowblocks_tag);
641DEFINE_INODE_EVENT(xfs_inode_free_cowblocks_invalid); 641DEFINE_INODE_EVENT(xfs_inode_free_cowblocks_invalid);
642 642
643/*
644 * ftrace's __print_symbolic requires that all enum values be wrapped in the
645 * TRACE_DEFINE_ENUM macro so that the enum value can be encoded in the ftrace
646 * ring buffer. Somehow this was only worth mentioning in the ftrace sample
647 * code.
648 */
649TRACE_DEFINE_ENUM(PE_SIZE_PTE);
650TRACE_DEFINE_ENUM(PE_SIZE_PMD);
651TRACE_DEFINE_ENUM(PE_SIZE_PUD);
652
643TRACE_EVENT(xfs_filemap_fault, 653TRACE_EVENT(xfs_filemap_fault,
644 TP_PROTO(struct xfs_inode *ip, enum page_entry_size pe_size, 654 TP_PROTO(struct xfs_inode *ip, enum page_entry_size pe_size,
645 bool write_fault), 655 bool write_fault),
@@ -1208,6 +1218,12 @@ DEFINE_EVENT(xfs_readpage_class, name, \
1208DEFINE_READPAGE_EVENT(xfs_vm_readpage); 1218DEFINE_READPAGE_EVENT(xfs_vm_readpage);
1209DEFINE_READPAGE_EVENT(xfs_vm_readpages); 1219DEFINE_READPAGE_EVENT(xfs_vm_readpages);
1210 1220
1221TRACE_DEFINE_ENUM(XFS_IO_HOLE);
1222TRACE_DEFINE_ENUM(XFS_IO_DELALLOC);
1223TRACE_DEFINE_ENUM(XFS_IO_UNWRITTEN);
1224TRACE_DEFINE_ENUM(XFS_IO_OVERWRITE);
1225TRACE_DEFINE_ENUM(XFS_IO_COW);
1226
1211DECLARE_EVENT_CLASS(xfs_imap_class, 1227DECLARE_EVENT_CLASS(xfs_imap_class,
1212 TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count, 1228 TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count,
1213 int type, struct xfs_bmbt_irec *irec), 1229 int type, struct xfs_bmbt_irec *irec),
@@ -1885,11 +1901,11 @@ TRACE_EVENT(xfs_dir2_leafn_moveents,
1885 { 0, "target" }, \ 1901 { 0, "target" }, \
1886 { 1, "temp" } 1902 { 1, "temp" }
1887 1903
1888#define XFS_INODE_FORMAT_STR \ 1904TRACE_DEFINE_ENUM(XFS_DINODE_FMT_DEV);
1889 { 0, "invalid" }, \ 1905TRACE_DEFINE_ENUM(XFS_DINODE_FMT_LOCAL);
1890 { 1, "local" }, \ 1906TRACE_DEFINE_ENUM(XFS_DINODE_FMT_EXTENTS);
1891 { 2, "extent" }, \ 1907TRACE_DEFINE_ENUM(XFS_DINODE_FMT_BTREE);
1892 { 3, "btree" } 1908TRACE_DEFINE_ENUM(XFS_DINODE_FMT_UUID);
1893 1909
1894DECLARE_EVENT_CLASS(xfs_swap_extent_class, 1910DECLARE_EVENT_CLASS(xfs_swap_extent_class,
1895 TP_PROTO(struct xfs_inode *ip, int which), 1911 TP_PROTO(struct xfs_inode *ip, int which),
@@ -2178,6 +2194,14 @@ DEFINE_DISCARD_EVENT(xfs_discard_exclude);
2178DEFINE_DISCARD_EVENT(xfs_discard_busy); 2194DEFINE_DISCARD_EVENT(xfs_discard_busy);
2179 2195
2180/* btree cursor events */ 2196/* btree cursor events */
2197TRACE_DEFINE_ENUM(XFS_BTNUM_BNOi);
2198TRACE_DEFINE_ENUM(XFS_BTNUM_CNTi);
2199TRACE_DEFINE_ENUM(XFS_BTNUM_BMAPi);
2200TRACE_DEFINE_ENUM(XFS_BTNUM_INOi);
2201TRACE_DEFINE_ENUM(XFS_BTNUM_FINOi);
2202TRACE_DEFINE_ENUM(XFS_BTNUM_RMAPi);
2203TRACE_DEFINE_ENUM(XFS_BTNUM_REFCi);
2204
2181DECLARE_EVENT_CLASS(xfs_btree_cur_class, 2205DECLARE_EVENT_CLASS(xfs_btree_cur_class,
2182 TP_PROTO(struct xfs_btree_cur *cur, int level, struct xfs_buf *bp), 2206 TP_PROTO(struct xfs_btree_cur *cur, int level, struct xfs_buf *bp),
2183 TP_ARGS(cur, level, bp), 2207 TP_ARGS(cur, level, bp),
@@ -2197,9 +2221,9 @@ DECLARE_EVENT_CLASS(xfs_btree_cur_class,
2197 __entry->ptr = cur->bc_ptrs[level]; 2221 __entry->ptr = cur->bc_ptrs[level];
2198 __entry->daddr = bp ? bp->b_bn : -1; 2222 __entry->daddr = bp ? bp->b_bn : -1;
2199 ), 2223 ),
2200 TP_printk("dev %d:%d btnum %d level %d/%d ptr %d daddr 0x%llx", 2224 TP_printk("dev %d:%d btree %s level %d/%d ptr %d daddr 0x%llx",
2201 MAJOR(__entry->dev), MINOR(__entry->dev), 2225 MAJOR(__entry->dev), MINOR(__entry->dev),
2202 __entry->btnum, 2226 __print_symbolic(__entry->btnum, XFS_BTNUM_STRINGS),
2203 __entry->level, 2227 __entry->level,
2204 __entry->nlevels, 2228 __entry->nlevels,
2205 __entry->ptr, 2229 __entry->ptr,
@@ -2276,7 +2300,7 @@ DECLARE_EVENT_CLASS(xfs_defer_pending_class,
2276 ), 2300 ),
2277 TP_fast_assign( 2301 TP_fast_assign(
2278 __entry->dev = mp ? mp->m_super->s_dev : 0; 2302 __entry->dev = mp ? mp->m_super->s_dev : 0;
2279 __entry->type = dfp->dfp_type->type; 2303 __entry->type = dfp->dfp_type;
2280 __entry->intent = dfp->dfp_intent; 2304 __entry->intent = dfp->dfp_intent;
2281 __entry->committed = dfp->dfp_done != NULL; 2305 __entry->committed = dfp->dfp_done != NULL;
2282 __entry->nr = dfp->dfp_count; 2306 __entry->nr = dfp->dfp_count;
@@ -2405,7 +2429,7 @@ DEFINE_BMAP_FREE_DEFERRED_EVENT(xfs_agfl_free_deferred);
2405DECLARE_EVENT_CLASS(xfs_rmap_class, 2429DECLARE_EVENT_CLASS(xfs_rmap_class,
2406 TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, 2430 TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno,
2407 xfs_agblock_t agbno, xfs_extlen_t len, bool unwritten, 2431 xfs_agblock_t agbno, xfs_extlen_t len, bool unwritten,
2408 struct xfs_owner_info *oinfo), 2432 const struct xfs_owner_info *oinfo),
2409 TP_ARGS(mp, agno, agbno, len, unwritten, oinfo), 2433 TP_ARGS(mp, agno, agbno, len, unwritten, oinfo),
2410 TP_STRUCT__entry( 2434 TP_STRUCT__entry(
2411 __field(dev_t, dev) 2435 __field(dev_t, dev)
@@ -2440,7 +2464,7 @@ DECLARE_EVENT_CLASS(xfs_rmap_class,
2440DEFINE_EVENT(xfs_rmap_class, name, \ 2464DEFINE_EVENT(xfs_rmap_class, name, \
2441 TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, \ 2465 TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, \
2442 xfs_agblock_t agbno, xfs_extlen_t len, bool unwritten, \ 2466 xfs_agblock_t agbno, xfs_extlen_t len, bool unwritten, \
2443 struct xfs_owner_info *oinfo), \ 2467 const struct xfs_owner_info *oinfo), \
2444 TP_ARGS(mp, agno, agbno, len, unwritten, oinfo)) 2468 TP_ARGS(mp, agno, agbno, len, unwritten, oinfo))
2445 2469
2446/* simple AG-based error/%ip tracepoint class */ 2470/* simple AG-based error/%ip tracepoint class */
@@ -2610,10 +2634,9 @@ DEFINE_AG_ERROR_EVENT(xfs_ag_resv_init_error);
2610#define DEFINE_AG_EXTENT_EVENT(name) DEFINE_DISCARD_EVENT(name) 2634#define DEFINE_AG_EXTENT_EVENT(name) DEFINE_DISCARD_EVENT(name)
2611 2635
2612/* ag btree lookup tracepoint class */ 2636/* ag btree lookup tracepoint class */
2613#define XFS_AG_BTREE_CMP_FORMAT_STR \ 2637TRACE_DEFINE_ENUM(XFS_LOOKUP_EQi);
2614 { XFS_LOOKUP_EQ, "eq" }, \ 2638TRACE_DEFINE_ENUM(XFS_LOOKUP_LEi);
2615 { XFS_LOOKUP_LE, "le" }, \ 2639TRACE_DEFINE_ENUM(XFS_LOOKUP_GEi);
2616 { XFS_LOOKUP_GE, "ge" }
2617DECLARE_EVENT_CLASS(xfs_ag_btree_lookup_class, 2640DECLARE_EVENT_CLASS(xfs_ag_btree_lookup_class,
2618 TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, 2641 TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno,
2619 xfs_agblock_t agbno, xfs_lookup_t dir), 2642 xfs_agblock_t agbno, xfs_lookup_t dir),
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index a0c5dbda18aa..c6e1c5704a8c 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -223,13 +223,13 @@ void xfs_trans_dirty_buf(struct xfs_trans *, struct xfs_buf *);
223bool xfs_trans_buf_is_dirty(struct xfs_buf *bp); 223bool xfs_trans_buf_is_dirty(struct xfs_buf *bp);
224void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint); 224void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint);
225 225
226void xfs_extent_free_init_defer_op(void);
227struct xfs_efd_log_item *xfs_trans_get_efd(struct xfs_trans *, 226struct xfs_efd_log_item *xfs_trans_get_efd(struct xfs_trans *,
228 struct xfs_efi_log_item *, 227 struct xfs_efi_log_item *,
229 uint); 228 uint);
230int xfs_trans_free_extent(struct xfs_trans *, 229int xfs_trans_free_extent(struct xfs_trans *,
231 struct xfs_efd_log_item *, xfs_fsblock_t, 230 struct xfs_efd_log_item *, xfs_fsblock_t,
232 xfs_extlen_t, struct xfs_owner_info *, 231 xfs_extlen_t,
232 const struct xfs_owner_info *,
233 bool); 233 bool);
234int xfs_trans_commit(struct xfs_trans *); 234int xfs_trans_commit(struct xfs_trans *);
235int xfs_trans_roll(struct xfs_trans **); 235int xfs_trans_roll(struct xfs_trans **);
@@ -248,7 +248,6 @@ extern kmem_zone_t *xfs_trans_zone;
248/* rmap updates */ 248/* rmap updates */
249enum xfs_rmap_intent_type; 249enum xfs_rmap_intent_type;
250 250
251void xfs_rmap_update_init_defer_op(void);
252struct xfs_rud_log_item *xfs_trans_get_rud(struct xfs_trans *tp, 251struct xfs_rud_log_item *xfs_trans_get_rud(struct xfs_trans *tp,
253 struct xfs_rui_log_item *ruip); 252 struct xfs_rui_log_item *ruip);
254int xfs_trans_log_finish_rmap_update(struct xfs_trans *tp, 253int xfs_trans_log_finish_rmap_update(struct xfs_trans *tp,
@@ -260,7 +259,6 @@ int xfs_trans_log_finish_rmap_update(struct xfs_trans *tp,
260/* refcount updates */ 259/* refcount updates */
261enum xfs_refcount_intent_type; 260enum xfs_refcount_intent_type;
262 261
263void xfs_refcount_update_init_defer_op(void);
264struct xfs_cud_log_item *xfs_trans_get_cud(struct xfs_trans *tp, 262struct xfs_cud_log_item *xfs_trans_get_cud(struct xfs_trans *tp,
265 struct xfs_cui_log_item *cuip); 263 struct xfs_cui_log_item *cuip);
266int xfs_trans_log_finish_refcount_update(struct xfs_trans *tp, 264int xfs_trans_log_finish_refcount_update(struct xfs_trans *tp,
@@ -272,7 +270,6 @@ int xfs_trans_log_finish_refcount_update(struct xfs_trans *tp,
272/* mapping updates */ 270/* mapping updates */
273enum xfs_bmap_intent_type; 271enum xfs_bmap_intent_type;
274 272
275void xfs_bmap_update_init_defer_op(void);
276struct xfs_bud_log_item *xfs_trans_get_bud(struct xfs_trans *tp, 273struct xfs_bud_log_item *xfs_trans_get_bud(struct xfs_trans *tp,
277 struct xfs_bui_log_item *buip); 274 struct xfs_bui_log_item *buip);
278int xfs_trans_log_finish_bmap_update(struct xfs_trans *tp, 275int xfs_trans_log_finish_bmap_update(struct xfs_trans *tp,
diff --git a/fs/xfs/xfs_trans_bmap.c b/fs/xfs/xfs_trans_bmap.c
index 741c558b2179..11cff449d055 100644
--- a/fs/xfs/xfs_trans_bmap.c
+++ b/fs/xfs/xfs_trans_bmap.c
@@ -17,6 +17,7 @@
17#include "xfs_alloc.h" 17#include "xfs_alloc.h"
18#include "xfs_bmap.h" 18#include "xfs_bmap.h"
19#include "xfs_inode.h" 19#include "xfs_inode.h"
20#include "xfs_defer.h"
20 21
21/* 22/*
22 * This routine is called to allocate a "bmap update done" 23 * This routine is called to allocate a "bmap update done"
@@ -220,8 +221,7 @@ xfs_bmap_update_cancel_item(
220 kmem_free(bmap); 221 kmem_free(bmap);
221} 222}
222 223
223static const struct xfs_defer_op_type xfs_bmap_update_defer_type = { 224const struct xfs_defer_op_type xfs_bmap_update_defer_type = {
224 .type = XFS_DEFER_OPS_TYPE_BMAP,
225 .max_items = XFS_BUI_MAX_FAST_EXTENTS, 225 .max_items = XFS_BUI_MAX_FAST_EXTENTS,
226 .diff_items = xfs_bmap_update_diff_items, 226 .diff_items = xfs_bmap_update_diff_items,
227 .create_intent = xfs_bmap_update_create_intent, 227 .create_intent = xfs_bmap_update_create_intent,
@@ -231,10 +231,3 @@ static const struct xfs_defer_op_type xfs_bmap_update_defer_type = {
231 .finish_item = xfs_bmap_update_finish_item, 231 .finish_item = xfs_bmap_update_finish_item,
232 .cancel_item = xfs_bmap_update_cancel_item, 232 .cancel_item = xfs_bmap_update_cancel_item,
233}; 233};
234
235/* Register the deferred op type. */
236void
237xfs_bmap_update_init_defer_op(void)
238{
239 xfs_defer_init_op_type(&xfs_bmap_update_defer_type);
240}
diff --git a/fs/xfs/xfs_trans_extfree.c b/fs/xfs/xfs_trans_extfree.c
index 855c0b651fd4..0710434eb240 100644
--- a/fs/xfs/xfs_trans_extfree.c
+++ b/fs/xfs/xfs_trans_extfree.c
@@ -18,6 +18,7 @@
18#include "xfs_alloc.h" 18#include "xfs_alloc.h"
19#include "xfs_bmap.h" 19#include "xfs_bmap.h"
20#include "xfs_trace.h" 20#include "xfs_trace.h"
21#include "xfs_defer.h"
21 22
22/* 23/*
23 * This routine is called to allocate an "extent free done" 24 * This routine is called to allocate an "extent free done"
@@ -52,19 +53,20 @@ xfs_trans_get_efd(struct xfs_trans *tp,
52 */ 53 */
53int 54int
54xfs_trans_free_extent( 55xfs_trans_free_extent(
55 struct xfs_trans *tp, 56 struct xfs_trans *tp,
56 struct xfs_efd_log_item *efdp, 57 struct xfs_efd_log_item *efdp,
57 xfs_fsblock_t start_block, 58 xfs_fsblock_t start_block,
58 xfs_extlen_t ext_len, 59 xfs_extlen_t ext_len,
59 struct xfs_owner_info *oinfo, 60 const struct xfs_owner_info *oinfo,
60 bool skip_discard) 61 bool skip_discard)
61{ 62{
62 struct xfs_mount *mp = tp->t_mountp; 63 struct xfs_mount *mp = tp->t_mountp;
63 uint next_extent; 64 struct xfs_extent *extp;
64 xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, start_block); 65 uint next_extent;
65 xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, start_block); 66 xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, start_block);
66 struct xfs_extent *extp; 67 xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp,
67 int error; 68 start_block);
69 int error;
68 70
69 trace_xfs_bmap_free_deferred(tp->t_mountp, agno, 0, agbno, ext_len); 71 trace_xfs_bmap_free_deferred(tp->t_mountp, agno, 0, agbno, ext_len);
70 72
@@ -206,8 +208,7 @@ xfs_extent_free_cancel_item(
206 kmem_free(free); 208 kmem_free(free);
207} 209}
208 210
209static const struct xfs_defer_op_type xfs_extent_free_defer_type = { 211const struct xfs_defer_op_type xfs_extent_free_defer_type = {
210 .type = XFS_DEFER_OPS_TYPE_FREE,
211 .max_items = XFS_EFI_MAX_FAST_EXTENTS, 212 .max_items = XFS_EFI_MAX_FAST_EXTENTS,
212 .diff_items = xfs_extent_free_diff_items, 213 .diff_items = xfs_extent_free_diff_items,
213 .create_intent = xfs_extent_free_create_intent, 214 .create_intent = xfs_extent_free_create_intent,
@@ -274,8 +275,7 @@ xfs_agfl_free_finish_item(
274 275
275 276
276/* sub-type with special handling for AGFL deferred frees */ 277/* sub-type with special handling for AGFL deferred frees */
277static const struct xfs_defer_op_type xfs_agfl_free_defer_type = { 278const struct xfs_defer_op_type xfs_agfl_free_defer_type = {
278 .type = XFS_DEFER_OPS_TYPE_AGFL_FREE,
279 .max_items = XFS_EFI_MAX_FAST_EXTENTS, 279 .max_items = XFS_EFI_MAX_FAST_EXTENTS,
280 .diff_items = xfs_extent_free_diff_items, 280 .diff_items = xfs_extent_free_diff_items,
281 .create_intent = xfs_extent_free_create_intent, 281 .create_intent = xfs_extent_free_create_intent,
@@ -285,11 +285,3 @@ static const struct xfs_defer_op_type xfs_agfl_free_defer_type = {
285 .finish_item = xfs_agfl_free_finish_item, 285 .finish_item = xfs_agfl_free_finish_item,
286 .cancel_item = xfs_extent_free_cancel_item, 286 .cancel_item = xfs_extent_free_cancel_item,
287}; 287};
288
289/* Register the deferred op type. */
290void
291xfs_extent_free_init_defer_op(void)
292{
293 xfs_defer_init_op_type(&xfs_extent_free_defer_type);
294 xfs_defer_init_op_type(&xfs_agfl_free_defer_type);
295}
diff --git a/fs/xfs/xfs_trans_refcount.c b/fs/xfs/xfs_trans_refcount.c
index 523c55663954..6c947ff4faf6 100644
--- a/fs/xfs/xfs_trans_refcount.c
+++ b/fs/xfs/xfs_trans_refcount.c
@@ -16,6 +16,7 @@
16#include "xfs_refcount_item.h" 16#include "xfs_refcount_item.h"
17#include "xfs_alloc.h" 17#include "xfs_alloc.h"
18#include "xfs_refcount.h" 18#include "xfs_refcount.h"
19#include "xfs_defer.h"
19 20
20/* 21/*
21 * This routine is called to allocate a "refcount update done" 22 * This routine is called to allocate a "refcount update done"
@@ -227,8 +228,7 @@ xfs_refcount_update_cancel_item(
227 kmem_free(refc); 228 kmem_free(refc);
228} 229}
229 230
230static const struct xfs_defer_op_type xfs_refcount_update_defer_type = { 231const struct xfs_defer_op_type xfs_refcount_update_defer_type = {
231 .type = XFS_DEFER_OPS_TYPE_REFCOUNT,
232 .max_items = XFS_CUI_MAX_FAST_EXTENTS, 232 .max_items = XFS_CUI_MAX_FAST_EXTENTS,
233 .diff_items = xfs_refcount_update_diff_items, 233 .diff_items = xfs_refcount_update_diff_items,
234 .create_intent = xfs_refcount_update_create_intent, 234 .create_intent = xfs_refcount_update_create_intent,
@@ -239,10 +239,3 @@ static const struct xfs_defer_op_type xfs_refcount_update_defer_type = {
239 .finish_cleanup = xfs_refcount_update_finish_cleanup, 239 .finish_cleanup = xfs_refcount_update_finish_cleanup,
240 .cancel_item = xfs_refcount_update_cancel_item, 240 .cancel_item = xfs_refcount_update_cancel_item,
241}; 241};
242
243/* Register the deferred op type. */
244void
245xfs_refcount_update_init_defer_op(void)
246{
247 xfs_defer_init_op_type(&xfs_refcount_update_defer_type);
248}
diff --git a/fs/xfs/xfs_trans_rmap.c b/fs/xfs/xfs_trans_rmap.c
index 05b00e40251f..a42890931ecd 100644
--- a/fs/xfs/xfs_trans_rmap.c
+++ b/fs/xfs/xfs_trans_rmap.c
@@ -16,6 +16,7 @@
16#include "xfs_rmap_item.h" 16#include "xfs_rmap_item.h"
17#include "xfs_alloc.h" 17#include "xfs_alloc.h"
18#include "xfs_rmap.h" 18#include "xfs_rmap.h"
19#include "xfs_defer.h"
19 20
20/* Set the map extent flags for this reverse mapping. */ 21/* Set the map extent flags for this reverse mapping. */
21static void 22static void
@@ -244,8 +245,7 @@ xfs_rmap_update_cancel_item(
244 kmem_free(rmap); 245 kmem_free(rmap);
245} 246}
246 247
247static const struct xfs_defer_op_type xfs_rmap_update_defer_type = { 248const struct xfs_defer_op_type xfs_rmap_update_defer_type = {
248 .type = XFS_DEFER_OPS_TYPE_RMAP,
249 .max_items = XFS_RUI_MAX_FAST_EXTENTS, 249 .max_items = XFS_RUI_MAX_FAST_EXTENTS,
250 .diff_items = xfs_rmap_update_diff_items, 250 .diff_items = xfs_rmap_update_diff_items,
251 .create_intent = xfs_rmap_update_create_intent, 251 .create_intent = xfs_rmap_update_create_intent,
@@ -256,10 +256,3 @@ static const struct xfs_defer_op_type xfs_rmap_update_defer_type = {
256 .finish_cleanup = xfs_rmap_update_finish_cleanup, 256 .finish_cleanup = xfs_rmap_update_finish_cleanup,
257 .cancel_item = xfs_rmap_update_cancel_item, 257 .cancel_item = xfs_rmap_update_cancel_item,
258}; 258};
259
260/* Register the deferred op type. */
261void
262xfs_rmap_update_init_defer_op(void)
263{
264 xfs_defer_init_op_type(&xfs_rmap_update_defer_type);
265}