Re: [PATCH 018/119] xfs: enable the xfs_defer mechanism to process extents to free
From: Brian Foster <hidden>
Date: 2016-06-28 12:32:40
Also in:
linux-fsdevel
On Mon, Jun 27, 2016 at 03:00:03PM -0700, Darrick J. Wong wrote:
On Mon, Jun 27, 2016 at 02:41:45PM -0700, Darrick J. Wong wrote:quoted
On Mon, Jun 27, 2016 at 09:15:08AM -0400, Brian Foster wrote:quoted
On Thu, Jun 16, 2016 at 06:19:47PM -0700, Darrick J. Wong wrote:quoted
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: Darrick J. Wong <redacted> ---Could we merge this with the xfs_trans_*efi/efd* bits? We'd need to preserve some calls for recovery, but it looks like other parts are only used by the deferred ops infrastructure at this point.Yes, we could replace xfs_bmap_free_create_{intent,done} with xfs_trans_get_ef[id] and lose the silly functions. I'll go take care of all of them.Hah, gcc complains about the mismatch in pointer types for the second argument. fs/xfs/xfs_defer_item.c:504:17: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types] .create_done = xfs_trans_get_bud, ^ fs/xfs/xfs_defer_item.c:504:17: note: (near initialization for ‘xfs_bmap_update_defer_type.create_done’) I guess one could put in an ugly cast to coerce the types at a cost of uglifying the code. <shrug> Opinions?
Not sure what you mean here... I should be more clear. What I was thinking is to nuke xfs_defer_item.c, define the 'const struct xfs_defer_op_type xfs_extent_free_defer_type' right in xfs_trans_extfree.c (perhaps rename the file) and wire up the functions appropriately. Just change the function signatures if you need to. For something like xfs_trans_get_efd(), maybe refactor the guts into a static helper that both the defer callback and xfs_trans_get_efd() can use, since we need the latter for log recovery. Will something like that work? To put it simply, it looks like we have at least a few places where defer item has a callback that calls yet another interface, but is the only caller of the latter (e.g., xfs_bmap_free_create_intent()->xfs_trans_get_efi()). Brian
--Dquoted
--Dquoted
Brianquoted
fs/xfs/libxfs/xfs_defer.h | 1 fs/xfs/xfs_defer_item.c | 108 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+)diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index 85c7a3a..743fc32 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h@@ -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, };diff --git a/fs/xfs/xfs_defer_item.c b/fs/xfs/xfs_defer_item.c index 4c2ba28..127a54e 100644 --- a/fs/xfs/xfs_defer_item.c +++ b/fs/xfs/xfs_defer_item.c@@ -29,9 +29,117 @@ #include "xfs_defer.h" #include "xfs_trans.h" #include "xfs_trace.h" +#include "xfs_bmap.h" +#include "xfs_extfree_item.h" + +/* Extent Freeing */ + +/* Sort bmap items by AG. */ +static int +xfs_bmap_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_bmap_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_bmap_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_bmap_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_bmap_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_bmap_free_abort_intent( + void *intent) +{ + xfs_efi_release(intent); +} + +/* Cancel a free extent. */ +STATIC void +xfs_bmap_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); +} + +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_bmap_free_diff_items, + .create_intent = xfs_bmap_free_create_intent, + .abort_intent = xfs_bmap_free_abort_intent, + .log_item = xfs_bmap_free_log_item, + .create_done = xfs_bmap_free_create_done, + .finish_item = xfs_bmap_free_finish_item, + .cancel_item = xfs_bmap_free_cancel_item, +}; + +/* Deferred Item Initialization */ /* Initialize the deferred operation types. */ void xfs_defer_init_types(void) { + xfs_defer_init_op_type(&xfs_extent_free_defer_type); }_______________________________________________ xfs mailing list xfs@oss.sgi.com http://oss.sgi.com/mailman/listinfo/xfs_______________________________________________ xfs mailing list xfs@oss.sgi.com http://oss.sgi.com/mailman/listinfo/xfs_______________________________________________ xfs mailing list xfs@oss.sgi.com http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________ xfs mailing list xfs@oss.sgi.com http://oss.sgi.com/mailman/listinfo/xfs