162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2016 Oracle. All Rights Reserved. 462306a36Sopenharmony_ci * Author: Darrick J. Wong <darrick.wong@oracle.com> 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci#ifndef __XFS_DEFER_H__ 762306a36Sopenharmony_ci#define __XFS_DEFER_H__ 862306a36Sopenharmony_ci 962306a36Sopenharmony_cistruct xfs_btree_cur; 1062306a36Sopenharmony_cistruct xfs_defer_op_type; 1162306a36Sopenharmony_cistruct xfs_defer_capture; 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci/* 1462306a36Sopenharmony_ci * Header for deferred operation list. 1562306a36Sopenharmony_ci */ 1662306a36Sopenharmony_cienum xfs_defer_ops_type { 1762306a36Sopenharmony_ci XFS_DEFER_OPS_TYPE_BMAP, 1862306a36Sopenharmony_ci XFS_DEFER_OPS_TYPE_REFCOUNT, 1962306a36Sopenharmony_ci XFS_DEFER_OPS_TYPE_RMAP, 2062306a36Sopenharmony_ci XFS_DEFER_OPS_TYPE_FREE, 2162306a36Sopenharmony_ci XFS_DEFER_OPS_TYPE_AGFL_FREE, 2262306a36Sopenharmony_ci XFS_DEFER_OPS_TYPE_ATTR, 2362306a36Sopenharmony_ci XFS_DEFER_OPS_TYPE_MAX, 2462306a36Sopenharmony_ci}; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci/* 2762306a36Sopenharmony_ci * Save a log intent item and a list of extents, so that we can replay 2862306a36Sopenharmony_ci * whatever action had to happen to the extent list and file the log done 2962306a36Sopenharmony_ci * item. 3062306a36Sopenharmony_ci */ 3162306a36Sopenharmony_cistruct xfs_defer_pending { 3262306a36Sopenharmony_ci struct list_head dfp_list; /* pending items */ 3362306a36Sopenharmony_ci struct list_head dfp_work; /* work items */ 3462306a36Sopenharmony_ci struct xfs_log_item *dfp_intent; /* log intent item */ 3562306a36Sopenharmony_ci struct xfs_log_item *dfp_done; /* log done item */ 3662306a36Sopenharmony_ci unsigned int dfp_count; /* # extent items */ 3762306a36Sopenharmony_ci enum xfs_defer_ops_type dfp_type; 3862306a36Sopenharmony_ci}; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_civoid xfs_defer_add(struct xfs_trans *tp, enum xfs_defer_ops_type type, 4162306a36Sopenharmony_ci struct list_head *h); 4262306a36Sopenharmony_ciint xfs_defer_finish_noroll(struct xfs_trans **tp); 4362306a36Sopenharmony_ciint xfs_defer_finish(struct xfs_trans **tp); 4462306a36Sopenharmony_civoid xfs_defer_cancel(struct xfs_trans *); 4562306a36Sopenharmony_civoid xfs_defer_move(struct xfs_trans *dtp, struct xfs_trans *stp); 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci/* Description of a deferred type. */ 4862306a36Sopenharmony_cistruct xfs_defer_op_type { 4962306a36Sopenharmony_ci struct xfs_log_item *(*create_intent)(struct xfs_trans *tp, 5062306a36Sopenharmony_ci struct list_head *items, unsigned int count, bool sort); 5162306a36Sopenharmony_ci void (*abort_intent)(struct xfs_log_item *intent); 5262306a36Sopenharmony_ci struct xfs_log_item *(*create_done)(struct xfs_trans *tp, 5362306a36Sopenharmony_ci struct xfs_log_item *intent, unsigned int count); 5462306a36Sopenharmony_ci int (*finish_item)(struct xfs_trans *tp, struct xfs_log_item *done, 5562306a36Sopenharmony_ci struct list_head *item, struct xfs_btree_cur **state); 5662306a36Sopenharmony_ci void (*finish_cleanup)(struct xfs_trans *tp, 5762306a36Sopenharmony_ci struct xfs_btree_cur *state, int error); 5862306a36Sopenharmony_ci void (*cancel_item)(struct list_head *item); 5962306a36Sopenharmony_ci unsigned int max_items; 6062306a36Sopenharmony_ci}; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ciextern const struct xfs_defer_op_type xfs_bmap_update_defer_type; 6362306a36Sopenharmony_ciextern const struct xfs_defer_op_type xfs_refcount_update_defer_type; 6462306a36Sopenharmony_ciextern const struct xfs_defer_op_type xfs_rmap_update_defer_type; 6562306a36Sopenharmony_ciextern const struct xfs_defer_op_type xfs_extent_free_defer_type; 6662306a36Sopenharmony_ciextern const struct xfs_defer_op_type xfs_agfl_free_defer_type; 6762306a36Sopenharmony_ciextern const struct xfs_defer_op_type xfs_attr_defer_type; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci/* 7162306a36Sopenharmony_ci * Deferred operation item relogging limits. 7262306a36Sopenharmony_ci */ 7362306a36Sopenharmony_ci#define XFS_DEFER_OPS_NR_INODES 2 /* join up to two inodes */ 7462306a36Sopenharmony_ci#define XFS_DEFER_OPS_NR_BUFS 2 /* join up to two buffers */ 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci/* Resources that must be held across a transaction roll. */ 7762306a36Sopenharmony_cistruct xfs_defer_resources { 7862306a36Sopenharmony_ci /* held buffers */ 7962306a36Sopenharmony_ci struct xfs_buf *dr_bp[XFS_DEFER_OPS_NR_BUFS]; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci /* inodes with no unlock flags */ 8262306a36Sopenharmony_ci struct xfs_inode *dr_ip[XFS_DEFER_OPS_NR_INODES]; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci /* number of held buffers */ 8562306a36Sopenharmony_ci unsigned short dr_bufs; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci /* bitmap of ordered buffers */ 8862306a36Sopenharmony_ci unsigned short dr_ordered; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci /* number of held inodes */ 9162306a36Sopenharmony_ci unsigned short dr_inos; 9262306a36Sopenharmony_ci}; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci/* 9562306a36Sopenharmony_ci * This structure enables a dfops user to detach the chain of deferred 9662306a36Sopenharmony_ci * operations from a transaction so that they can be continued later. 9762306a36Sopenharmony_ci */ 9862306a36Sopenharmony_cistruct xfs_defer_capture { 9962306a36Sopenharmony_ci /* List of other capture structures. */ 10062306a36Sopenharmony_ci struct list_head dfc_list; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci /* Deferred ops state saved from the transaction. */ 10362306a36Sopenharmony_ci struct list_head dfc_dfops; 10462306a36Sopenharmony_ci unsigned int dfc_tpflags; 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci /* Block reservations for the data and rt devices. */ 10762306a36Sopenharmony_ci unsigned int dfc_blkres; 10862306a36Sopenharmony_ci unsigned int dfc_rtxres; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci /* Log reservation saved from the transaction. */ 11162306a36Sopenharmony_ci unsigned int dfc_logres; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci struct xfs_defer_resources dfc_held; 11462306a36Sopenharmony_ci}; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci/* 11762306a36Sopenharmony_ci * Functions to capture a chain of deferred operations and continue them later. 11862306a36Sopenharmony_ci * This doesn't normally happen except log recovery. 11962306a36Sopenharmony_ci */ 12062306a36Sopenharmony_ciint xfs_defer_ops_capture_and_commit(struct xfs_trans *tp, 12162306a36Sopenharmony_ci struct list_head *capture_list); 12262306a36Sopenharmony_civoid xfs_defer_ops_continue(struct xfs_defer_capture *d, struct xfs_trans *tp, 12362306a36Sopenharmony_ci struct xfs_defer_resources *dres); 12462306a36Sopenharmony_civoid xfs_defer_ops_capture_abort(struct xfs_mount *mp, 12562306a36Sopenharmony_ci struct xfs_defer_capture *d); 12662306a36Sopenharmony_civoid xfs_defer_resources_rele(struct xfs_defer_resources *dres); 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ciint __init xfs_defer_init_item_caches(void); 12962306a36Sopenharmony_civoid xfs_defer_destroy_item_caches(void); 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci#endif /* __XFS_DEFER_H__ */ 132