diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-27 20:04:23 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-27 20:04:23 -0500 |
commit | 47a43f2f0ce24bb75e3e4500118000585a3b496a (patch) | |
tree | 4decf322cd12b49c3bc82d7578617bb27db0541a /fs | |
parent | e01799ac56306ab211f2edf1221a82dc57eab8f5 (diff) | |
parent | 65eed012d1f2d0f0bf0ffc036826d58147de77b8 (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')
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 | */ |
1695 | STATIC int | 1693 | STATIC int |
1696 | xfs_free_ag_extent( | 1694 | xfs_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 | */ |
3011 | int /* error */ | 3010 | int |
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); | |||
186 | int xfs_bmap_set_attrforkoff(struct xfs_inode *ip, int size, int *version); | 186 | int xfs_bmap_set_attrforkoff(struct xfs_inode *ip, int size, int *version); |
187 | void xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork); | 187 | void xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork); |
188 | void __xfs_bmap_add_free(struct xfs_trans *tp, xfs_fsblock_t bno, | 188 | void __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); |
191 | void xfs_bmap_compute_maxlevels(struct xfs_mount *mp, int whichfork); | 191 | void xfs_bmap_compute_maxlevels(struct xfs_mount *mp, int whichfork); |
192 | int xfs_bmap_first_unused(struct xfs_trans *tp, struct xfs_inode *ip, | 192 | int 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 | ||
175 | static const struct xfs_defer_op_type *defer_op_types[XFS_DEFER_OPS_TYPE_MAX]; | 175 | static 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 | ||
432 | out: | 441 | out: |
@@ -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. */ | ||
521 | void | ||
522 | xfs_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 @@ | |||
9 | struct xfs_defer_op_type; | 9 | struct 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 | */ | ||
16 | struct 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 | */ |
28 | enum xfs_defer_ops_type { | 14 | enum 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 | */ | ||
28 | struct 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 | |||
37 | void xfs_defer_add(struct xfs_trans *tp, enum xfs_defer_ops_type type, | 37 | void xfs_defer_add(struct xfs_trans *tp, enum xfs_defer_ops_type type, |
38 | struct list_head *h); | 38 | struct list_head *h); |
39 | int xfs_defer_finish_noroll(struct xfs_trans **tp); | 39 | int 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. */ |
45 | struct xfs_defer_op_type { | 45 | struct 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 | ||
59 | void xfs_defer_init_op_type(const struct xfs_defer_op_type *type); | 58 | extern const struct xfs_defer_op_type xfs_bmap_update_defer_type; |
59 | extern const struct xfs_defer_op_type xfs_refcount_update_defer_type; | ||
60 | extern const struct xfs_defer_op_type xfs_rmap_update_defer_type; | ||
61 | extern const struct xfs_defer_op_type xfs_extent_free_defer_type; | ||
62 | extern 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 | */ |
920 | typedef enum xfs_dinode_fmt { | 923 | typedef 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( | |||
2388 | out_map: | 2381 | out_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 | ||
147 | STATIC int | 144 | STATIC 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 | */ |
459 | STATIC int | 459 | STATIC int |
460 | xfs_rmap_unmap( | 460 | xfs_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 | */ |
654 | int | 654 | int |
655 | xfs_rmap_free( | 655 | xfs_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 | */ |
711 | STATIC int | 711 | STATIC int |
712 | xfs_rmap_map( | 712 | xfs_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 | */ |
891 | int | 891 | int |
892 | xfs_rmap_alloc( | 892 | xfs_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 | */ |
930 | STATIC int | 930 | STATIC int |
931 | xfs_rmap_convert( | 931 | xfs_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 | */ |
1355 | STATIC int | 1355 | STATIC int |
1356 | xfs_rmap_convert_shared( | 1356 | xfs_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 | */ |
1744 | STATIC int | 1744 | STATIC int |
1745 | xfs_rmap_unmap_shared( | 1745 | xfs_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 | */ |
1906 | STATIC int | 1906 | STATIC int |
1907 | xfs_rmap_map_shared( | 1907 | xfs_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 | */ |
2460 | int | 2460 | int |
2461 | xfs_rmap_record_exists( | 2461 | xfs_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 | |||
2554 | const struct xfs_owner_info XFS_RMAP_OINFO_SKIP_UPDATE = { | ||
2555 | .oi_owner = XFS_RMAP_OWN_NULL, | ||
2556 | }; | ||
2557 | const struct xfs_owner_info XFS_RMAP_OINFO_ANY_OWNER = { | ||
2558 | .oi_owner = XFS_RMAP_OWN_UNKNOWN, | ||
2559 | }; | ||
2560 | const struct xfs_owner_info XFS_RMAP_OINFO_FS = { | ||
2561 | .oi_owner = XFS_RMAP_OWN_FS, | ||
2562 | }; | ||
2563 | const struct xfs_owner_info XFS_RMAP_OINFO_LOG = { | ||
2564 | .oi_owner = XFS_RMAP_OWN_LOG, | ||
2565 | }; | ||
2566 | const struct xfs_owner_info XFS_RMAP_OINFO_AG = { | ||
2567 | .oi_owner = XFS_RMAP_OWN_AG, | ||
2568 | }; | ||
2569 | const struct xfs_owner_info XFS_RMAP_OINFO_INOBT = { | ||
2570 | .oi_owner = XFS_RMAP_OWN_INOBT, | ||
2571 | }; | ||
2572 | const struct xfs_owner_info XFS_RMAP_OINFO_INODES = { | ||
2573 | .oi_owner = XFS_RMAP_OWN_INODES, | ||
2574 | }; | ||
2575 | const struct xfs_owner_info XFS_RMAP_OINFO_REFC = { | ||
2576 | .oi_owner = XFS_RMAP_OWN_REFC, | ||
2577 | }; | ||
2578 | const 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 | ||
9 | static inline void | 9 | static inline void |
10 | xfs_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 | |||
19 | static inline void | ||
20 | xfs_rmap_ino_bmbt_owner( | 10 | xfs_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 | ||
46 | static inline void | ||
47 | xfs_rmap_skip_owner_update( | ||
48 | struct xfs_owner_info *oi) | ||
49 | { | ||
50 | xfs_rmap_ag_owner(oi, XFS_RMAP_OWN_NULL); | ||
51 | } | ||
52 | |||
53 | static inline bool | 36 | static inline bool |
54 | xfs_rmap_should_skip_owner_update( | 37 | xfs_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 | ||
60 | static inline void | ||
61 | xfs_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 | ||
69 | struct xfs_buf; | 45 | struct xfs_buf; |
@@ -103,12 +79,12 @@ xfs_rmap_irec_offset_unpack( | |||
103 | 79 | ||
104 | static inline void | 80 | static inline void |
105 | xfs_owner_info_unpack( | 81 | xfs_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 | ||
138 | int xfs_rmap_alloc(struct xfs_trans *tp, struct xfs_buf *agbp, | 114 | int 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); |
141 | int xfs_rmap_free(struct xfs_trans *tp, struct xfs_buf *agbp, | 117 | int 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 | ||
145 | int xfs_rmap_lookup_le(struct xfs_btree_cur *cur, xfs_agblock_t bno, | 121 | int 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, | |||
218 | int xfs_rmap_has_record(struct xfs_btree_cur *cur, xfs_agblock_t bno, | 194 | int 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); |
220 | int xfs_rmap_record_exists(struct xfs_btree_cur *cur, xfs_agblock_t bno, | 196 | int 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); |
223 | int xfs_rmap_has_other_keys(struct xfs_btree_cur *cur, xfs_agblock_t bno, | 199 | int 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); |
226 | int xfs_rmap_map_raw(struct xfs_btree_cur *cur, struct xfs_rmap_irec *rmap); | 202 | int xfs_rmap_map_raw(struct xfs_btree_cur *cur, struct xfs_rmap_irec *rmap); |
227 | 203 | ||
204 | extern const struct xfs_owner_info XFS_RMAP_OINFO_SKIP_UPDATE; | ||
205 | extern const struct xfs_owner_info XFS_RMAP_OINFO_ANY_OWNER; | ||
206 | extern const struct xfs_owner_info XFS_RMAP_OINFO_FS; | ||
207 | extern const struct xfs_owner_info XFS_RMAP_OINFO_LOG; | ||
208 | extern const struct xfs_owner_info XFS_RMAP_OINFO_AG; | ||
209 | extern const struct xfs_owner_info XFS_RMAP_OINFO_INOBT; | ||
210 | extern const struct xfs_owner_info XFS_RMAP_OINFO_INODES; | ||
211 | extern const struct xfs_owner_info XFS_RMAP_OINFO_REFC; | ||
212 | extern 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 | */ | ||
203 | xfs_failaddr_t | 206 | xfs_failaddr_t |
204 | xfs_symlink_shortform_verify( | 207 | xfs_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 | */ | ||
103 | typedef enum { | 107 | typedef 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 | */ | ||
107 | typedef enum { | 120 | typedef 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 | |||
112 | struct xfs_name { | 134 | struct 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 | |||
484 | xchk_agf_xref( | 482 | xchk_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 | ||
600 | struct xchk_agfl_info { | 596 | struct 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 { | |||
609 | STATIC void | 604 | STATIC void |
610 | xchk_agfl_block_xref( | 605 | xchk_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 | |||
662 | xchk_agfl_xref( | 656 | xchk_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 | |||
791 | xchk_agi_xref( | 782 | xchk_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 | |||
646 | xrep_agfl( | 646 | xrep_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); |
713 | err: | 712 | err: |
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 | ||
136 | int | 134 | int |
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 | */ |
584 | int | 584 | int |
585 | xchk_btree( | 585 | xchk_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 | ||
32 | struct xchk_btree { | 32 | struct 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 | }; |
47 | int xchk_btree(struct xfs_scrub *sc, struct xfs_btree_cur *cur, | 47 | int 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 | ||
315 | struct xchk_rmap_ownedby_info { | 315 | struct 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 | ||
320 | STATIC int | 320 | STATIC int |
@@ -347,15 +347,15 @@ int | |||
347 | xchk_count_rmap_ownedby_ag( | 347 | xchk_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, | |||
116 | void xchk_ag_btcur_free(struct xchk_ag *sa); | 116 | void xchk_ag_btcur_free(struct xchk_ag *sa); |
117 | int xchk_ag_btcur_init(struct xfs_scrub *sc, struct xchk_ag *sa); | 117 | int xchk_ag_btcur_init(struct xfs_scrub *sc, struct xchk_ag *sa); |
118 | int xchk_count_rmap_ownedby_ag(struct xfs_scrub *sc, struct xfs_btree_cur *cur, | 118 | int 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 | ||
121 | int xchk_setup_ag_btree(struct xfs_scrub *sc, struct xfs_inode *ip, | 121 | int 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 | ||
47 | struct 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 | |||
405 | xchk_iallocbt_xref_rmap_inodes( | 401 | xchk_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( | |||
383 | STATIC void | 383 | STATIC void |
384 | xchk_refcount_xref_rmap( | 384 | xchk_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 | |||
419 | xchk_refcountbt( | 417 | xchk_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. */ |
300 | int | 300 | int |
301 | xrep_alloc_ag_block( | 301 | xrep_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. */ |
539 | STATIC int | 537 | STATIC int |
540 | xrep_reap_block( | 538 | xrep_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. */ |
613 | int | 611 | int |
614 | xrep_reap_extents( | 612 | xrep_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); | |||
21 | bool xrep_ag_has_space(struct xfs_perag *pag, xfs_extlen_t nr_blocks, | 21 | bool 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); |
23 | xfs_extlen_t xrep_calc_ag_resblks(struct xfs_scrub *sc); | 23 | xfs_extlen_t xrep_calc_ag_resblks(struct xfs_scrub *sc); |
24 | int xrep_alloc_ag_block(struct xfs_scrub *sc, struct xfs_owner_info *oinfo, | 24 | int 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); | ||
26 | int xrep_init_btblock(struct xfs_scrub *sc, xfs_fsblock_t fsb, | 27 | int 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; | |||
32 | int xrep_fix_freelist(struct xfs_scrub *sc, bool can_shrink); | 33 | int xrep_fix_freelist(struct xfs_scrub *sc, bool can_shrink); |
33 | int xrep_invalidate_blocks(struct xfs_scrub *sc, struct xfs_bitmap *btlist); | 34 | int xrep_invalidate_blocks(struct xfs_scrub *sc, struct xfs_bitmap *btlist); |
34 | int xrep_reap_extents(struct xfs_scrub *sc, struct xfs_bitmap *exlist, | 35 | int 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 | ||
37 | struct xrep_find_ag_btree { | 38 | struct 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 | |||
174 | xchk_rmapbt( | 174 | xchk_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 */ |
185 | static inline void | 182 | static inline void |
186 | xchk_xref_check_owner( | 183 | xchk_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 */ |
208 | void | 205 | void |
209 | xchk_xref_is_owned_by( | 206 | xchk_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 */ |
219 | void | 216 | void |
220 | xchk_xref_is_not_owned_by( | 217 | xchk_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, | |||
122 | void xchk_xref_is_inode_chunk(struct xfs_scrub *sc, xfs_agblock_t agbno, | 122 | void xchk_xref_is_inode_chunk(struct xfs_scrub *sc, xfs_agblock_t agbno, |
123 | xfs_extlen_t len); | 123 | xfs_extlen_t len); |
124 | void xchk_xref_is_owned_by(struct xfs_scrub *sc, xfs_agblock_t agbno, | 124 | void 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); |
126 | void xchk_xref_is_not_owned_by(struct xfs_scrub *sc, xfs_agblock_t agbno, | 126 | void 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); |
128 | void xchk_xref_has_no_owner(struct xfs_scrub *sc, xfs_agblock_t agbno, | 128 | void xchk_xref_has_no_owner(struct xfs_scrub *sc, xfs_agblock_t agbno, |
129 | xfs_extlen_t len); | 129 | xfs_extlen_t len); |
130 | void xchk_xref_is_cow_staging(struct xfs_scrub *sc, xfs_agblock_t bno, | 130 | void 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 | */ | ||
21 | TRACE_DEFINE_ENUM(XFS_BTNUM_BNOi); | ||
22 | TRACE_DEFINE_ENUM(XFS_BTNUM_CNTi); | ||
23 | TRACE_DEFINE_ENUM(XFS_BTNUM_BMAPi); | ||
24 | TRACE_DEFINE_ENUM(XFS_BTNUM_INOi); | ||
25 | TRACE_DEFINE_ENUM(XFS_BTNUM_FINOi); | ||
26 | TRACE_DEFINE_ENUM(XFS_BTNUM_RMAPi); | ||
27 | TRACE_DEFINE_ENUM(XFS_BTNUM_REFCi); | ||
28 | |||
29 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_PROBE); | ||
30 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_SB); | ||
31 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_AGF); | ||
32 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_AGFL); | ||
33 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_AGI); | ||
34 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_BNOBT); | ||
35 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_CNTBT); | ||
36 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_INOBT); | ||
37 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_FINOBT); | ||
38 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_RMAPBT); | ||
39 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_REFCNTBT); | ||
40 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_INODE); | ||
41 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_BMBTD); | ||
42 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_BMBTA); | ||
43 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_BMBTC); | ||
44 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_DIR); | ||
45 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_XATTR); | ||
46 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_SYMLINK); | ||
47 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_PARENT); | ||
48 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_RTBITMAP); | ||
49 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_RTSUM); | ||
50 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_UQUOTA); | ||
51 | TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_GQUOTA); | ||
52 | TRACE_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 | |||
15 | DECLARE_EVENT_CLASS(xchk_class, | 80 | DECLARE_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 | ) |
607 | TRACE_EVENT(xrep_findroot_block, | 672 | TRACE_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 | */ |
14 | enum { | 17 | enum { |
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++) { |
2278 | retry: | 2274 | retry: |
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 | */ |
628 | int | 635 | STATIC int |
629 | xfs_reflink_end_cow( | 636 | xfs_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; | ||
740 | prev_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 | ||
751 | out_cancel: | 739 | out_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); |
754 | out: | 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 | */ | ||
748 | int | ||
749 | xfs_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; |
94 | out: | ||
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 | ||
864 | static void | ||
865 | xfs_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 | */ |
1193 | int /* error */ | 1236 | int /* error */ |
1194 | xfs_rtmount_inodes( | 1237 | xfs_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 | |||
1218 | xfs_rtunmount_inodes( | 1260 | xfs_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 | */ |
382 | STATIC int | 389 | STATIC int |
383 | xfs_inactive_symlink_rmt( | 390 | xfs_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); | |||
640 | DEFINE_INODE_EVENT(xfs_inode_clear_cowblocks_tag); | 640 | DEFINE_INODE_EVENT(xfs_inode_clear_cowblocks_tag); |
641 | DEFINE_INODE_EVENT(xfs_inode_free_cowblocks_invalid); | 641 | DEFINE_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 | */ | ||
649 | TRACE_DEFINE_ENUM(PE_SIZE_PTE); | ||
650 | TRACE_DEFINE_ENUM(PE_SIZE_PMD); | ||
651 | TRACE_DEFINE_ENUM(PE_SIZE_PUD); | ||
652 | |||
643 | TRACE_EVENT(xfs_filemap_fault, | 653 | TRACE_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, \ | |||
1208 | DEFINE_READPAGE_EVENT(xfs_vm_readpage); | 1218 | DEFINE_READPAGE_EVENT(xfs_vm_readpage); |
1209 | DEFINE_READPAGE_EVENT(xfs_vm_readpages); | 1219 | DEFINE_READPAGE_EVENT(xfs_vm_readpages); |
1210 | 1220 | ||
1221 | TRACE_DEFINE_ENUM(XFS_IO_HOLE); | ||
1222 | TRACE_DEFINE_ENUM(XFS_IO_DELALLOC); | ||
1223 | TRACE_DEFINE_ENUM(XFS_IO_UNWRITTEN); | ||
1224 | TRACE_DEFINE_ENUM(XFS_IO_OVERWRITE); | ||
1225 | TRACE_DEFINE_ENUM(XFS_IO_COW); | ||
1226 | |||
1211 | DECLARE_EVENT_CLASS(xfs_imap_class, | 1227 | DECLARE_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 \ | 1904 | TRACE_DEFINE_ENUM(XFS_DINODE_FMT_DEV); |
1889 | { 0, "invalid" }, \ | 1905 | TRACE_DEFINE_ENUM(XFS_DINODE_FMT_LOCAL); |
1890 | { 1, "local" }, \ | 1906 | TRACE_DEFINE_ENUM(XFS_DINODE_FMT_EXTENTS); |
1891 | { 2, "extent" }, \ | 1907 | TRACE_DEFINE_ENUM(XFS_DINODE_FMT_BTREE); |
1892 | { 3, "btree" } | 1908 | TRACE_DEFINE_ENUM(XFS_DINODE_FMT_UUID); |
1893 | 1909 | ||
1894 | DECLARE_EVENT_CLASS(xfs_swap_extent_class, | 1910 | DECLARE_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); | |||
2178 | DEFINE_DISCARD_EVENT(xfs_discard_busy); | 2194 | DEFINE_DISCARD_EVENT(xfs_discard_busy); |
2179 | 2195 | ||
2180 | /* btree cursor events */ | 2196 | /* btree cursor events */ |
2197 | TRACE_DEFINE_ENUM(XFS_BTNUM_BNOi); | ||
2198 | TRACE_DEFINE_ENUM(XFS_BTNUM_CNTi); | ||
2199 | TRACE_DEFINE_ENUM(XFS_BTNUM_BMAPi); | ||
2200 | TRACE_DEFINE_ENUM(XFS_BTNUM_INOi); | ||
2201 | TRACE_DEFINE_ENUM(XFS_BTNUM_FINOi); | ||
2202 | TRACE_DEFINE_ENUM(XFS_BTNUM_RMAPi); | ||
2203 | TRACE_DEFINE_ENUM(XFS_BTNUM_REFCi); | ||
2204 | |||
2181 | DECLARE_EVENT_CLASS(xfs_btree_cur_class, | 2205 | DECLARE_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); | |||
2405 | DECLARE_EVENT_CLASS(xfs_rmap_class, | 2429 | DECLARE_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, | |||
2440 | DEFINE_EVENT(xfs_rmap_class, name, \ | 2464 | DEFINE_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 \ | 2637 | TRACE_DEFINE_ENUM(XFS_LOOKUP_EQi); |
2614 | { XFS_LOOKUP_EQ, "eq" }, \ | 2638 | TRACE_DEFINE_ENUM(XFS_LOOKUP_LEi); |
2615 | { XFS_LOOKUP_LE, "le" }, \ | 2639 | TRACE_DEFINE_ENUM(XFS_LOOKUP_GEi); |
2616 | { XFS_LOOKUP_GE, "ge" } | ||
2617 | DECLARE_EVENT_CLASS(xfs_ag_btree_lookup_class, | 2640 | DECLARE_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 *); | |||
223 | bool xfs_trans_buf_is_dirty(struct xfs_buf *bp); | 223 | bool xfs_trans_buf_is_dirty(struct xfs_buf *bp); |
224 | void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint); | 224 | void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint); |
225 | 225 | ||
226 | void xfs_extent_free_init_defer_op(void); | ||
227 | struct xfs_efd_log_item *xfs_trans_get_efd(struct xfs_trans *, | 226 | struct 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); |
230 | int xfs_trans_free_extent(struct xfs_trans *, | 229 | int 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); |
234 | int xfs_trans_commit(struct xfs_trans *); | 234 | int xfs_trans_commit(struct xfs_trans *); |
235 | int xfs_trans_roll(struct xfs_trans **); | 235 | int xfs_trans_roll(struct xfs_trans **); |
@@ -248,7 +248,6 @@ extern kmem_zone_t *xfs_trans_zone; | |||
248 | /* rmap updates */ | 248 | /* rmap updates */ |
249 | enum xfs_rmap_intent_type; | 249 | enum xfs_rmap_intent_type; |
250 | 250 | ||
251 | void xfs_rmap_update_init_defer_op(void); | ||
252 | struct xfs_rud_log_item *xfs_trans_get_rud(struct xfs_trans *tp, | 251 | struct 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); |
254 | int xfs_trans_log_finish_rmap_update(struct xfs_trans *tp, | 253 | int 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 */ |
261 | enum xfs_refcount_intent_type; | 260 | enum xfs_refcount_intent_type; |
262 | 261 | ||
263 | void xfs_refcount_update_init_defer_op(void); | ||
264 | struct xfs_cud_log_item *xfs_trans_get_cud(struct xfs_trans *tp, | 262 | struct 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); |
266 | int xfs_trans_log_finish_refcount_update(struct xfs_trans *tp, | 264 | int 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 */ |
273 | enum xfs_bmap_intent_type; | 271 | enum xfs_bmap_intent_type; |
274 | 272 | ||
275 | void xfs_bmap_update_init_defer_op(void); | ||
276 | struct xfs_bud_log_item *xfs_trans_get_bud(struct xfs_trans *tp, | 273 | struct 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); |
278 | int xfs_trans_log_finish_bmap_update(struct xfs_trans *tp, | 275 | int 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 | ||
223 | static const struct xfs_defer_op_type xfs_bmap_update_defer_type = { | 224 | const 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. */ | ||
236 | void | ||
237 | xfs_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 | */ |
53 | int | 54 | int |
54 | xfs_trans_free_extent( | 55 | xfs_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 | ||
209 | static const struct xfs_defer_op_type xfs_extent_free_defer_type = { | 211 | const 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 */ |
277 | static const struct xfs_defer_op_type xfs_agfl_free_defer_type = { | 278 | const 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. */ | ||
290 | void | ||
291 | xfs_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 | ||
230 | static const struct xfs_defer_op_type xfs_refcount_update_defer_type = { | 231 | const 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. */ | ||
244 | void | ||
245 | xfs_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. */ |
21 | static void | 22 | static void |
@@ -244,8 +245,7 @@ xfs_rmap_update_cancel_item( | |||
244 | kmem_free(rmap); | 245 | kmem_free(rmap); |
245 | } | 246 | } |
246 | 247 | ||
247 | static const struct xfs_defer_op_type xfs_rmap_update_defer_type = { | 248 | const 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. */ | ||
261 | void | ||
262 | xfs_rmap_update_init_defer_op(void) | ||
263 | { | ||
264 | xfs_defer_init_op_type(&xfs_rmap_update_defer_type); | ||
265 | } | ||