Skip to content

Commit d32e907

Browse files
committed
Merge tag 'xfs-fixes-6.16-rc5' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull xfs fixes from Carlos Maiolino: - Fix umount hang with unflushable inodes (and add new tracepoint used for debugging this) - Fix ABBA deadlock in xfs_reclaim_inode() vs xfs_ifree_cluster() - Fix dquot buffer pin deadlock * tag 'xfs-fixes-6.16-rc5' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: xfs: add FALLOC_FL_ALLOCATE_RANGE to supported flags mask xfs: fix unmount hang with unflushable inodes stuck in the AIL xfs: factor out stale buffer item completion xfs: rearrange code in xfs_buf_item.c xfs: add tracepoints for stale pinned inode state debug xfs: avoid dquot buffer pin deadlock xfs: catch stale AGF/AGF metadata xfs: xfs_ifree_cluster vs xfs_iflush_shutdown_abort deadlock xfs: actually use the xfs_growfs_check_rtgeom tracepoint xfs: Improve error handling in xfs_mru_cache_create() xfs: move xfs_submit_zoned_bio a bit xfs: use xfs_readonly_buftarg in xfs_remount_rw xfs: remove NULL pointer checks in xfs_mru_cache_insert xfs: check for shutdown before going to sleep in xfs_select_zone
2 parents b4911fb + 9e9b466 commit d32e907

19 files changed

+320
-287
lines changed

fs/xfs/libxfs/xfs_alloc.c

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3444,16 +3444,41 @@ xfs_alloc_read_agf(
34443444

34453445
set_bit(XFS_AGSTATE_AGF_INIT, &pag->pag_opstate);
34463446
}
3447+
34473448
#ifdef DEBUG
3448-
else if (!xfs_is_shutdown(mp)) {
3449-
ASSERT(pag->pagf_freeblks == be32_to_cpu(agf->agf_freeblks));
3450-
ASSERT(pag->pagf_btreeblks == be32_to_cpu(agf->agf_btreeblks));
3451-
ASSERT(pag->pagf_flcount == be32_to_cpu(agf->agf_flcount));
3452-
ASSERT(pag->pagf_longest == be32_to_cpu(agf->agf_longest));
3453-
ASSERT(pag->pagf_bno_level == be32_to_cpu(agf->agf_bno_level));
3454-
ASSERT(pag->pagf_cnt_level == be32_to_cpu(agf->agf_cnt_level));
3449+
/*
3450+
* It's possible for the AGF to be out of sync if the block device is
3451+
* silently dropping writes. This can happen in fstests with dmflakey
3452+
* enabled, which allows the buffer to be cleaned and reclaimed by
3453+
* memory pressure and then re-read from disk here. We will get a
3454+
* stale version of the AGF from disk, and nothing good can happen from
3455+
* here. Hence if we detect this situation, immediately shut down the
3456+
* filesystem.
3457+
*
3458+
* This can also happen if we are already in the middle of a forced
3459+
* shutdown, so don't bother checking if we are already shut down.
3460+
*/
3461+
if (!xfs_is_shutdown(pag_mount(pag))) {
3462+
bool ok = true;
3463+
3464+
ok &= pag->pagf_freeblks == be32_to_cpu(agf->agf_freeblks);
3465+
ok &= pag->pagf_freeblks == be32_to_cpu(agf->agf_freeblks);
3466+
ok &= pag->pagf_btreeblks == be32_to_cpu(agf->agf_btreeblks);
3467+
ok &= pag->pagf_flcount == be32_to_cpu(agf->agf_flcount);
3468+
ok &= pag->pagf_longest == be32_to_cpu(agf->agf_longest);
3469+
ok &= pag->pagf_bno_level == be32_to_cpu(agf->agf_bno_level);
3470+
ok &= pag->pagf_cnt_level == be32_to_cpu(agf->agf_cnt_level);
3471+
3472+
if (XFS_IS_CORRUPT(pag_mount(pag), !ok)) {
3473+
xfs_ag_mark_sick(pag, XFS_SICK_AG_AGF);
3474+
xfs_trans_brelse(tp, agfbp);
3475+
xfs_force_shutdown(pag_mount(pag),
3476+
SHUTDOWN_CORRUPT_ONDISK);
3477+
return -EFSCORRUPTED;
3478+
}
34553479
}
3456-
#endif
3480+
#endif /* DEBUG */
3481+
34573482
if (agfbpp)
34583483
*agfbpp = agfbp;
34593484
else

fs/xfs/libxfs/xfs_ialloc.c

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2801,12 +2801,35 @@ xfs_ialloc_read_agi(
28012801
set_bit(XFS_AGSTATE_AGI_INIT, &pag->pag_opstate);
28022802
}
28032803

2804+
#ifdef DEBUG
28042805
/*
2805-
* It's possible for these to be out of sync if
2806-
* we are in the middle of a forced shutdown.
2806+
* It's possible for the AGF to be out of sync if the block device is
2807+
* silently dropping writes. This can happen in fstests with dmflakey
2808+
* enabled, which allows the buffer to be cleaned and reclaimed by
2809+
* memory pressure and then re-read from disk here. We will get a
2810+
* stale version of the AGF from disk, and nothing good can happen from
2811+
* here. Hence if we detect this situation, immediately shut down the
2812+
* filesystem.
2813+
*
2814+
* This can also happen if we are already in the middle of a forced
2815+
* shutdown, so don't bother checking if we are already shut down.
28072816
*/
2808-
ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) ||
2809-
xfs_is_shutdown(pag_mount(pag)));
2817+
if (!xfs_is_shutdown(pag_mount(pag))) {
2818+
bool ok = true;
2819+
2820+
ok &= pag->pagi_freecount == be32_to_cpu(agi->agi_freecount);
2821+
ok &= pag->pagi_count == be32_to_cpu(agi->agi_count);
2822+
2823+
if (XFS_IS_CORRUPT(pag_mount(pag), !ok)) {
2824+
xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI);
2825+
xfs_trans_brelse(tp, agibp);
2826+
xfs_force_shutdown(pag_mount(pag),
2827+
SHUTDOWN_CORRUPT_ONDISK);
2828+
return -EFSCORRUPTED;
2829+
}
2830+
}
2831+
#endif /* DEBUG */
2832+
28102833
if (agibpp)
28112834
*agibpp = agibp;
28122835
else

fs/xfs/xfs_buf.c

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2082,44 +2082,6 @@ xfs_buf_delwri_submit(
20822082
return error;
20832083
}
20842084

2085-
/*
2086-
* Push a single buffer on a delwri queue.
2087-
*
2088-
* The purpose of this function is to submit a single buffer of a delwri queue
2089-
* and return with the buffer still on the original queue.
2090-
*
2091-
* The buffer locking and queue management logic between _delwri_pushbuf() and
2092-
* _delwri_queue() guarantee that the buffer cannot be queued to another list
2093-
* before returning.
2094-
*/
2095-
int
2096-
xfs_buf_delwri_pushbuf(
2097-
struct xfs_buf *bp,
2098-
struct list_head *buffer_list)
2099-
{
2100-
int error;
2101-
2102-
ASSERT(bp->b_flags & _XBF_DELWRI_Q);
2103-
2104-
trace_xfs_buf_delwri_pushbuf(bp, _RET_IP_);
2105-
2106-
xfs_buf_lock(bp);
2107-
bp->b_flags &= ~(_XBF_DELWRI_Q | XBF_ASYNC);
2108-
bp->b_flags |= XBF_WRITE;
2109-
xfs_buf_submit(bp);
2110-
2111-
/*
2112-
* The buffer is now locked, under I/O but still on the original delwri
2113-
* queue. Wait for I/O completion, restore the DELWRI_Q flag and
2114-
* return with the buffer unlocked and still on the original queue.
2115-
*/
2116-
error = xfs_buf_iowait(bp);
2117-
bp->b_flags |= _XBF_DELWRI_Q;
2118-
xfs_buf_unlock(bp);
2119-
2120-
return error;
2121-
}
2122-
21232085
void xfs_buf_set_ref(struct xfs_buf *bp, int lru_ref)
21242086
{
21252087
/*

fs/xfs/xfs_buf.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,6 @@ extern bool xfs_buf_delwri_queue(struct xfs_buf *, struct list_head *);
326326
void xfs_buf_delwri_queue_here(struct xfs_buf *bp, struct list_head *bl);
327327
extern int xfs_buf_delwri_submit(struct list_head *);
328328
extern int xfs_buf_delwri_submit_nowait(struct list_head *);
329-
extern int xfs_buf_delwri_pushbuf(struct xfs_buf *, struct list_head *);
330329

331330
static inline xfs_daddr_t xfs_buf_daddr(struct xfs_buf *bp)
332331
{

0 commit comments

Comments
 (0)