Commit 8751b21a authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'xfs-6.12-merge-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull xfs updates from Chandan Babu:
 "New code:

   - Introduce new ioctls to exchange contents of two files.

     The first ioctl does the preparation work to exchange the contents
     of two files while the second ioctl performs the actual exchange if
     the target file has not been changed since a given sampling point.

  Fixes:

   - Fix bugs associated with calculating the maximum range of realtime
     extents to scan for free space.

   - Copy keys instead of records when resizing the incore BMBT root
     block.

   - Do not report FITRIMming more bytes than possibly exist in the
     filesystem.

   - Modify xfs_fs.h to prevent C++ compilation errors.

   - Do not over eagerly free post-EOF speculative preallocation.

   - Ensure st_blocks never goes to zero during COW writes

  Cleanups/refactors:

   - Use Xarray to hold per-AG data instead of a Radix tree.

   - Cleanups to:
      - realtime bitmap
      - inode allocator
      - quota
      - inode rooted btree code"

* tag 'xfs-6.12-merge-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (61 commits)
  xfs: ensure st_blocks never goes to zero during COW writes
  xfs: use xas_for_each_marked in xfs_reclaim_inodes_count
  xfs: convert perag lookup to xarray
  xfs: simplify tagged perag iteration
  xfs: move the tagged perag lookup helpers to xfs_icache.c
  xfs: use kfree_rcu_mightsleep to free the perag structures
  xfs: use LIST_HEAD() to simplify code
  xfs: Remove duplicate xfs_trans_priv.h header
  xfs: remove unnecessary check
  xfs: Use xfs set and clear mp state helpers
  xfs: reclaim speculative preallocations for append only files
  xfs: simplify extent lookup in xfs_can_free_eofblocks
  xfs: check XFS_EOFBLOCKS_RELEASED earlier in xfs_release_eofblocks
  xfs: only free posteof blocks on first close
  xfs: don't free post-EOF blocks on read close
  xfs: skip all of xfs_file_release when shut down
  xfs: don't bother returning errors from xfs_file_release
  xfs: refactor f_op->release handling
  xfs: remove the i_mode check in xfs_release
  xfs: standardize the btree maxrecs function parameters
  ...
parents 4e0373f1 90fa22da
Loading
Loading
Loading
Loading
+9 −85
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ xfs_perag_get(
	struct xfs_perag	*pag;

	rcu_read_lock();
	pag = radix_tree_lookup(&mp->m_perag_tree, agno);
	pag = xa_load(&mp->m_perags, agno);
	if (pag) {
		trace_xfs_perag_get(pag, _RET_IP_);
		ASSERT(atomic_read(&pag->pag_ref) >= 0);
@@ -56,31 +56,6 @@ xfs_perag_get(
	return pag;
}

/*
 * search from @first to find the next perag with the given tag set.
 */
struct xfs_perag *
xfs_perag_get_tag(
	struct xfs_mount	*mp,
	xfs_agnumber_t		first,
	unsigned int		tag)
{
	struct xfs_perag	*pag;
	int			found;

	rcu_read_lock();
	found = radix_tree_gang_lookup_tag(&mp->m_perag_tree,
					(void **)&pag, first, 1, tag);
	if (found <= 0) {
		rcu_read_unlock();
		return NULL;
	}
	trace_xfs_perag_get_tag(pag, _RET_IP_);
	atomic_inc(&pag->pag_ref);
	rcu_read_unlock();
	return pag;
}

/* Get a passive reference to the given perag. */
struct xfs_perag *
xfs_perag_hold(
@@ -117,7 +92,7 @@ xfs_perag_grab(
	struct xfs_perag	*pag;

	rcu_read_lock();
	pag = radix_tree_lookup(&mp->m_perag_tree, agno);
	pag = xa_load(&mp->m_perags, agno);
	if (pag) {
		trace_xfs_perag_grab(pag, _RET_IP_);
		if (!atomic_inc_not_zero(&pag->pag_active_ref))
@@ -127,32 +102,6 @@ xfs_perag_grab(
	return pag;
}

/*
 * search from @first to find the next perag with the given tag set.
 */
struct xfs_perag *
xfs_perag_grab_tag(
	struct xfs_mount	*mp,
	xfs_agnumber_t		first,
	int			tag)
{
	struct xfs_perag	*pag;
	int			found;

	rcu_read_lock();
	found = radix_tree_gang_lookup_tag(&mp->m_perag_tree,
					(void **)&pag, first, 1, tag);
	if (found <= 0) {
		rcu_read_unlock();
		return NULL;
	}
	trace_xfs_perag_grab_tag(pag, _RET_IP_);
	if (!atomic_inc_not_zero(&pag->pag_active_ref))
		pag = NULL;
	rcu_read_unlock();
	return pag;
}

void
xfs_perag_rele(
	struct xfs_perag	*pag)
@@ -235,16 +184,6 @@ xfs_initialize_perag_data(
	return error;
}

STATIC void
__xfs_free_perag(
	struct rcu_head	*head)
{
	struct xfs_perag *pag = container_of(head, struct xfs_perag, rcu_head);

	ASSERT(!delayed_work_pending(&pag->pag_blockgc_work));
	kfree(pag);
}

/*
 * Free up the per-ag resources associated with the mount structure.
 */
@@ -256,9 +195,7 @@ xfs_free_perag(
	xfs_agnumber_t		agno;

	for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
		spin_lock(&mp->m_perag_lock);
		pag = radix_tree_delete(&mp->m_perag_tree, agno);
		spin_unlock(&mp->m_perag_lock);
		pag = xa_erase(&mp->m_perags, agno);
		ASSERT(pag);
		XFS_IS_CORRUPT(pag->pag_mount, atomic_read(&pag->pag_ref) != 0);
		xfs_defer_drain_free(&pag->pag_intents_drain);
@@ -270,7 +207,7 @@ xfs_free_perag(
		xfs_perag_rele(pag);
		XFS_IS_CORRUPT(pag->pag_mount,
				atomic_read(&pag->pag_active_ref) != 0);
		call_rcu(&pag->rcu_head, __xfs_free_perag);
		kfree_rcu_mightsleep(pag);
	}
}

@@ -347,9 +284,7 @@ xfs_free_unused_perag_range(
	xfs_agnumber_t		index;

	for (index = agstart; index < agend; index++) {
		spin_lock(&mp->m_perag_lock);
		pag = radix_tree_delete(&mp->m_perag_tree, index);
		spin_unlock(&mp->m_perag_lock);
		pag = xa_erase(&mp->m_perags, index);
		if (!pag)
			break;
		xfs_buf_cache_destroy(&pag->pag_bcache);
@@ -390,20 +325,11 @@ xfs_initialize_perag(
		pag->pag_agno = index;
		pag->pag_mount = mp;

		error = radix_tree_preload(GFP_KERNEL | __GFP_RETRY_MAYFAIL);
		if (error)
			goto out_free_pag;

		spin_lock(&mp->m_perag_lock);
		if (radix_tree_insert(&mp->m_perag_tree, index, pag)) {
			WARN_ON_ONCE(1);
			spin_unlock(&mp->m_perag_lock);
			radix_tree_preload_end();
			error = -EEXIST;
		error = xa_insert(&mp->m_perags, index, pag, GFP_KERNEL);
		if (error) {
			WARN_ON_ONCE(error == -EBUSY);
			goto out_free_pag;
		}
		spin_unlock(&mp->m_perag_lock);
		radix_tree_preload_end();

#ifdef __KERNEL__
		/* Place kernel structure only init below this point. */
@@ -451,9 +377,7 @@ xfs_initialize_perag(

out_remove_pag:
	xfs_defer_drain_free(&pag->pag_intents_drain);
	spin_lock(&mp->m_perag_lock);
	radix_tree_delete(&mp->m_perag_tree, index);
	spin_unlock(&mp->m_perag_lock);
	pag = xa_erase(&mp->m_perags, index);
out_free_pag:
	kfree(pag);
out_unwind_new_pags:
+0 −14
Original line number Diff line number Diff line
@@ -63,9 +63,6 @@ struct xfs_perag {
	/* Blocks reserved for the reverse mapping btree. */
	struct xfs_ag_resv	pag_rmapbt_resv;

	/* for rcu-safe freeing */
	struct rcu_head	rcu_head;

	/* Precalculated geometry info */
	xfs_agblock_t		block_count;
	xfs_agblock_t		min_block;
@@ -156,15 +153,11 @@ void xfs_free_perag(struct xfs_mount *mp);

/* Passive AG references */
struct xfs_perag *xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno);
struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *mp, xfs_agnumber_t agno,
		unsigned int tag);
struct xfs_perag *xfs_perag_hold(struct xfs_perag *pag);
void xfs_perag_put(struct xfs_perag *pag);

/* Active AG references */
struct xfs_perag *xfs_perag_grab(struct xfs_mount *, xfs_agnumber_t);
struct xfs_perag *xfs_perag_grab_tag(struct xfs_mount *, xfs_agnumber_t,
				   int tag);
void xfs_perag_rele(struct xfs_perag *pag);

/*
@@ -266,13 +259,6 @@ xfs_perag_next(
	(agno) = 0; \
	for_each_perag_from((mp), (agno), (pag))

#define for_each_perag_tag(mp, agno, pag, tag) \
	for ((agno) = 0, (pag) = xfs_perag_grab_tag((mp), 0, (tag)); \
		(pag) != NULL; \
		(agno) = (pag)->pag_agno + 1, \
		xfs_perag_rele(pag), \
		(pag) = xfs_perag_grab_tag((mp), (agno), (tag)))

static inline struct xfs_perag *
xfs_perag_next_wrap(
	struct xfs_perag	*pag,
+3 −3
Original line number Diff line number Diff line
@@ -569,11 +569,11 @@ xfs_allocbt_block_maxrecs(
/*
 * Calculate number of records in an alloc btree block.
 */
int
unsigned int
xfs_allocbt_maxrecs(
	struct xfs_mount	*mp,
	int			blocklen,
	int			leaf)
	unsigned int		blocklen,
	bool			leaf)
{
	blocklen -= XFS_ALLOC_BLOCK_LEN(mp);
	return xfs_allocbt_block_maxrecs(blocklen, leaf);
+2 −1
Original line number Diff line number Diff line
@@ -53,7 +53,8 @@ struct xfs_btree_cur *xfs_bnobt_init_cursor(struct xfs_mount *mp,
struct xfs_btree_cur *xfs_cntbt_init_cursor(struct xfs_mount *mp,
		struct xfs_trans *tp, struct xfs_buf *bp,
		struct xfs_perag *pag);
extern int xfs_allocbt_maxrecs(struct xfs_mount *, int, int);
unsigned int xfs_allocbt_maxrecs(struct xfs_mount *mp, unsigned int blocklen,
		bool leaf);
extern xfs_extlen_t xfs_allocbt_calc_size(struct xfs_mount *mp,
		unsigned long long len);

+4 −4
Original line number Diff line number Diff line
@@ -686,7 +686,7 @@ xfs_attr_shortform_bytesfit(
		 */
		if (!dp->i_forkoff && dp->i_df.if_bytes >
		    xfs_default_attroffset(dp))
			dsize = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
			dsize = xfs_bmdr_space_calc(MINDBTPTRS);
		break;
	case XFS_DINODE_FMT_BTREE:
		/*
@@ -700,7 +700,7 @@ xfs_attr_shortform_bytesfit(
				return 0;
			return dp->i_forkoff;
		}
		dsize = XFS_BMAP_BROOT_SPACE(mp, dp->i_df.if_broot);
		dsize = xfs_bmap_bmdr_space(dp->i_df.if_broot);
		break;
	}

@@ -708,11 +708,11 @@ xfs_attr_shortform_bytesfit(
	 * A data fork btree root must have space for at least
	 * MINDBTPTRS key/ptr pairs if the data fork is small or empty.
	 */
	minforkoff = max_t(int64_t, dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS));
	minforkoff = max_t(int64_t, dsize, xfs_bmdr_space_calc(MINDBTPTRS));
	minforkoff = roundup(minforkoff, 8) >> 3;

	/* attr fork btree root can have at least this many key/ptr pairs */
	maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS);
	maxforkoff = XFS_LITINO(mp) - xfs_bmdr_space_calc(MINABTPTRS);
	maxforkoff = maxforkoff >> 3;	/* rounded down */

	if (offset >= maxforkoff)
Loading