summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-06-05 08:34:32 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-06-05 08:34:32 -0700
commit6a5358410af387fd48251a5e5cc4cf73dc16de52 (patch)
tree9a640eeebffb87ce0fe8947e80b808a339c5ab68
parent2b389a573b76f4e3e1e17654eeaced3eb48c2972 (diff)
parentdabfaca8140f64535a79020f0f86ea56f5db5bb2 (diff)
Merge tag 'xfs-fixes-7.1-rc7' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull xfs fixes from Carlos Maiolino: "A collection of fixes mostly for the RT device, including a small refactor that has no functional change" * tag 'xfs-fixes-7.1-rc7' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: xfs: Remove mention of PageWriteback xfs: abort mount if xfs_fs_reserve_ag_blocks fails xfs: factor rtgroup geom write pointer reporting into a helper xfs: drop the RTG reference later in xfs_ioc_rtgroup_geometry xfs: fix rtgroup cleanup in CoW fork repair xfs: fix error returns in CoW fork repair xfs: fix overlapping extents returned for pNFS LAYOUTGET xfs: fix use of uninitialized imap in xfs_fs_map_blocks error path xfs: handle racing deletions in xfs_zone_gc_iter_irec
-rw-r--r--fs/xfs/scrub/cow_repair.c12
-rw-r--r--fs/xfs/xfs_ioctl.c47
-rw-r--r--fs/xfs/xfs_mount.c7
-rw-r--r--fs/xfs/xfs_pnfs.c11
-rw-r--r--fs/xfs/xfs_reflink.c14
-rw-r--r--fs/xfs/xfs_zone_gc.c2
6 files changed, 50 insertions, 43 deletions
diff --git a/fs/xfs/scrub/cow_repair.c b/fs/xfs/scrub/cow_repair.c
index bffc4666ce60..c25716fc4fee 100644
--- a/fs/xfs/scrub/cow_repair.c
+++ b/fs/xfs/scrub/cow_repair.c
@@ -300,18 +300,15 @@ xrep_cow_find_bad(
* on the debugging knob, replace everything in the CoW fork.
*/
if ((sc->sm->sm_flags & XFS_SCRUB_IFLAG_FORCE_REBUILD) ||
- XFS_TEST_ERROR(sc->mp, XFS_ERRTAG_FORCE_SCRUB_REPAIR)) {
+ XFS_TEST_ERROR(sc->mp, XFS_ERRTAG_FORCE_SCRUB_REPAIR))
error = xrep_cow_mark_file_range(xc, xc->irec.br_startblock,
xc->irec.br_blockcount);
- if (error)
- return error;
- }
out_sa:
xchk_ag_free(sc, &sc->sa);
out_pag:
xfs_perag_put(pag);
- return 0;
+ return error;
}
/*
@@ -385,12 +382,9 @@ xrep_cow_find_bad_rt(
* CoW fork and then scan for staging extents in the refcountbt.
*/
if ((sc->sm->sm_flags & XFS_SCRUB_IFLAG_FORCE_REBUILD) ||
- XFS_TEST_ERROR(sc->mp, XFS_ERRTAG_FORCE_SCRUB_REPAIR)) {
+ XFS_TEST_ERROR(sc->mp, XFS_ERRTAG_FORCE_SCRUB_REPAIR))
error = xrep_cow_mark_file_range(xc, xc->irec.br_startblock,
xc->irec.br_blockcount);
- if (error)
- goto out_rtg;
- }
out_sr:
xchk_rtgroup_btcur_free(&sc->sr);
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 46e234863644..96af6b62ce39 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -409,6 +409,26 @@ xfs_ioc_ag_geometry(
return 0;
}
+static void
+xfs_rtgroup_report_write_pointer(
+ struct xfs_rtgroup *rtg,
+ struct xfs_rtgroup_geometry *rgeo)
+{
+ xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP);
+ if (rtg->rtg_open_zone) {
+ rgeo->rg_writepointer = rtg->rtg_open_zone->oz_allocated;
+ } else {
+ xfs_rgblock_t highest_rgbno = xfs_rtrmap_highest_rgbno(rtg);
+
+ if (highest_rgbno == NULLRGBLOCK)
+ rgeo->rg_writepointer = 0;
+ else
+ rgeo->rg_writepointer = highest_rgbno + 1;
+ }
+ xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_RMAP);
+ rgeo->rg_flags |= XFS_RTGROUP_GEOM_WRITEPOINTER;
+}
+
STATIC int
xfs_ioc_rtgroup_geometry(
struct xfs_mount *mp,
@@ -416,7 +436,6 @@ xfs_ioc_rtgroup_geometry(
{
struct xfs_rtgroup *rtg;
struct xfs_rtgroup_geometry rgeo;
- xfs_rgblock_t highest_rgbno;
int error;
if (copy_from_user(&rgeo, arg, sizeof(rgeo)))
@@ -433,28 +452,16 @@ xfs_ioc_rtgroup_geometry(
return -EINVAL;
error = xfs_rtgroup_get_geometry(rtg, &rgeo);
- xfs_rtgroup_put(rtg);
if (error)
- return error;
-
- if (xfs_has_zoned(mp)) {
- xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP);
- if (rtg->rtg_open_zone) {
- rgeo.rg_writepointer = rtg->rtg_open_zone->oz_allocated;
- } else {
- highest_rgbno = xfs_rtrmap_highest_rgbno(rtg);
- if (highest_rgbno == NULLRGBLOCK)
- rgeo.rg_writepointer = 0;
- else
- rgeo.rg_writepointer = highest_rgbno + 1;
- }
- xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_RMAP);
- rgeo.rg_flags |= XFS_RTGROUP_GEOM_WRITEPOINTER;
- }
+ goto out_put_rtg;
+ if (xfs_has_zoned(mp))
+ xfs_rtgroup_report_write_pointer(rtg, &rgeo);
if (copy_to_user(arg, &rgeo, sizeof(rgeo)))
- return -EFAULT;
- return 0;
+ error = -EFAULT;
+out_put_rtg:
+ xfs_rtgroup_put(rtg);
+ return error;
}
/*
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index b24195f570cd..7aa51826b1ca 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1149,9 +1149,12 @@ xfs_mountfs(
* blocks.
*/
error = xfs_fs_reserve_ag_blocks(mp);
- if (error && error == -ENOSPC)
+ if (error) {
+ if (error != -ENOSPC)
+ goto out_rtunmount;
xfs_warn(mp,
- "ENOSPC reserving per-AG metadata pool, log recovery may fail.");
+"ENOSPC reserving per-AG metadata pool, log recovery may fail.");
+ }
error = xfs_log_mount_finish(mp);
xfs_fs_unreserve_ag_blocks(mp);
if (error) {
diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c
index 221e55887a2a..d92993367ab6 100644
--- a/fs/xfs/xfs_pnfs.c
+++ b/fs/xfs/xfs_pnfs.c
@@ -118,7 +118,6 @@ xfs_fs_map_blocks(
struct xfs_bmbt_irec imap;
xfs_fileoff_t offset_fsb, end_fsb;
loff_t limit;
- int bmapi_flags = XFS_BMAPI_ENTIRE;
int nimaps = 1;
uint lock_flags;
int error = 0;
@@ -172,14 +171,18 @@ xfs_fs_map_blocks(
offset_fsb = XFS_B_TO_FSBT(mp, offset);
lock_flags = xfs_ilock_data_map_shared(ip);
+ /* request mappings for the specified range only */
error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb,
- &imap, &nimaps, bmapi_flags);
+ &imap, &nimaps, 0);
+ if (error) {
+ xfs_iunlock(ip, lock_flags);
+ goto out_unlock;
+ }
seq = xfs_iomap_inode_sequence(ip, 0);
ASSERT(!nimaps || imap.br_startblock != DELAYSTARTBLOCK);
- if (!error && write &&
- (!nimaps || imap.br_startblock == HOLESTARTBLOCK)) {
+ if (write && (!nimaps || imap.br_startblock == HOLESTARTBLOCK)) {
if (offset + length > XFS_ISIZE(ip))
end_fsb = xfs_iomap_eof_align_last_fsb(ip, end_fsb);
else if (nimaps && imap.br_startblock == HOLESTARTBLOCK)
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index db23a0f231d6..251dec48f0e3 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -949,16 +949,16 @@ xfs_reflink_end_cow(
* repeatedly cycles the ILOCK to allocate one transaction per remapped
* extent.
*
- * If we're being called by writeback then the pages will still
- * have PageWriteback set, which prevents races with reflink remapping
- * and truncate. Reflink remapping prevents races with writeback by
- * taking the iolock and mmaplock before flushing the pages and
- * remapping, which means there won't be any further writeback or page
- * cache dirtying until the reflink completes.
+ * If we're being called by writeback then the folios will still
+ * have the writeback flag set, which prevents races with reflink
+ * remapping and truncate. Reflink remapping prevents races with
+ * writeback by taking the iolock and mmaplock before flushing
+ * the folios and remapping, which means there won't be any further
+ * writeback or page cache dirtying until the reflink completes.
*
* We should never have two threads issuing writeback for the same file
* region. There are also have post-eof checks in the writeback
- * preparation code so that we don't bother writing out pages that are
+ * preparation code so that we don't bother writing out folios that are
* about to be truncated.
*
* If we're being called as part of directio write completion, the dio
diff --git a/fs/xfs/xfs_zone_gc.c b/fs/xfs/xfs_zone_gc.c
index c8a1d5c0332c..f03211e4354a 100644
--- a/fs/xfs/xfs_zone_gc.c
+++ b/fs/xfs/xfs_zone_gc.c
@@ -400,7 +400,7 @@ retry:
/*
* If the inode was already deleted, skip over it.
*/
- if (error == -ENOENT) {
+ if (error == -ENOENT || error == -EINVAL) {
iter->rec_idx++;
goto retry;
}