Commit 1524cb28 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents 3c21441e 08c73a4b
Loading
Loading
Loading
Loading
+27 −1
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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.
 * 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
Original line number Diff line number Diff line
@@ -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);