Skip to content

Commit

Permalink
Merge tag 'xfs-fixes-6.13-rc2' of git://git.kernel.org/pub/scm/fs/xfs…
Browse files Browse the repository at this point in the history
…/xfs-linux

Pull xfs fixes from Carlos Maiolino:

 - Use xchg() in xlog_cil_insert_pcp_aggregate()

 - Fix ABBA deadlock on a race between mount and log shutdown

 - Fix quota softlimit incoherency on delalloc

 - Fix sparse inode limits on runt AG

 - remove unknown compat feature checks in SB write valdation

 - Eliminate a lockdep false positive

* tag 'xfs-fixes-6.13-rc2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
  xfs: don't call xfs_bmap_same_rtgroup in xfs_bmap_add_extent_hole_delay
  xfs: Use xchg() in xlog_cil_insert_pcp_aggregate()
  xfs: prevent mount and log shutdown race
  xfs: delalloc and quota softlimit timers are incoherent
  xfs: fix sparse inode limits on runt AG
  xfs: remove unknown compat feature check in superblock write validation
  xfs: eliminate lockdep false positives in xfs_attr_shortform_list
  • Loading branch information
torvalds committed Dec 3, 2024
2 parents ceb8bf2 + cc2dba0 commit 9141c5d
Show file tree
Hide file tree
Showing 8 changed files with 26 additions and 36 deletions.
6 changes: 2 additions & 4 deletions fs/xfs/libxfs/xfs_bmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -2620,17 +2620,15 @@ xfs_bmap_add_extent_hole_delay(
*/
if ((state & BMAP_LEFT_VALID) && (state & BMAP_LEFT_DELAY) &&
left.br_startoff + left.br_blockcount == new->br_startoff &&
left.br_blockcount + new->br_blockcount <= XFS_MAX_BMBT_EXTLEN &&
xfs_bmap_same_rtgroup(ip, whichfork, &left, new))
left.br_blockcount + new->br_blockcount <= XFS_MAX_BMBT_EXTLEN)
state |= BMAP_LEFT_CONTIG;

if ((state & BMAP_RIGHT_VALID) && (state & BMAP_RIGHT_DELAY) &&
new->br_startoff + new->br_blockcount == right.br_startoff &&
new->br_blockcount + right.br_blockcount <= XFS_MAX_BMBT_EXTLEN &&
(!(state & BMAP_LEFT_CONTIG) ||
(left.br_blockcount + new->br_blockcount +
right.br_blockcount <= XFS_MAX_BMBT_EXTLEN)) &&
xfs_bmap_same_rtgroup(ip, whichfork, new, &right))
right.br_blockcount <= XFS_MAX_BMBT_EXTLEN)))
state |= BMAP_RIGHT_CONTIG;

/*
Expand Down
16 changes: 9 additions & 7 deletions fs/xfs/libxfs/xfs_ialloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -853,7 +853,8 @@ xfs_ialloc_ag_alloc(
* the end of the AG.
*/
args.min_agbno = args.mp->m_sb.sb_inoalignmt;
args.max_agbno = round_down(args.mp->m_sb.sb_agblocks,
args.max_agbno = round_down(xfs_ag_block_count(args.mp,
pag_agno(pag)),
args.mp->m_sb.sb_inoalignmt) -
igeo->ialloc_blks;

Expand Down Expand Up @@ -2349,9 +2350,9 @@ xfs_difree(
return -EINVAL;
}
agbno = XFS_AGINO_TO_AGBNO(mp, agino);
if (agbno >= mp->m_sb.sb_agblocks) {
xfs_warn(mp, "%s: agbno >= mp->m_sb.sb_agblocks (%d >= %d).",
__func__, agbno, mp->m_sb.sb_agblocks);
if (agbno >= xfs_ag_block_count(mp, pag_agno(pag))) {
xfs_warn(mp, "%s: agbno >= xfs_ag_block_count (%d >= %d).",
__func__, agbno, xfs_ag_block_count(mp, pag_agno(pag)));
ASSERT(0);
return -EINVAL;
}
Expand Down Expand Up @@ -2474,7 +2475,7 @@ xfs_imap(
*/
agino = XFS_INO_TO_AGINO(mp, ino);
agbno = XFS_AGINO_TO_AGBNO(mp, agino);
if (agbno >= mp->m_sb.sb_agblocks ||
if (agbno >= xfs_ag_block_count(mp, pag_agno(pag)) ||
ino != xfs_agino_to_ino(pag, agino)) {
error = -EINVAL;
#ifdef DEBUG
Expand All @@ -2484,11 +2485,12 @@ xfs_imap(
*/
if (flags & XFS_IGET_UNTRUSTED)
return error;
if (agbno >= mp->m_sb.sb_agblocks) {
if (agbno >= xfs_ag_block_count(mp, pag_agno(pag))) {
xfs_alert(mp,
"%s: agbno (0x%llx) >= mp->m_sb.sb_agblocks (0x%lx)",
__func__, (unsigned long long)agbno,
(unsigned long)mp->m_sb.sb_agblocks);
(unsigned long)xfs_ag_block_count(mp,
pag_agno(pag)));
}
if (ino != xfs_agino_to_ino(pag, agino)) {
xfs_alert(mp,
Expand Down
7 changes: 0 additions & 7 deletions fs/xfs/libxfs/xfs_sb.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,13 +326,6 @@ xfs_validate_sb_write(
* the kernel cannot support since we checked for unsupported bits in
* the read verifier, which means that memory is corrupt.
*/
if (xfs_sb_has_compat_feature(sbp, XFS_SB_FEAT_COMPAT_UNKNOWN)) {
xfs_warn(mp,
"Corruption detected in superblock compatible features (0x%x)!",
(sbp->sb_features_compat & XFS_SB_FEAT_COMPAT_UNKNOWN));
return -EFSCORRUPTED;
}

if (!xfs_is_readonly(mp) &&
xfs_sb_has_ro_compat_feature(sbp, XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) {
xfs_alert(mp,
Expand Down
3 changes: 2 additions & 1 deletion fs/xfs/xfs_attr_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ xfs_attr_shortform_list(
* It didn't all fit, so we have to sort everything on hashval.
*/
sbsize = sf->count * sizeof(*sbuf);
sbp = sbuf = kmalloc(sbsize, GFP_KERNEL | __GFP_NOFAIL);
sbp = sbuf = kmalloc(sbsize,
GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);

/*
* Scan the attribute list for the rest of the entries, storing
Expand Down
11 changes: 11 additions & 0 deletions fs/xfs/xfs_log.c
Original file line number Diff line number Diff line change
Expand Up @@ -3455,6 +3455,16 @@ xlog_force_shutdown(
if (!log)
return false;

/*
* Ensure that there is only ever one log shutdown being processed.
* If we allow the log force below on a second pass after shutting
* down the log, we risk deadlocking the CIL push as it may require
* locks on objects the current shutdown context holds (e.g. taking
* buffer locks to abort buffers on last unpin of buf log items).
*/
if (test_and_set_bit(XLOG_SHUTDOWN_STARTED, &log->l_opstate))
return false;

/*
* Flush all the completed transactions to disk before marking the log
* being shut down. We need to do this first as shutting down the log
Expand Down Expand Up @@ -3487,6 +3497,7 @@ xlog_force_shutdown(
spin_lock(&log->l_icloglock);
if (test_and_set_bit(XLOG_IO_ERROR, &log->l_opstate)) {
spin_unlock(&log->l_icloglock);
ASSERT(0);
return false;
}
spin_unlock(&log->l_icloglock);
Expand Down
5 changes: 1 addition & 4 deletions fs/xfs/xfs_log_cil.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,8 @@ xlog_cil_insert_pcp_aggregate(
*/
for_each_cpu(cpu, &ctx->cil_pcpmask) {
struct xlog_cil_pcp *cilpcp = per_cpu_ptr(cil->xc_pcp, cpu);
int old = READ_ONCE(cilpcp->space_used);

while (!try_cmpxchg(&cilpcp->space_used, &old, 0))
;
count += old;
count += xchg(&cilpcp->space_used, 0);
}
atomic_add(count, &ctx->space_used);
}
Expand Down
1 change: 1 addition & 0 deletions fs/xfs/xfs_log_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@ struct xlog {
#define XLOG_IO_ERROR 2 /* log hit an I/O error, and being
shutdown */
#define XLOG_TAIL_WARN 3 /* log tail verify warning issued */
#define XLOG_SHUTDOWN_STARTED 4 /* xlog_force_shutdown() exclusion */

static inline bool
xlog_recovery_needed(struct xlog *log)
Expand Down
13 changes: 0 additions & 13 deletions fs/xfs/xfs_qm_syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -427,19 +427,6 @@ xfs_qm_scall_getquota_fill_qc(
dst->d_ino_timer = 0;
dst->d_rt_spc_timer = 0;
}

#ifdef DEBUG
if (xfs_dquot_is_enforced(dqp) && dqp->q_id != 0) {
if ((dst->d_space > dst->d_spc_softlimit) &&
(dst->d_spc_softlimit > 0)) {
ASSERT(dst->d_spc_timer != 0);
}
if ((dst->d_ino_count > dqp->q_ino.softlimit) &&
(dqp->q_ino.softlimit > 0)) {
ASSERT(dst->d_ino_timer != 0);
}
}
#endif
}

/* Return the quota information for the dquot matching id. */
Expand Down

0 comments on commit 9141c5d

Please sign in to comment.