Re: [PATCH 1/2] xfs: idiotproof defer op type configuration

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Oct 29, 2018 at 11:25:52AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
> 
> Recently, we forgot to port a new defer op type to xfsprogs, which
> caused us some userspace pain.  Reorganize the way we make libxfs
> clients supply defer op type information so that all type information
> has to be provided at build time instead of risky runtime dynamic
> configuration.
> 

https://youtu.be/Ya2xifdO_l0

> Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
> ---

Reviewed-by: Brian Foster <bfoster@xxxxxxxxxx>

>  fs/xfs/libxfs/xfs_defer.c   |   17 ++++++++---------
>  fs/xfs/libxfs/xfs_defer.h   |    6 +++++-
>  fs/xfs/xfs_super.c          |    6 +-----
>  fs/xfs/xfs_trans.h          |    4 ----
>  fs/xfs/xfs_trans_bmap.c     |   10 ++--------
>  fs/xfs/xfs_trans_extfree.c  |   13 +++----------
>  fs/xfs/xfs_trans_refcount.c |   10 ++--------
>  fs/xfs/xfs_trans_rmap.c     |   10 ++--------
>  8 files changed, 23 insertions(+), 53 deletions(-)
> 
> 
> diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c
> index e792b167150a..277117a8ad13 100644
> --- a/fs/xfs/libxfs/xfs_defer.c
> +++ b/fs/xfs/libxfs/xfs_defer.c
> @@ -172,7 +172,13 @@
>   * reoccur.
>   */
>  
> -static const struct xfs_defer_op_type *defer_op_types[XFS_DEFER_OPS_TYPE_MAX];
> +static const struct xfs_defer_op_type *defer_op_types[] = {
> +	[XFS_DEFER_OPS_TYPE_BMAP]	= &xfs_bmap_update_defer_type,
> +	[XFS_DEFER_OPS_TYPE_REFCOUNT]	= &xfs_refcount_update_defer_type,
> +	[XFS_DEFER_OPS_TYPE_RMAP]	= &xfs_rmap_update_defer_type,
> +	[XFS_DEFER_OPS_TYPE_FREE]	= &xfs_extent_free_defer_type,
> +	[XFS_DEFER_OPS_TYPE_AGFL_FREE]	= &xfs_agfl_free_defer_type,
> +};
>  
>  /*
>   * For each pending item in the intake list, log its intent item and the
> @@ -488,6 +494,7 @@ xfs_defer_add(
>  	struct xfs_defer_pending	*dfp = NULL;
>  
>  	ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
> +	BUILD_BUG_ON(ARRAY_SIZE(defer_op_types) != XFS_DEFER_OPS_TYPE_MAX);
>  
>  	/*
>  	 * Add the item to a pending item at the end of the intake list.
> @@ -517,14 +524,6 @@ xfs_defer_add(
>  	dfp->dfp_count++;
>  }
>  
> -/* Initialize a deferred operation list. */
> -void
> -xfs_defer_init_op_type(
> -	const struct xfs_defer_op_type	*type)
> -{
> -	defer_op_types[type->type] = type;
> -}
> -
>  /*
>   * Move deferred ops from one transaction to another and reset the source to
>   * initial state. This is primarily used to carry state forward across
> diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h
> index 2584a5b95b0d..0a4b88e3df74 100644
> --- a/fs/xfs/libxfs/xfs_defer.h
> +++ b/fs/xfs/libxfs/xfs_defer.h
> @@ -56,6 +56,10 @@ struct xfs_defer_op_type {
>  	void (*log_item)(struct xfs_trans *, void *, struct list_head *);
>  };
>  
> -void xfs_defer_init_op_type(const struct xfs_defer_op_type *type);
> +extern const struct xfs_defer_op_type xfs_bmap_update_defer_type;
> +extern const struct xfs_defer_op_type xfs_refcount_update_defer_type;
> +extern const struct xfs_defer_op_type xfs_rmap_update_defer_type;
> +extern const struct xfs_defer_op_type xfs_extent_free_defer_type;
> +extern const struct xfs_defer_op_type xfs_agfl_free_defer_type;
>  
>  #endif /* __XFS_DEFER_H__ */
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index d3e6cd063688..a2e944b80d2a 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -38,6 +38,7 @@
>  #include "xfs_refcount_item.h"
>  #include "xfs_bmap_item.h"
>  #include "xfs_reflink.h"
> +#include "xfs_defer.h"
>  
>  #include <linux/namei.h>
>  #include <linux/dax.h>
> @@ -2085,11 +2086,6 @@ init_xfs_fs(void)
>  	printk(KERN_INFO XFS_VERSION_STRING " with "
>  			 XFS_BUILD_OPTIONS " enabled\n");
>  
> -	xfs_extent_free_init_defer_op();
> -	xfs_rmap_update_init_defer_op();
> -	xfs_refcount_update_init_defer_op();
> -	xfs_bmap_update_init_defer_op();
> -
>  	xfs_dir_startup();
>  
>  	error = xfs_init_zones();
> diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
> index a0c5dbda18aa..3ba14ebb7a3b 100644
> --- a/fs/xfs/xfs_trans.h
> +++ b/fs/xfs/xfs_trans.h
> @@ -223,7 +223,6 @@ void		xfs_trans_dirty_buf(struct xfs_trans *, struct xfs_buf *);
>  bool		xfs_trans_buf_is_dirty(struct xfs_buf *bp);
>  void		xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint);
>  
> -void		xfs_extent_free_init_defer_op(void);
>  struct xfs_efd_log_item	*xfs_trans_get_efd(struct xfs_trans *,
>  				  struct xfs_efi_log_item *,
>  				  uint);
> @@ -248,7 +247,6 @@ extern kmem_zone_t	*xfs_trans_zone;
>  /* rmap updates */
>  enum xfs_rmap_intent_type;
>  
> -void xfs_rmap_update_init_defer_op(void);
>  struct xfs_rud_log_item *xfs_trans_get_rud(struct xfs_trans *tp,
>  		struct xfs_rui_log_item *ruip);
>  int xfs_trans_log_finish_rmap_update(struct xfs_trans *tp,
> @@ -260,7 +258,6 @@ int xfs_trans_log_finish_rmap_update(struct xfs_trans *tp,
>  /* refcount updates */
>  enum xfs_refcount_intent_type;
>  
> -void xfs_refcount_update_init_defer_op(void);
>  struct xfs_cud_log_item *xfs_trans_get_cud(struct xfs_trans *tp,
>  		struct xfs_cui_log_item *cuip);
>  int xfs_trans_log_finish_refcount_update(struct xfs_trans *tp,
> @@ -272,7 +269,6 @@ int xfs_trans_log_finish_refcount_update(struct xfs_trans *tp,
>  /* mapping updates */
>  enum xfs_bmap_intent_type;
>  
> -void xfs_bmap_update_init_defer_op(void);
>  struct xfs_bud_log_item *xfs_trans_get_bud(struct xfs_trans *tp,
>  		struct xfs_bui_log_item *buip);
>  int xfs_trans_log_finish_bmap_update(struct xfs_trans *tp,
> diff --git a/fs/xfs/xfs_trans_bmap.c b/fs/xfs/xfs_trans_bmap.c
> index 741c558b2179..e027e68b4f9e 100644
> --- a/fs/xfs/xfs_trans_bmap.c
> +++ b/fs/xfs/xfs_trans_bmap.c
> @@ -17,6 +17,7 @@
>  #include "xfs_alloc.h"
>  #include "xfs_bmap.h"
>  #include "xfs_inode.h"
> +#include "xfs_defer.h"
>  
>  /*
>   * This routine is called to allocate a "bmap update done"
> @@ -220,7 +221,7 @@ xfs_bmap_update_cancel_item(
>  	kmem_free(bmap);
>  }
>  
> -static const struct xfs_defer_op_type xfs_bmap_update_defer_type = {
> +const struct xfs_defer_op_type xfs_bmap_update_defer_type = {
>  	.type		= XFS_DEFER_OPS_TYPE_BMAP,
>  	.max_items	= XFS_BUI_MAX_FAST_EXTENTS,
>  	.diff_items	= xfs_bmap_update_diff_items,
> @@ -231,10 +232,3 @@ static const struct xfs_defer_op_type xfs_bmap_update_defer_type = {
>  	.finish_item	= xfs_bmap_update_finish_item,
>  	.cancel_item	= xfs_bmap_update_cancel_item,
>  };
> -
> -/* Register the deferred op type. */
> -void
> -xfs_bmap_update_init_defer_op(void)
> -{
> -	xfs_defer_init_op_type(&xfs_bmap_update_defer_type);
> -}
> diff --git a/fs/xfs/xfs_trans_extfree.c b/fs/xfs/xfs_trans_extfree.c
> index 855c0b651fd4..1872962aa470 100644
> --- a/fs/xfs/xfs_trans_extfree.c
> +++ b/fs/xfs/xfs_trans_extfree.c
> @@ -18,6 +18,7 @@
>  #include "xfs_alloc.h"
>  #include "xfs_bmap.h"
>  #include "xfs_trace.h"
> +#include "xfs_defer.h"
>  
>  /*
>   * This routine is called to allocate an "extent free done"
> @@ -206,7 +207,7 @@ xfs_extent_free_cancel_item(
>  	kmem_free(free);
>  }
>  
> -static const struct xfs_defer_op_type xfs_extent_free_defer_type = {
> +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,
> @@ -274,7 +275,7 @@ xfs_agfl_free_finish_item(
>  
>  
>  /* sub-type with special handling for AGFL deferred frees */
> -static const struct xfs_defer_op_type xfs_agfl_free_defer_type = {
> +const struct xfs_defer_op_type xfs_agfl_free_defer_type = {
>  	.type		= XFS_DEFER_OPS_TYPE_AGFL_FREE,
>  	.max_items	= XFS_EFI_MAX_FAST_EXTENTS,
>  	.diff_items	= xfs_extent_free_diff_items,
> @@ -285,11 +286,3 @@ static const struct xfs_defer_op_type xfs_agfl_free_defer_type = {
>  	.finish_item	= xfs_agfl_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);
> -	xfs_defer_init_op_type(&xfs_agfl_free_defer_type);
> -}
> diff --git a/fs/xfs/xfs_trans_refcount.c b/fs/xfs/xfs_trans_refcount.c
> index 523c55663954..116c040d54bd 100644
> --- a/fs/xfs/xfs_trans_refcount.c
> +++ b/fs/xfs/xfs_trans_refcount.c
> @@ -16,6 +16,7 @@
>  #include "xfs_refcount_item.h"
>  #include "xfs_alloc.h"
>  #include "xfs_refcount.h"
> +#include "xfs_defer.h"
>  
>  /*
>   * This routine is called to allocate a "refcount update done"
> @@ -227,7 +228,7 @@ xfs_refcount_update_cancel_item(
>  	kmem_free(refc);
>  }
>  
> -static const struct xfs_defer_op_type xfs_refcount_update_defer_type = {
> +const struct xfs_defer_op_type xfs_refcount_update_defer_type = {
>  	.type		= XFS_DEFER_OPS_TYPE_REFCOUNT,
>  	.max_items	= XFS_CUI_MAX_FAST_EXTENTS,
>  	.diff_items	= xfs_refcount_update_diff_items,
> @@ -239,10 +240,3 @@ static const struct xfs_defer_op_type xfs_refcount_update_defer_type = {
>  	.finish_cleanup = xfs_refcount_update_finish_cleanup,
>  	.cancel_item	= xfs_refcount_update_cancel_item,
>  };
> -
> -/* Register the deferred op type. */
> -void
> -xfs_refcount_update_init_defer_op(void)
> -{
> -	xfs_defer_init_op_type(&xfs_refcount_update_defer_type);
> -}
> diff --git a/fs/xfs/xfs_trans_rmap.c b/fs/xfs/xfs_trans_rmap.c
> index 05b00e40251f..f75cdc5b578a 100644
> --- a/fs/xfs/xfs_trans_rmap.c
> +++ b/fs/xfs/xfs_trans_rmap.c
> @@ -16,6 +16,7 @@
>  #include "xfs_rmap_item.h"
>  #include "xfs_alloc.h"
>  #include "xfs_rmap.h"
> +#include "xfs_defer.h"
>  
>  /* Set the map extent flags for this reverse mapping. */
>  static void
> @@ -244,7 +245,7 @@ xfs_rmap_update_cancel_item(
>  	kmem_free(rmap);
>  }
>  
> -static const struct xfs_defer_op_type xfs_rmap_update_defer_type = {
> +const struct xfs_defer_op_type xfs_rmap_update_defer_type = {
>  	.type		= XFS_DEFER_OPS_TYPE_RMAP,
>  	.max_items	= XFS_RUI_MAX_FAST_EXTENTS,
>  	.diff_items	= xfs_rmap_update_diff_items,
> @@ -256,10 +257,3 @@ static const struct xfs_defer_op_type xfs_rmap_update_defer_type = {
>  	.finish_cleanup = xfs_rmap_update_finish_cleanup,
>  	.cancel_item	= xfs_rmap_update_cancel_item,
>  };
> -
> -/* Register the deferred op type. */
> -void
> -xfs_rmap_update_init_defer_op(void)
> -{
> -	xfs_defer_init_op_type(&xfs_rmap_update_defer_type);
> -}
> 



[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux