Skip to content

Commit

Permalink
Merge tag 'xfs-6.3-merge-2' of git://git.kernel.org/pub/scm/fs/xfs/xf…
Browse files Browse the repository at this point in the history
…s-linux

Pull xfs updates from Darrick Wong:
 "There's a couple of bug fixes, some cleanups for inconsistent variable
  names and reduction of struct boxing and unboxing in the logging code.

  More work is pending, which will begin reworking allocation group
  lifetimes and finally replace confusing indirect calls to the
  allocator with actual ... function calls. But I want to let that
  experience another week of testing.

  Summary:

   - Eliminate repeated boxing and unboxing of log item parameters

   - Clean up some confusing variable names in the log item code

   - Fix a deadlock when doing unwritten extent conversion that causes a
     bmbt split when there are sustained memory shortages and the worker
     pool runs out of worker threads

   - Fix the panic_mask debug knob not being able to trigger on verifier
     errors

   - Constify kobj_type objects"

* tag 'xfs-6.3-merge-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
  xfs: revert commit 8954c44
  xfs: make kobj_type structures constant
  xfs: allow setting full range of panic tags
  xfs: don't use BMBT btree split workers for IO completion
  xfs: fix confusing variable names in xfs_refcount_item.c
  xfs: pass refcount intent directly through the log intent code
  xfs: fix confusing variable names in xfs_rmap_item.c
  xfs: pass rmap space mapping directly through the log intent code
  xfs: fix confusing xfs_extent_item variable names
  xfs: pass xfs_extent_free_item directly through the log intent code
  xfs: fix confusing variable names in xfs_bmap_item.c
  xfs: pass the xfs_bmbt_irec directly through the log intent code
  xfs: use strscpy() to instead of strncpy()
  • Loading branch information
torvalds committed Feb 22, 2023
2 parents d151e8b + dd07bb8 commit 28e3352
Show file tree
Hide file tree
Showing 19 changed files with 376 additions and 411 deletions.
2 changes: 1 addition & 1 deletion Documentation/admin-guide/xfs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ The following sysctls are available for the XFS filesystem:
XFS_ERRLEVEL_LOW: 1
XFS_ERRLEVEL_HIGH: 5

fs.xfs.panic_mask (Min: 0 Default: 0 Max: 256)
fs.xfs.panic_mask (Min: 0 Default: 0 Max: 511)
Causes certain error conditions to call BUG(). Value is a bitmask;
OR together the tags which represent errors which should cause panics:

Expand Down
32 changes: 16 additions & 16 deletions fs/xfs/libxfs/xfs_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2472,20 +2472,20 @@ xfs_defer_agfl_block(
struct xfs_owner_info *oinfo)
{
struct xfs_mount *mp = tp->t_mountp;
struct xfs_extent_free_item *new; /* new element */
struct xfs_extent_free_item *xefi;

ASSERT(xfs_extfree_item_cache != NULL);
ASSERT(oinfo != NULL);

new = kmem_cache_zalloc(xfs_extfree_item_cache,
xefi = kmem_cache_zalloc(xfs_extfree_item_cache,
GFP_KERNEL | __GFP_NOFAIL);
new->xefi_startblock = XFS_AGB_TO_FSB(mp, agno, agbno);
new->xefi_blockcount = 1;
new->xefi_owner = oinfo->oi_owner;
xefi->xefi_startblock = XFS_AGB_TO_FSB(mp, agno, agbno);
xefi->xefi_blockcount = 1;
xefi->xefi_owner = oinfo->oi_owner;

trace_xfs_agfl_free_defer(mp, agno, 0, agbno, 1);

xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_AGFL_FREE, &new->xefi_list);
xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_AGFL_FREE, &xefi->xefi_list);
}

/*
Expand All @@ -2500,7 +2500,7 @@ __xfs_free_extent_later(
const struct xfs_owner_info *oinfo,
bool skip_discard)
{
struct xfs_extent_free_item *new; /* new element */
struct xfs_extent_free_item *xefi;
#ifdef DEBUG
struct xfs_mount *mp = tp->t_mountp;
xfs_agnumber_t agno;
Expand All @@ -2519,27 +2519,27 @@ __xfs_free_extent_later(
#endif
ASSERT(xfs_extfree_item_cache != NULL);

new = kmem_cache_zalloc(xfs_extfree_item_cache,
xefi = kmem_cache_zalloc(xfs_extfree_item_cache,
GFP_KERNEL | __GFP_NOFAIL);
new->xefi_startblock = bno;
new->xefi_blockcount = (xfs_extlen_t)len;
xefi->xefi_startblock = bno;
xefi->xefi_blockcount = (xfs_extlen_t)len;
if (skip_discard)
new->xefi_flags |= XFS_EFI_SKIP_DISCARD;
xefi->xefi_flags |= XFS_EFI_SKIP_DISCARD;
if (oinfo) {
ASSERT(oinfo->oi_offset == 0);

if (oinfo->oi_flags & XFS_OWNER_INFO_ATTR_FORK)
new->xefi_flags |= XFS_EFI_ATTR_FORK;
xefi->xefi_flags |= XFS_EFI_ATTR_FORK;
if (oinfo->oi_flags & XFS_OWNER_INFO_BMBT_BLOCK)
new->xefi_flags |= XFS_EFI_BMBT_BLOCK;
new->xefi_owner = oinfo->oi_owner;
xefi->xefi_flags |= XFS_EFI_BMBT_BLOCK;
xefi->xefi_owner = oinfo->oi_owner;
} else {
new->xefi_owner = XFS_RMAP_OWN_NULL;
xefi->xefi_owner = XFS_RMAP_OWN_NULL;
}
trace_xfs_bmap_free_defer(tp->t_mountp,
XFS_FSB_TO_AGNO(tp->t_mountp, bno), 0,
XFS_FSB_TO_AGBNO(tp->t_mountp, bno), len);
xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_FREE, &new->xefi_list);
xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_FREE, &xefi->xefi_list);
}

#ifdef DEBUG
Expand Down
32 changes: 15 additions & 17 deletions fs/xfs/libxfs/xfs_bmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -6146,39 +6146,37 @@ xfs_bmap_unmap_extent(
int
xfs_bmap_finish_one(
struct xfs_trans *tp,
struct xfs_inode *ip,
enum xfs_bmap_intent_type type,
int whichfork,
xfs_fileoff_t startoff,
xfs_fsblock_t startblock,
xfs_filblks_t *blockcount,
xfs_exntst_t state)
struct xfs_bmap_intent *bi)
{
struct xfs_bmbt_irec *bmap = &bi->bi_bmap;
int error = 0;

ASSERT(tp->t_firstblock == NULLFSBLOCK);

trace_xfs_bmap_deferred(tp->t_mountp,
XFS_FSB_TO_AGNO(tp->t_mountp, startblock), type,
XFS_FSB_TO_AGBNO(tp->t_mountp, startblock),
ip->i_ino, whichfork, startoff, *blockcount, state);
XFS_FSB_TO_AGNO(tp->t_mountp, bmap->br_startblock),
bi->bi_type,
XFS_FSB_TO_AGBNO(tp->t_mountp, bmap->br_startblock),
bi->bi_owner->i_ino, bi->bi_whichfork,
bmap->br_startoff, bmap->br_blockcount,
bmap->br_state);

if (WARN_ON_ONCE(whichfork != XFS_DATA_FORK))
if (WARN_ON_ONCE(bi->bi_whichfork != XFS_DATA_FORK))
return -EFSCORRUPTED;

if (XFS_TEST_ERROR(false, tp->t_mountp,
XFS_ERRTAG_BMAP_FINISH_ONE))
return -EIO;

switch (type) {
switch (bi->bi_type) {
case XFS_BMAP_MAP:
error = xfs_bmapi_remap(tp, ip, startoff, *blockcount,
startblock, 0);
*blockcount = 0;
error = xfs_bmapi_remap(tp, bi->bi_owner, bmap->br_startoff,
bmap->br_blockcount, bmap->br_startblock, 0);
bmap->br_blockcount = 0;
break;
case XFS_BMAP_UNMAP:
error = __xfs_bunmapi(tp, ip, startoff, blockcount,
XFS_BMAPI_REMAP, 1);
error = __xfs_bunmapi(tp, bi->bi_owner, bmap->br_startoff,
&bmap->br_blockcount, XFS_BMAPI_REMAP, 1);
break;
default:
ASSERT(0);
Expand Down
5 changes: 1 addition & 4 deletions fs/xfs/libxfs/xfs_bmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,10 +234,7 @@ struct xfs_bmap_intent {
struct xfs_bmbt_irec bi_bmap;
};

int xfs_bmap_finish_one(struct xfs_trans *tp, struct xfs_inode *ip,
enum xfs_bmap_intent_type type, int whichfork,
xfs_fileoff_t startoff, xfs_fsblock_t startblock,
xfs_filblks_t *blockcount, xfs_exntst_t state);
int xfs_bmap_finish_one(struct xfs_trans *tp, struct xfs_bmap_intent *bi);
void xfs_bmap_map_extent(struct xfs_trans *tp, struct xfs_inode *ip,
struct xfs_bmbt_irec *imap);
void xfs_bmap_unmap_extent(struct xfs_trans *tp, struct xfs_inode *ip,
Expand Down
18 changes: 16 additions & 2 deletions fs/xfs/libxfs/xfs_btree.c
Original file line number Diff line number Diff line change
Expand Up @@ -2913,9 +2913,22 @@ xfs_btree_split_worker(
}

/*
* BMBT split requests often come in with little stack to work on. Push
* BMBT split requests often come in with little stack to work on so we push
* them off to a worker thread so there is lots of stack to use. For the other
* btree types, just call directly to avoid the context switch overhead here.
*
* Care must be taken here - the work queue rescuer thread introduces potential
* AGF <> worker queue deadlocks if the BMBT block allocation has to lock new
* AGFs to allocate blocks. A task being run by the rescuer could attempt to
* lock an AGF that is already locked by a task queued to run by the rescuer,
* resulting in an ABBA deadlock as the rescuer cannot run the lock holder to
* release it until the current thread it is running gains the lock.
*
* To avoid this issue, we only ever queue BMBT splits that don't have an AGF
* already locked to allocate from. The only place that doesn't hold an AGF
* locked is unwritten extent conversion at IO completion, but that has already
* been offloaded to a worker thread and hence has no stack consumption issues
* we have to worry about.
*/
STATIC int /* error */
xfs_btree_split(
Expand All @@ -2929,7 +2942,8 @@ xfs_btree_split(
struct xfs_btree_split_args args;
DECLARE_COMPLETION_ONSTACK(done);

if (cur->bc_btnum != XFS_BTNUM_BMAP)
if (cur->bc_btnum != XFS_BTNUM_BMAP ||
cur->bc_tp->t_firstblock == NULLFSBLOCK)
return __xfs_btree_split(cur, level, ptrp, key, curp, stat);

args.cur = cur;
Expand Down
96 changes: 43 additions & 53 deletions fs/xfs/libxfs/xfs_refcount.c
Original file line number Diff line number Diff line change
Expand Up @@ -1213,37 +1213,33 @@ xfs_refcount_adjust_extents(
STATIC int
xfs_refcount_adjust(
struct xfs_btree_cur *cur,
xfs_agblock_t agbno,
xfs_extlen_t aglen,
xfs_agblock_t *new_agbno,
xfs_extlen_t *new_aglen,
xfs_agblock_t *agbno,
xfs_extlen_t *aglen,
enum xfs_refc_adjust_op adj)
{
bool shape_changed;
int shape_changes = 0;
int error;

*new_agbno = agbno;
*new_aglen = aglen;
if (adj == XFS_REFCOUNT_ADJUST_INCREASE)
trace_xfs_refcount_increase(cur->bc_mp, cur->bc_ag.pag->pag_agno,
agbno, aglen);
trace_xfs_refcount_increase(cur->bc_mp,
cur->bc_ag.pag->pag_agno, *agbno, *aglen);
else
trace_xfs_refcount_decrease(cur->bc_mp, cur->bc_ag.pag->pag_agno,
agbno, aglen);
trace_xfs_refcount_decrease(cur->bc_mp,
cur->bc_ag.pag->pag_agno, *agbno, *aglen);

/*
* Ensure that no rcextents cross the boundary of the adjustment range.
*/
error = xfs_refcount_split_extent(cur, XFS_REFC_DOMAIN_SHARED,
agbno, &shape_changed);
*agbno, &shape_changed);
if (error)
goto out_error;
if (shape_changed)
shape_changes++;

error = xfs_refcount_split_extent(cur, XFS_REFC_DOMAIN_SHARED,
agbno + aglen, &shape_changed);
*agbno + *aglen, &shape_changed);
if (error)
goto out_error;
if (shape_changed)
Expand All @@ -1253,7 +1249,7 @@ xfs_refcount_adjust(
* Try to merge with the left or right extents of the range.
*/
error = xfs_refcount_merge_extents(cur, XFS_REFC_DOMAIN_SHARED,
new_agbno, new_aglen, adj, &shape_changed);
agbno, aglen, adj, &shape_changed);
if (error)
goto out_error;
if (shape_changed)
Expand All @@ -1262,7 +1258,7 @@ xfs_refcount_adjust(
cur->bc_ag.refc.shape_changes++;

/* Now that we've taken care of the ends, adjust the middle extents */
error = xfs_refcount_adjust_extents(cur, new_agbno, new_aglen, adj);
error = xfs_refcount_adjust_extents(cur, agbno, aglen, adj);
if (error)
goto out_error;

Expand Down Expand Up @@ -1298,21 +1294,20 @@ xfs_refcount_finish_one_cleanup(
static inline int
xfs_refcount_continue_op(
struct xfs_btree_cur *cur,
xfs_fsblock_t startblock,
xfs_agblock_t new_agbno,
xfs_extlen_t new_len,
xfs_fsblock_t *new_fsbno)
struct xfs_refcount_intent *ri,
xfs_agblock_t new_agbno)
{
struct xfs_mount *mp = cur->bc_mp;
struct xfs_perag *pag = cur->bc_ag.pag;

if (XFS_IS_CORRUPT(mp, !xfs_verify_agbext(pag, new_agbno, new_len)))
if (XFS_IS_CORRUPT(mp, !xfs_verify_agbext(pag, new_agbno,
ri->ri_blockcount)))
return -EFSCORRUPTED;

*new_fsbno = XFS_AGB_TO_FSB(mp, pag->pag_agno, new_agbno);
ri->ri_startblock = XFS_AGB_TO_FSB(mp, pag->pag_agno, new_agbno);

ASSERT(xfs_verify_fsbext(mp, *new_fsbno, new_len));
ASSERT(pag->pag_agno == XFS_FSB_TO_AGNO(mp, *new_fsbno));
ASSERT(xfs_verify_fsbext(mp, ri->ri_startblock, ri->ri_blockcount));
ASSERT(pag->pag_agno == XFS_FSB_TO_AGNO(mp, ri->ri_startblock));

return 0;
}
Expand All @@ -1327,29 +1322,24 @@ xfs_refcount_continue_op(
int
xfs_refcount_finish_one(
struct xfs_trans *tp,
enum xfs_refcount_intent_type type,
xfs_fsblock_t startblock,
xfs_extlen_t blockcount,
xfs_fsblock_t *new_fsb,
xfs_extlen_t *new_len,
struct xfs_refcount_intent *ri,
struct xfs_btree_cur **pcur)
{
struct xfs_mount *mp = tp->t_mountp;
struct xfs_btree_cur *rcur;
struct xfs_buf *agbp = NULL;
int error = 0;
xfs_agblock_t bno;
xfs_agblock_t new_agbno;
unsigned long nr_ops = 0;
int shape_changes = 0;
struct xfs_perag *pag;

pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, startblock));
bno = XFS_FSB_TO_AGBNO(mp, startblock);
pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, ri->ri_startblock));
bno = XFS_FSB_TO_AGBNO(mp, ri->ri_startblock);

trace_xfs_refcount_deferred(mp, XFS_FSB_TO_AGNO(mp, startblock),
type, XFS_FSB_TO_AGBNO(mp, startblock),
blockcount);
trace_xfs_refcount_deferred(mp, XFS_FSB_TO_AGNO(mp, ri->ri_startblock),
ri->ri_type, XFS_FSB_TO_AGBNO(mp, ri->ri_startblock),
ri->ri_blockcount);

if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_REFCOUNT_FINISH_ONE)) {
error = -EIO;
Expand Down Expand Up @@ -1380,42 +1370,42 @@ xfs_refcount_finish_one(
}
*pcur = rcur;

switch (type) {
switch (ri->ri_type) {
case XFS_REFCOUNT_INCREASE:
error = xfs_refcount_adjust(rcur, bno, blockcount, &new_agbno,
new_len, XFS_REFCOUNT_ADJUST_INCREASE);
error = xfs_refcount_adjust(rcur, &bno, &ri->ri_blockcount,
XFS_REFCOUNT_ADJUST_INCREASE);
if (error)
goto out_drop;
if (*new_len > 0)
error = xfs_refcount_continue_op(rcur, startblock,
new_agbno, *new_len, new_fsb);
if (ri->ri_blockcount > 0)
error = xfs_refcount_continue_op(rcur, ri, bno);
break;
case XFS_REFCOUNT_DECREASE:
error = xfs_refcount_adjust(rcur, bno, blockcount, &new_agbno,
new_len, XFS_REFCOUNT_ADJUST_DECREASE);
error = xfs_refcount_adjust(rcur, &bno, &ri->ri_blockcount,
XFS_REFCOUNT_ADJUST_DECREASE);
if (error)
goto out_drop;
if (*new_len > 0)
error = xfs_refcount_continue_op(rcur, startblock,
new_agbno, *new_len, new_fsb);
if (ri->ri_blockcount > 0)
error = xfs_refcount_continue_op(rcur, ri, bno);
break;
case XFS_REFCOUNT_ALLOC_COW:
*new_fsb = startblock + blockcount;
*new_len = 0;
error = __xfs_refcount_cow_alloc(rcur, bno, blockcount);
error = __xfs_refcount_cow_alloc(rcur, bno, ri->ri_blockcount);
if (error)
goto out_drop;
ri->ri_blockcount = 0;
break;
case XFS_REFCOUNT_FREE_COW:
*new_fsb = startblock + blockcount;
*new_len = 0;
error = __xfs_refcount_cow_free(rcur, bno, blockcount);
error = __xfs_refcount_cow_free(rcur, bno, ri->ri_blockcount);
if (error)
goto out_drop;
ri->ri_blockcount = 0;
break;
default:
ASSERT(0);
error = -EFSCORRUPTED;
}
if (!error && *new_len > 0)
trace_xfs_refcount_finish_one_leftover(mp, pag->pag_agno, type,
bno, blockcount, new_agbno, *new_len);
if (!error && ri->ri_blockcount > 0)
trace_xfs_refcount_finish_one_leftover(mp, pag->pag_agno,
ri->ri_type, bno, ri->ri_blockcount);
out_drop:
xfs_perag_put(pag);
return error;
Expand Down
4 changes: 1 addition & 3 deletions fs/xfs/libxfs/xfs_refcount.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,7 @@ void xfs_refcount_decrease_extent(struct xfs_trans *tp,
extern void xfs_refcount_finish_one_cleanup(struct xfs_trans *tp,
struct xfs_btree_cur *rcur, int error);
extern int xfs_refcount_finish_one(struct xfs_trans *tp,
enum xfs_refcount_intent_type type, xfs_fsblock_t startblock,
xfs_extlen_t blockcount, xfs_fsblock_t *new_fsb,
xfs_extlen_t *new_len, struct xfs_btree_cur **pcur);
struct xfs_refcount_intent *ri, struct xfs_btree_cur **pcur);

extern int xfs_refcount_find_shared(struct xfs_btree_cur *cur,
xfs_agblock_t agbno, xfs_extlen_t aglen, xfs_agblock_t *fbno,
Expand Down
Loading

0 comments on commit 28e3352

Please sign in to comment.