Merge tag 'xfs-fixes-6.15-rc7' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull xfs fixes from Carlos Maiolino:
 "This includes a bug fix for a possible data corruption vector on the
  zoned allocator garbage collector"

* tag 'xfs-fixes-6.15-rc7' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
  xfs: Fix comment on xfs_trans_ail_update_bulk()
  xfs: Fix a comment on xfs_ail_delete
  xfs: Fail remount with noattr2 on a v5 with v4 enabled
  xfs: fix zoned GC data corruption due to wrong bv_offset
  xfs: free up mp->m_free[0].count in error case
This commit is contained in:
Linus Torvalds
2025-05-16 09:51:49 -07:00
3 changed files with 48 additions and 19 deletions
+27 -1
View File
@@ -1149,7 +1149,7 @@ xfs_init_percpu_counters(
return 0;
free_freecounters:
while (--i > 0)
while (--i >= 0)
percpu_counter_destroy(&mp->m_free[i].count);
percpu_counter_destroy(&mp->m_delalloc_rtextents);
free_delalloc:
@@ -2114,6 +2114,21 @@ xfs_fs_reconfigure(
if (error)
return error;
/* attr2 -> noattr2 */
if (xfs_has_noattr2(new_mp)) {
if (xfs_has_crc(mp)) {
xfs_warn(mp,
"attr2 is always enabled for a V5 filesystem - can't be changed.");
return -EINVAL;
}
mp->m_features &= ~XFS_FEAT_ATTR2;
mp->m_features |= XFS_FEAT_NOATTR2;
} else if (xfs_has_attr2(new_mp)) {
/* noattr2 -> attr2 */
mp->m_features &= ~XFS_FEAT_NOATTR2;
mp->m_features |= XFS_FEAT_ATTR2;
}
/* inode32 -> inode64 */
if (xfs_has_small_inums(mp) && !xfs_has_small_inums(new_mp)) {
mp->m_features &= ~XFS_FEAT_SMALL_INUMS;
@@ -2126,6 +2141,17 @@ xfs_fs_reconfigure(
mp->m_maxagi = xfs_set_inode_alloc(mp, mp->m_sb.sb_agcount);
}
/*
* Now that mp has been modified according to the remount options, we
* do a final option validation with xfs_finish_flags() just like it is
* just like it is done during mount. We cannot use
* done during mount. We cannot use xfs_finish_flags() on new_mp as it
* contains only the user given options.
*/
error = xfs_finish_flags(mp);
if (error)
return error;
/* ro -> rw */
if (xfs_is_readonly(mp) && !(flags & SB_RDONLY)) {
error = xfs_remount_rw(mp);
+18 -16
View File
@@ -315,7 +315,7 @@ xfs_ail_splice(
}
/*
* Delete the given item from the AIL. Return a pointer to the item.
* Delete the given item from the AIL.
*/
static void
xfs_ail_delete(
@@ -777,26 +777,28 @@ xfs_ail_update_finish(
}
/*
* xfs_trans_ail_update - bulk AIL insertion operation.
* xfs_trans_ail_update_bulk - bulk AIL insertion operation.
*
* @xfs_trans_ail_update takes an array of log items that all need to be
* @xfs_trans_ail_update_bulk takes an array of log items that all need to be
* positioned at the same LSN in the AIL. If an item is not in the AIL, it will
* be added. Otherwise, it will be repositioned by removing it and re-adding
* it to the AIL. If we move the first item in the AIL, update the log tail to
* match the new minimum LSN in the AIL.
* be added. Otherwise, it will be repositioned by removing it and re-adding
* it to the AIL.
*
* This function takes the AIL lock once to execute the update operations on
* all the items in the array, and as such should not be called with the AIL
* lock held. As a result, once we have the AIL lock, we need to check each log
* item LSN to confirm it needs to be moved forward in the AIL.
* If we move the first item in the AIL, update the log tail to match the new
* minimum LSN in the AIL.
*
* To optimise the insert operation, we delete all the items from the AIL in
* the first pass, moving them into a temporary list, then splice the temporary
* list into the correct position in the AIL. This avoids needing to do an
* insert operation on every item.
* This function should be called with the AIL lock held.
*
* This function must be called with the AIL lock held. The lock is dropped
* before returning.
* To optimise the insert operation, we add all items to a temporary list, then
* splice this list into the correct position in the AIL.
*
* Items that are already in the AIL are first deleted from their current
* location before being added to the temporary list.
*
* This avoids needing to do an insert operation on every item.
*
* The AIL lock is dropped by xfs_ail_update_finish() before returning to
* the caller.
*/
void
xfs_trans_ail_update_bulk(
+3 -2
View File
@@ -807,7 +807,8 @@ xfs_zone_gc_write_chunk(
{
struct xfs_zone_gc_data *data = chunk->data;
struct xfs_mount *mp = chunk->ip->i_mount;
unsigned int folio_offset = chunk->bio.bi_io_vec->bv_offset;
phys_addr_t bvec_paddr =
bvec_phys(bio_first_bvec_all(&chunk->bio));
struct xfs_gc_bio *split_chunk;
if (chunk->bio.bi_status)
@@ -822,7 +823,7 @@ xfs_zone_gc_write_chunk(
bio_reset(&chunk->bio, mp->m_rtdev_targp->bt_bdev, REQ_OP_WRITE);
bio_add_folio_nofail(&chunk->bio, chunk->scratch->folio, chunk->len,
folio_offset);
offset_in_folio(chunk->scratch->folio, bvec_paddr));
while ((split_chunk = xfs_zone_gc_split_write(data, chunk)))
xfs_zone_gc_submit_write(data, split_chunk);