summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-03-13 10:49:15 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-03-13 10:49:15 -0700
commit399af66228cfd7df79dc360810b6b673000f8090 (patch)
tree69be367f431555217d41c937e38eee96795cb4ea /fs
parentd874ca0522389405e26bc2ba38b59c9849c52cc1 (diff)
parent362c490980867930a098b99f421268fbd7ca05fd (diff)
Merge tag 'xfs-fixes-7.0-rc4' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull xfs fixes from Carlos Maiolino: "A couple race fixes found on the new healthmon mechanism, and another flushing dquots during filesystem shutdown" * tag 'xfs-fixes-7.0-rc4' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: xfs: fix integer overflow in bmap intent sort comparator xfs: fix undersized l_iclog_roundoff values xfs: ensure dquot item is deleted from AIL only after log shutdown xfs: remove redundant set null for ip->i_itemp xfs: fix returned valued from xfs_defer_can_append xfs: Remove redundant NULL check after __GFP_NOFAIL xfs: fix race between healthmon unmount and read_iter xfs: remove scratch field from struct xfs_gc_bio
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/libxfs/xfs_da_btree.c8
-rw-r--r--fs/xfs/libxfs/xfs_defer.c2
-rw-r--r--fs/xfs/xfs_bmap_item.c2
-rw-r--r--fs/xfs/xfs_dquot.c8
-rw-r--r--fs/xfs/xfs_healthmon.c17
-rw-r--r--fs/xfs/xfs_icache.c1
-rw-r--r--fs/xfs/xfs_log.c2
-rw-r--r--fs/xfs/xfs_zone_gc.c2
8 files changed, 23 insertions, 19 deletions
diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c
index 766631f0562e..09d4c17b3e7b 100644
--- a/fs/xfs/libxfs/xfs_da_btree.c
+++ b/fs/xfs/libxfs/xfs_da_btree.c
@@ -2716,12 +2716,8 @@ xfs_dabuf_map(
* larger one that needs to be free by the caller.
*/
if (nirecs > 1) {
- map = kzalloc(nirecs * sizeof(struct xfs_buf_map),
- GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
- if (!map) {
- error = -ENOMEM;
- goto out_free_irecs;
- }
+ map = kcalloc(nirecs, sizeof(struct xfs_buf_map),
+ GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
*mapp = map;
}
diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c
index 472c261163ed..c6909716b041 100644
--- a/fs/xfs/libxfs/xfs_defer.c
+++ b/fs/xfs/libxfs/xfs_defer.c
@@ -809,7 +809,7 @@ xfs_defer_can_append(
/* Paused items cannot absorb more work */
if (dfp->dfp_flags & XFS_DEFER_PAUSED)
- return NULL;
+ return false;
/* Already full? */
if (ops->max_items && dfp->dfp_count >= ops->max_items)
diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c
index e8775f254c89..b237a25d6045 100644
--- a/fs/xfs/xfs_bmap_item.c
+++ b/fs/xfs/xfs_bmap_item.c
@@ -245,7 +245,7 @@ xfs_bmap_update_diff_items(
struct xfs_bmap_intent *ba = bi_entry(a);
struct xfs_bmap_intent *bb = bi_entry(b);
- return ba->bi_owner->i_ino - bb->bi_owner->i_ino;
+ return cmp_int(ba->bi_owner->i_ino, bb->bi_owner->i_ino);
}
/* Log bmap updates in the intent item. */
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 2b208e2c5264..69e9bc588c8b 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -1439,9 +1439,15 @@ xfs_qm_dqflush(
return 0;
out_abort:
+ /*
+ * Shut down the log before removing the dquot item from the AIL.
+ * Otherwise, the log tail may advance past this item's LSN while
+ * log writes are still in progress, making these unflushed changes
+ * unrecoverable on the next mount.
+ */
+ xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
dqp->q_flags &= ~XFS_DQFLAG_DIRTY;
xfs_trans_ail_delete(lip, 0);
- xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
xfs_dqfunlock(dqp);
return error;
}
diff --git a/fs/xfs/xfs_healthmon.c b/fs/xfs/xfs_healthmon.c
index 4a06d6632f65..26c325d34bd1 100644
--- a/fs/xfs/xfs_healthmon.c
+++ b/fs/xfs/xfs_healthmon.c
@@ -141,6 +141,16 @@ xfs_healthmon_detach(
hm->mount_cookie = DETACHED_MOUNT_COOKIE;
spin_unlock(&xfs_healthmon_lock);
+ /*
+ * Wake up any readers that might remain. This can happen if unmount
+ * races with the healthmon fd owner entering ->read_iter, having
+ * already emptied the event queue.
+ *
+ * In the ->release case there shouldn't be any readers because the
+ * only users of the waiter are read and poll.
+ */
+ wake_up_all(&hm->wait);
+
trace_xfs_healthmon_detach(hm);
xfs_healthmon_put(hm);
}
@@ -1027,13 +1037,6 @@ xfs_healthmon_release(
* process can create another health monitor file.
*/
xfs_healthmon_detach(hm);
-
- /*
- * Wake up any readers that might be left. There shouldn't be any
- * because the only users of the waiter are read and poll.
- */
- wake_up_all(&hm->wait);
-
xfs_healthmon_put(hm);
return 0;
}
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index a7a09e7eec81..2040a9292ee6 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -159,7 +159,6 @@ xfs_inode_free_callback(
ASSERT(!test_bit(XFS_LI_IN_AIL,
&ip->i_itemp->ili_item.li_flags));
xfs_inode_item_destroy(ip);
- ip->i_itemp = NULL;
}
kmem_cache_free(xfs_inode_cache, ip);
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index b96f262ba139..f807f8f4f705 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -1357,6 +1357,8 @@ xlog_alloc_log(
if (xfs_has_logv2(mp) && mp->m_sb.sb_logsunit > 1)
log->l_iclog_roundoff = mp->m_sb.sb_logsunit;
+ else if (mp->m_sb.sb_logsectsize > 0)
+ log->l_iclog_roundoff = mp->m_sb.sb_logsectsize;
else
log->l_iclog_roundoff = BBSIZE;
diff --git a/fs/xfs/xfs_zone_gc.c b/fs/xfs/xfs_zone_gc.c
index 7efeecd2d85f..309f70098524 100644
--- a/fs/xfs/xfs_zone_gc.c
+++ b/fs/xfs/xfs_zone_gc.c
@@ -96,7 +96,6 @@ struct xfs_gc_bio {
*/
xfs_fsblock_t old_startblock;
xfs_daddr_t new_daddr;
- struct xfs_zone_scratch *scratch;
/* Are we writing to a sequential write required zone? */
bool is_seq;
@@ -779,7 +778,6 @@ xfs_zone_gc_split_write(
ihold(VFS_I(chunk->ip));
split_chunk->ip = chunk->ip;
split_chunk->is_seq = chunk->is_seq;
- split_chunk->scratch = chunk->scratch;
split_chunk->offset = chunk->offset;
split_chunk->len = split_len;
split_chunk->old_startblock = chunk->old_startblock;