xref: /kernel/linux/linux-6.6/fs/xfs/libxfs/xfs_defer.h (revision 62306a36)
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