Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9749fee8 authored by Darrick J. Wong's avatar Darrick J. Wong Committed by Dave Chinner
Browse files

xfs: enable the xfs_defer mechanism to process extents to free



Connect the xfs_defer mechanism with the pieces that we'll need to
handle deferred extent freeing.  We'll wire up the existing code to
our new deferred mechanism later.

Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
parent bba61cbf
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ struct xfs_defer_pending {
 * find all the space it needs.
 */
enum xfs_defer_ops_type {
	XFS_DEFER_OPS_TYPE_FREE,
	XFS_DEFER_OPS_TYPE_MAX,
};

+2 −0
Original line number Diff line number Diff line
@@ -1854,6 +1854,8 @@ init_xfs_fs(void)
	printk(KERN_INFO XFS_VERSION_STRING " with "
			 XFS_BUILD_OPTIONS " enabled\n");

	xfs_extent_free_init_defer_op();

	xfs_dir_startup();

	error = xfs_init_zones();
+2 −0
Original line number Diff line number Diff line
@@ -210,6 +210,8 @@ void xfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int);
void		xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *, uint);
void		xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint);
void		xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint);

void		xfs_extent_free_init_defer_op(void);
struct xfs_efi_log_item	*xfs_trans_get_efi(struct xfs_trans *, uint);
void		xfs_trans_log_efi_extent(struct xfs_trans *,
					 struct xfs_efi_log_item *,
+110 −0
Original line number Diff line number Diff line
@@ -22,10 +22,12 @@
#include "xfs_log_format.h"
#include "xfs_trans_resv.h"
#include "xfs_mount.h"
#include "xfs_defer.h"
#include "xfs_trans.h"
#include "xfs_trans_priv.h"
#include "xfs_extfree_item.h"
#include "xfs_alloc.h"
#include "xfs_bmap.h"

/*
 * This routine is called to allocate an "extent free intention"
@@ -145,3 +147,111 @@ xfs_trans_free_extent(

	return error;
}

/* Sort bmap items by AG. */
static int
xfs_extent_free_diff_items(
	void				*priv,
	struct list_head		*a,
	struct list_head		*b)
{
	struct xfs_mount		*mp = priv;
	struct xfs_bmap_free_item	*ra;
	struct xfs_bmap_free_item	*rb;

	ra = container_of(a, struct xfs_bmap_free_item, xbfi_list);
	rb = container_of(b, struct xfs_bmap_free_item, xbfi_list);
	return  XFS_FSB_TO_AGNO(mp, ra->xbfi_startblock) -
		XFS_FSB_TO_AGNO(mp, rb->xbfi_startblock);
}

/* Get an EFI. */
STATIC void *
xfs_extent_free_create_intent(
	struct xfs_trans		*tp,
	unsigned int			count)
{
	return xfs_trans_get_efi(tp, count);
}

/* Log a free extent to the intent item. */
STATIC void
xfs_extent_free_log_item(
	struct xfs_trans		*tp,
	void				*intent,
	struct list_head		*item)
{
	struct xfs_bmap_free_item	*free;

	free = container_of(item, struct xfs_bmap_free_item, xbfi_list);
	xfs_trans_log_efi_extent(tp, intent, free->xbfi_startblock,
			free->xbfi_blockcount);
}

/* Get an EFD so we can process all the free extents. */
STATIC void *
xfs_extent_free_create_done(
	struct xfs_trans		*tp,
	void				*intent,
	unsigned int			count)
{
	return xfs_trans_get_efd(tp, intent, count);
}

/* Process a free extent. */
STATIC int
xfs_extent_free_finish_item(
	struct xfs_trans		*tp,
	struct xfs_defer_ops		*dop,
	struct list_head		*item,
	void				*done_item,
	void				**state)
{
	struct xfs_bmap_free_item	*free;
	int				error;

	free = container_of(item, struct xfs_bmap_free_item, xbfi_list);
	error = xfs_trans_free_extent(tp, done_item,
			free->xbfi_startblock,
			free->xbfi_blockcount);
	kmem_free(free);
	return error;
}

/* Abort all pending EFIs. */
STATIC void
xfs_extent_free_abort_intent(
	void				*intent)
{
	xfs_efi_release(intent);
}

/* Cancel a free extent. */
STATIC void
xfs_extent_free_cancel_item(
	struct list_head		*item)
{
	struct xfs_bmap_free_item	*free;

	free = container_of(item, struct xfs_bmap_free_item, xbfi_list);
	kmem_free(free);
}

static const struct xfs_defer_op_type xfs_extent_free_defer_type = {
	.type		= XFS_DEFER_OPS_TYPE_FREE,
	.max_items	= XFS_EFI_MAX_FAST_EXTENTS,
	.diff_items	= xfs_extent_free_diff_items,
	.create_intent	= xfs_extent_free_create_intent,
	.abort_intent	= xfs_extent_free_abort_intent,
	.log_item	= xfs_extent_free_log_item,
	.create_done	= xfs_extent_free_create_done,
	.finish_item	= xfs_extent_free_finish_item,
	.cancel_item	= xfs_extent_free_cancel_item,
};

/* Register the deferred op type. */
void
xfs_extent_free_init_defer_op(void)
{
	xfs_defer_init_op_type(&xfs_extent_free_defer_type);
}