mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
xfs: streamline defer op type handling
There's no need to bundle a pointer to the defer op type into the defer op control structure. Instead, store the defer op type enum, which enables us to shorten some of the lines. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Eric Sandeen <sandeen@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com>
This commit is contained in:
parent
bc9f2b7c8a
commit
02b100fb83
@ -191,15 +191,15 @@ xfs_defer_create_intents(
|
|||||||
{
|
{
|
||||||
struct list_head *li;
|
struct list_head *li;
|
||||||
struct xfs_defer_pending *dfp;
|
struct xfs_defer_pending *dfp;
|
||||||
|
const struct xfs_defer_op_type *ops;
|
||||||
|
|
||||||
list_for_each_entry(dfp, &tp->t_dfops, dfp_list) {
|
list_for_each_entry(dfp, &tp->t_dfops, dfp_list) {
|
||||||
dfp->dfp_intent = dfp->dfp_type->create_intent(tp,
|
ops = defer_op_types[dfp->dfp_type];
|
||||||
dfp->dfp_count);
|
dfp->dfp_intent = ops->create_intent(tp, dfp->dfp_count);
|
||||||
trace_xfs_defer_create_intent(tp->t_mountp, dfp);
|
trace_xfs_defer_create_intent(tp->t_mountp, dfp);
|
||||||
list_sort(tp->t_mountp, &dfp->dfp_work,
|
list_sort(tp->t_mountp, &dfp->dfp_work, ops->diff_items);
|
||||||
dfp->dfp_type->diff_items);
|
|
||||||
list_for_each(li, &dfp->dfp_work)
|
list_for_each(li, &dfp->dfp_work)
|
||||||
dfp->dfp_type->log_item(tp, dfp->dfp_intent, li);
|
ops->log_item(tp, dfp->dfp_intent, li);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,14 +210,16 @@ xfs_defer_trans_abort(
|
|||||||
struct list_head *dop_pending)
|
struct list_head *dop_pending)
|
||||||
{
|
{
|
||||||
struct xfs_defer_pending *dfp;
|
struct xfs_defer_pending *dfp;
|
||||||
|
const struct xfs_defer_op_type *ops;
|
||||||
|
|
||||||
trace_xfs_defer_trans_abort(tp, _RET_IP_);
|
trace_xfs_defer_trans_abort(tp, _RET_IP_);
|
||||||
|
|
||||||
/* Abort intent items that don't have a done item. */
|
/* Abort intent items that don't have a done item. */
|
||||||
list_for_each_entry(dfp, dop_pending, dfp_list) {
|
list_for_each_entry(dfp, dop_pending, dfp_list) {
|
||||||
|
ops = defer_op_types[dfp->dfp_type];
|
||||||
trace_xfs_defer_pending_abort(tp->t_mountp, dfp);
|
trace_xfs_defer_pending_abort(tp->t_mountp, dfp);
|
||||||
if (dfp->dfp_intent && !dfp->dfp_done) {
|
if (dfp->dfp_intent && !dfp->dfp_done) {
|
||||||
dfp->dfp_type->abort_intent(dfp->dfp_intent);
|
ops->abort_intent(dfp->dfp_intent);
|
||||||
dfp->dfp_intent = NULL;
|
dfp->dfp_intent = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -321,18 +323,20 @@ xfs_defer_cancel_list(
|
|||||||
struct xfs_defer_pending *pli;
|
struct xfs_defer_pending *pli;
|
||||||
struct list_head *pwi;
|
struct list_head *pwi;
|
||||||
struct list_head *n;
|
struct list_head *n;
|
||||||
|
const struct xfs_defer_op_type *ops;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Free the pending items. Caller should already have arranged
|
* Free the pending items. Caller should already have arranged
|
||||||
* for the intent items to be released.
|
* for the intent items to be released.
|
||||||
*/
|
*/
|
||||||
list_for_each_entry_safe(dfp, pli, dop_list, dfp_list) {
|
list_for_each_entry_safe(dfp, pli, dop_list, dfp_list) {
|
||||||
|
ops = defer_op_types[dfp->dfp_type];
|
||||||
trace_xfs_defer_cancel_list(mp, dfp);
|
trace_xfs_defer_cancel_list(mp, dfp);
|
||||||
list_del(&dfp->dfp_list);
|
list_del(&dfp->dfp_list);
|
||||||
list_for_each_safe(pwi, n, &dfp->dfp_work) {
|
list_for_each_safe(pwi, n, &dfp->dfp_work) {
|
||||||
list_del(pwi);
|
list_del(pwi);
|
||||||
dfp->dfp_count--;
|
dfp->dfp_count--;
|
||||||
dfp->dfp_type->cancel_item(pwi);
|
ops->cancel_item(pwi);
|
||||||
}
|
}
|
||||||
ASSERT(dfp->dfp_count == 0);
|
ASSERT(dfp->dfp_count == 0);
|
||||||
kmem_free(dfp);
|
kmem_free(dfp);
|
||||||
@ -356,7 +360,7 @@ xfs_defer_finish_noroll(
|
|||||||
struct list_head *n;
|
struct list_head *n;
|
||||||
void *state;
|
void *state;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
void (*cleanup_fn)(struct xfs_trans *, void *, int);
|
const struct xfs_defer_op_type *ops;
|
||||||
LIST_HEAD(dop_pending);
|
LIST_HEAD(dop_pending);
|
||||||
|
|
||||||
ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES);
|
ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES);
|
||||||
@ -379,18 +383,18 @@ xfs_defer_finish_noroll(
|
|||||||
/* Log an intent-done item for the first pending item. */
|
/* Log an intent-done item for the first pending item. */
|
||||||
dfp = list_first_entry(&dop_pending, struct xfs_defer_pending,
|
dfp = list_first_entry(&dop_pending, struct xfs_defer_pending,
|
||||||
dfp_list);
|
dfp_list);
|
||||||
|
ops = defer_op_types[dfp->dfp_type];
|
||||||
trace_xfs_defer_pending_finish((*tp)->t_mountp, dfp);
|
trace_xfs_defer_pending_finish((*tp)->t_mountp, dfp);
|
||||||
dfp->dfp_done = dfp->dfp_type->create_done(*tp, dfp->dfp_intent,
|
dfp->dfp_done = ops->create_done(*tp, dfp->dfp_intent,
|
||||||
dfp->dfp_count);
|
dfp->dfp_count);
|
||||||
cleanup_fn = dfp->dfp_type->finish_cleanup;
|
|
||||||
|
|
||||||
/* Finish the work items. */
|
/* Finish the work items. */
|
||||||
state = NULL;
|
state = NULL;
|
||||||
list_for_each_safe(li, n, &dfp->dfp_work) {
|
list_for_each_safe(li, n, &dfp->dfp_work) {
|
||||||
list_del(li);
|
list_del(li);
|
||||||
dfp->dfp_count--;
|
dfp->dfp_count--;
|
||||||
error = dfp->dfp_type->finish_item(*tp, li,
|
error = ops->finish_item(*tp, li, dfp->dfp_done,
|
||||||
dfp->dfp_done, &state);
|
&state);
|
||||||
if (error == -EAGAIN) {
|
if (error == -EAGAIN) {
|
||||||
/*
|
/*
|
||||||
* Caller wants a fresh transaction;
|
* Caller wants a fresh transaction;
|
||||||
@ -406,8 +410,8 @@ xfs_defer_finish_noroll(
|
|||||||
* xfs_defer_cancel will take care of freeing
|
* xfs_defer_cancel will take care of freeing
|
||||||
* all these lists and stuff.
|
* all these lists and stuff.
|
||||||
*/
|
*/
|
||||||
if (cleanup_fn)
|
if (ops->finish_cleanup)
|
||||||
cleanup_fn(*tp, state, error);
|
ops->finish_cleanup(*tp, state, error);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -419,20 +423,19 @@ xfs_defer_finish_noroll(
|
|||||||
* a Fresh Transaction while Finishing
|
* a Fresh Transaction while Finishing
|
||||||
* Deferred Work" above.
|
* Deferred Work" above.
|
||||||
*/
|
*/
|
||||||
dfp->dfp_intent = dfp->dfp_type->create_intent(*tp,
|
dfp->dfp_intent = ops->create_intent(*tp,
|
||||||
dfp->dfp_count);
|
dfp->dfp_count);
|
||||||
dfp->dfp_done = NULL;
|
dfp->dfp_done = NULL;
|
||||||
list_for_each(li, &dfp->dfp_work)
|
list_for_each(li, &dfp->dfp_work)
|
||||||
dfp->dfp_type->log_item(*tp, dfp->dfp_intent,
|
ops->log_item(*tp, dfp->dfp_intent, li);
|
||||||
li);
|
|
||||||
} else {
|
} else {
|
||||||
/* Done with the dfp, free it. */
|
/* Done with the dfp, free it. */
|
||||||
list_del(&dfp->dfp_list);
|
list_del(&dfp->dfp_list);
|
||||||
kmem_free(dfp);
|
kmem_free(dfp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cleanup_fn)
|
if (ops->finish_cleanup)
|
||||||
cleanup_fn(*tp, state, error);
|
ops->finish_cleanup(*tp, state, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@ -492,6 +495,7 @@ xfs_defer_add(
|
|||||||
struct list_head *li)
|
struct list_head *li)
|
||||||
{
|
{
|
||||||
struct xfs_defer_pending *dfp = NULL;
|
struct xfs_defer_pending *dfp = NULL;
|
||||||
|
const struct xfs_defer_op_type *ops;
|
||||||
|
|
||||||
ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
|
ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
|
||||||
BUILD_BUG_ON(ARRAY_SIZE(defer_op_types) != XFS_DEFER_OPS_TYPE_MAX);
|
BUILD_BUG_ON(ARRAY_SIZE(defer_op_types) != XFS_DEFER_OPS_TYPE_MAX);
|
||||||
@ -504,15 +508,15 @@ xfs_defer_add(
|
|||||||
if (!list_empty(&tp->t_dfops)) {
|
if (!list_empty(&tp->t_dfops)) {
|
||||||
dfp = list_last_entry(&tp->t_dfops,
|
dfp = list_last_entry(&tp->t_dfops,
|
||||||
struct xfs_defer_pending, dfp_list);
|
struct xfs_defer_pending, dfp_list);
|
||||||
if (dfp->dfp_type->type != type ||
|
ops = defer_op_types[dfp->dfp_type];
|
||||||
(dfp->dfp_type->max_items &&
|
if (dfp->dfp_type != type ||
|
||||||
dfp->dfp_count >= dfp->dfp_type->max_items))
|
(ops->max_items && dfp->dfp_count >= ops->max_items))
|
||||||
dfp = NULL;
|
dfp = NULL;
|
||||||
}
|
}
|
||||||
if (!dfp) {
|
if (!dfp) {
|
||||||
dfp = kmem_alloc(sizeof(struct xfs_defer_pending),
|
dfp = kmem_alloc(sizeof(struct xfs_defer_pending),
|
||||||
KM_SLEEP | KM_NOFS);
|
KM_SLEEP | KM_NOFS);
|
||||||
dfp->dfp_type = defer_op_types[type];
|
dfp->dfp_type = type;
|
||||||
dfp->dfp_intent = NULL;
|
dfp->dfp_intent = NULL;
|
||||||
dfp->dfp_done = NULL;
|
dfp->dfp_done = NULL;
|
||||||
dfp->dfp_count = 0;
|
dfp->dfp_count = 0;
|
||||||
|
@ -8,20 +8,6 @@
|
|||||||
|
|
||||||
struct xfs_defer_op_type;
|
struct xfs_defer_op_type;
|
||||||
|
|
||||||
/*
|
|
||||||
* Save a log intent item and a list of extents, so that we can replay
|
|
||||||
* whatever action had to happen to the extent list and file the log done
|
|
||||||
* item.
|
|
||||||
*/
|
|
||||||
struct xfs_defer_pending {
|
|
||||||
const struct xfs_defer_op_type *dfp_type; /* function pointers */
|
|
||||||
struct list_head dfp_list; /* pending items */
|
|
||||||
void *dfp_intent; /* log intent item */
|
|
||||||
void *dfp_done; /* log done item */
|
|
||||||
struct list_head dfp_work; /* work items */
|
|
||||||
unsigned int dfp_count; /* # extent items */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Header for deferred operation list.
|
* Header for deferred operation list.
|
||||||
*/
|
*/
|
||||||
@ -34,6 +20,20 @@ enum xfs_defer_ops_type {
|
|||||||
XFS_DEFER_OPS_TYPE_MAX,
|
XFS_DEFER_OPS_TYPE_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save a log intent item and a list of extents, so that we can replay
|
||||||
|
* whatever action had to happen to the extent list and file the log done
|
||||||
|
* item.
|
||||||
|
*/
|
||||||
|
struct xfs_defer_pending {
|
||||||
|
struct list_head dfp_list; /* pending items */
|
||||||
|
struct list_head dfp_work; /* work items */
|
||||||
|
void *dfp_intent; /* log intent item */
|
||||||
|
void *dfp_done; /* log done item */
|
||||||
|
unsigned int dfp_count; /* # extent items */
|
||||||
|
enum xfs_defer_ops_type dfp_type;
|
||||||
|
};
|
||||||
|
|
||||||
void xfs_defer_add(struct xfs_trans *tp, enum xfs_defer_ops_type type,
|
void xfs_defer_add(struct xfs_trans *tp, enum xfs_defer_ops_type type,
|
||||||
struct list_head *h);
|
struct list_head *h);
|
||||||
int xfs_defer_finish_noroll(struct xfs_trans **tp);
|
int xfs_defer_finish_noroll(struct xfs_trans **tp);
|
||||||
@ -43,8 +43,6 @@ void xfs_defer_move(struct xfs_trans *dtp, struct xfs_trans *stp);
|
|||||||
|
|
||||||
/* Description of a deferred type. */
|
/* Description of a deferred type. */
|
||||||
struct xfs_defer_op_type {
|
struct xfs_defer_op_type {
|
||||||
enum xfs_defer_ops_type type;
|
|
||||||
unsigned int max_items;
|
|
||||||
void (*abort_intent)(void *);
|
void (*abort_intent)(void *);
|
||||||
void *(*create_done)(struct xfs_trans *, void *, unsigned int);
|
void *(*create_done)(struct xfs_trans *, void *, unsigned int);
|
||||||
int (*finish_item)(struct xfs_trans *, struct list_head *, void *,
|
int (*finish_item)(struct xfs_trans *, struct list_head *, void *,
|
||||||
@ -54,6 +52,7 @@ struct xfs_defer_op_type {
|
|||||||
int (*diff_items)(void *, struct list_head *, struct list_head *);
|
int (*diff_items)(void *, struct list_head *, struct list_head *);
|
||||||
void *(*create_intent)(struct xfs_trans *, uint);
|
void *(*create_intent)(struct xfs_trans *, uint);
|
||||||
void (*log_item)(struct xfs_trans *, void *, struct list_head *);
|
void (*log_item)(struct xfs_trans *, void *, struct list_head *);
|
||||||
|
unsigned int max_items;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct xfs_defer_op_type xfs_bmap_update_defer_type;
|
extern const struct xfs_defer_op_type xfs_bmap_update_defer_type;
|
||||||
|
@ -2276,7 +2276,7 @@ DECLARE_EVENT_CLASS(xfs_defer_pending_class,
|
|||||||
),
|
),
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
__entry->dev = mp ? mp->m_super->s_dev : 0;
|
__entry->dev = mp ? mp->m_super->s_dev : 0;
|
||||||
__entry->type = dfp->dfp_type->type;
|
__entry->type = dfp->dfp_type;
|
||||||
__entry->intent = dfp->dfp_intent;
|
__entry->intent = dfp->dfp_intent;
|
||||||
__entry->committed = dfp->dfp_done != NULL;
|
__entry->committed = dfp->dfp_done != NULL;
|
||||||
__entry->nr = dfp->dfp_count;
|
__entry->nr = dfp->dfp_count;
|
||||||
|
@ -222,7 +222,6 @@ xfs_bmap_update_cancel_item(
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
.max_items = XFS_BUI_MAX_FAST_EXTENTS,
|
||||||
.diff_items = xfs_bmap_update_diff_items,
|
.diff_items = xfs_bmap_update_diff_items,
|
||||||
.create_intent = xfs_bmap_update_create_intent,
|
.create_intent = xfs_bmap_update_create_intent,
|
||||||
|
@ -208,7 +208,6 @@ xfs_extent_free_cancel_item(
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
.max_items = XFS_EFI_MAX_FAST_EXTENTS,
|
||||||
.diff_items = xfs_extent_free_diff_items,
|
.diff_items = xfs_extent_free_diff_items,
|
||||||
.create_intent = xfs_extent_free_create_intent,
|
.create_intent = xfs_extent_free_create_intent,
|
||||||
@ -276,7 +275,6 @@ xfs_agfl_free_finish_item(
|
|||||||
|
|
||||||
/* sub-type with special handling for AGFL deferred frees */
|
/* sub-type with special handling for AGFL deferred frees */
|
||||||
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,
|
.max_items = XFS_EFI_MAX_FAST_EXTENTS,
|
||||||
.diff_items = xfs_extent_free_diff_items,
|
.diff_items = xfs_extent_free_diff_items,
|
||||||
.create_intent = xfs_extent_free_create_intent,
|
.create_intent = xfs_extent_free_create_intent,
|
||||||
|
@ -229,7 +229,6 @@ xfs_refcount_update_cancel_item(
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
.max_items = XFS_CUI_MAX_FAST_EXTENTS,
|
||||||
.diff_items = xfs_refcount_update_diff_items,
|
.diff_items = xfs_refcount_update_diff_items,
|
||||||
.create_intent = xfs_refcount_update_create_intent,
|
.create_intent = xfs_refcount_update_create_intent,
|
||||||
|
@ -246,7 +246,6 @@ xfs_rmap_update_cancel_item(
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
.max_items = XFS_RUI_MAX_FAST_EXTENTS,
|
||||||
.diff_items = xfs_rmap_update_diff_items,
|
.diff_items = xfs_rmap_update_diff_items,
|
||||||
.create_intent = xfs_rmap_update_create_intent,
|
.create_intent = xfs_rmap_update_create_intent,
|
||||||
|
Loading…
Reference in New Issue
Block a user