xref: /openbmc/linux/fs/xfs/libxfs/xfs_log_recover.h (revision 46eeaa11bdd1bc9e077bdf741d32ca7235d263c6)
10b61f8a4SDave Chinner // SPDX-License-Identifier: GPL-2.0
284be0ffcSDave Chinner /*
384be0ffcSDave Chinner  * Copyright (c) 2000,2005 Silicon Graphics, Inc.
484be0ffcSDave Chinner  * All Rights Reserved.
584be0ffcSDave Chinner  */
684be0ffcSDave Chinner #ifndef	__XFS_LOG_RECOVER_H__
784be0ffcSDave Chinner #define __XFS_LOG_RECOVER_H__
884be0ffcSDave Chinner 
984be0ffcSDave Chinner /*
1086ffa471SDarrick J. Wong  * Each log item type (XFS_LI_*) gets its own xlog_recover_item_ops to
1186ffa471SDarrick J. Wong  * define how recovery should work for that type of log item.
1286ffa471SDarrick J. Wong  */
1386ffa471SDarrick J. Wong struct xlog_recover_item;
1486ffa471SDarrick J. Wong 
1586ffa471SDarrick J. Wong /* Sorting hat for log items as they're read in. */
1686ffa471SDarrick J. Wong enum xlog_recover_reorder {
1786ffa471SDarrick J. Wong 	XLOG_REORDER_BUFFER_LIST,
1886ffa471SDarrick J. Wong 	XLOG_REORDER_ITEM_LIST,
1986ffa471SDarrick J. Wong 	XLOG_REORDER_INODE_BUFFER_LIST,
2086ffa471SDarrick J. Wong 	XLOG_REORDER_CANCEL_LIST,
2186ffa471SDarrick J. Wong };
2286ffa471SDarrick J. Wong 
2386ffa471SDarrick J. Wong struct xlog_recover_item_ops {
2486ffa471SDarrick J. Wong 	uint16_t	item_type;	/* XFS_LI_* type code. */
2586ffa471SDarrick J. Wong 
2686ffa471SDarrick J. Wong 	/*
2786ffa471SDarrick J. Wong 	 * Help sort recovered log items into the order required to replay them
2886ffa471SDarrick J. Wong 	 * correctly.  Log item types that always use XLOG_REORDER_ITEM_LIST do
2986ffa471SDarrick J. Wong 	 * not have to supply a function here.  See the comment preceding
3086ffa471SDarrick J. Wong 	 * xlog_recover_reorder_trans for more details about what the return
3186ffa471SDarrick J. Wong 	 * values mean.
3286ffa471SDarrick J. Wong 	 */
3386ffa471SDarrick J. Wong 	enum xlog_recover_reorder (*reorder)(struct xlog_recover_item *item);
348ea5682dSDarrick J. Wong 
358ea5682dSDarrick J. Wong 	/* Start readahead for pass2, if provided. */
368ea5682dSDarrick J. Wong 	void (*ra_pass2)(struct xlog *log, struct xlog_recover_item *item);
373304a4faSDarrick J. Wong 
383304a4faSDarrick J. Wong 	/* Do whatever work we need to do for pass1, if provided. */
393304a4faSDarrick J. Wong 	int (*commit_pass1)(struct xlog *log, struct xlog_recover_item *item);
401094d3f1SDarrick J. Wong 
411094d3f1SDarrick J. Wong 	/*
421094d3f1SDarrick J. Wong 	 * This function should do whatever work is needed for pass2 of log
431094d3f1SDarrick J. Wong 	 * recovery, if provided.
441094d3f1SDarrick J. Wong 	 *
451094d3f1SDarrick J. Wong 	 * If the recovered item is an intent item, this function should parse
461094d3f1SDarrick J. Wong 	 * the recovered item to construct an in-core log intent item and
471094d3f1SDarrick J. Wong 	 * insert it into the AIL.  The in-core log intent item should have 1
481094d3f1SDarrick J. Wong 	 * refcount so that the item is freed either (a) when we commit the
491094d3f1SDarrick J. Wong 	 * recovered log item for the intent-done item; (b) replay the work and
501094d3f1SDarrick J. Wong 	 * log a new intent-done item; or (c) recovery fails and we have to
511094d3f1SDarrick J. Wong 	 * abort.
521094d3f1SDarrick J. Wong 	 *
531094d3f1SDarrick J. Wong 	 * If the recovered item is an intent-done item, this function should
541094d3f1SDarrick J. Wong 	 * parse the recovered item to find the id of the corresponding intent
551094d3f1SDarrick J. Wong 	 * log item.  Next, it should find the in-core log intent item in the
561094d3f1SDarrick J. Wong 	 * AIL and release it.
571094d3f1SDarrick J. Wong 	 */
581094d3f1SDarrick J. Wong 	int (*commit_pass2)(struct xlog *log, struct list_head *buffer_list,
591094d3f1SDarrick J. Wong 			    struct xlog_recover_item *item, xfs_lsn_t lsn);
6086ffa471SDarrick J. Wong };
6186ffa471SDarrick J. Wong 
6286ffa471SDarrick J. Wong extern const struct xlog_recover_item_ops xlog_icreate_item_ops;
6386ffa471SDarrick J. Wong extern const struct xlog_recover_item_ops xlog_buf_item_ops;
6486ffa471SDarrick J. Wong extern const struct xlog_recover_item_ops xlog_inode_item_ops;
6586ffa471SDarrick J. Wong extern const struct xlog_recover_item_ops xlog_dquot_item_ops;
6686ffa471SDarrick J. Wong extern const struct xlog_recover_item_ops xlog_quotaoff_item_ops;
6786ffa471SDarrick J. Wong extern const struct xlog_recover_item_ops xlog_bui_item_ops;
6886ffa471SDarrick J. Wong extern const struct xlog_recover_item_ops xlog_bud_item_ops;
6986ffa471SDarrick J. Wong extern const struct xlog_recover_item_ops xlog_efi_item_ops;
7086ffa471SDarrick J. Wong extern const struct xlog_recover_item_ops xlog_efd_item_ops;
7186ffa471SDarrick J. Wong extern const struct xlog_recover_item_ops xlog_rui_item_ops;
7286ffa471SDarrick J. Wong extern const struct xlog_recover_item_ops xlog_rud_item_ops;
7386ffa471SDarrick J. Wong extern const struct xlog_recover_item_ops xlog_cui_item_ops;
7486ffa471SDarrick J. Wong extern const struct xlog_recover_item_ops xlog_cud_item_ops;
75fd920008SAllison Henderson extern const struct xlog_recover_item_ops xlog_attri_item_ops;
76fd920008SAllison Henderson extern const struct xlog_recover_item_ops xlog_attrd_item_ops;
7786ffa471SDarrick J. Wong 
7886ffa471SDarrick J. Wong /*
7984be0ffcSDave Chinner  * Macros, structures, prototypes for internal log manager use.
8084be0ffcSDave Chinner  */
8184be0ffcSDave Chinner 
8284be0ffcSDave Chinner #define XLOG_RHASH_BITS  4
8384be0ffcSDave Chinner #define XLOG_RHASH_SIZE	16
8484be0ffcSDave Chinner #define XLOG_RHASH_SHIFT 2
8584be0ffcSDave Chinner #define XLOG_RHASH(tid)	\
86c8ce540dSDarrick J. Wong 	((((uint32_t)tid)>>XLOG_RHASH_SHIFT) & (XLOG_RHASH_SIZE-1))
8784be0ffcSDave Chinner 
8884be0ffcSDave Chinner #define XLOG_MAX_REGIONS_IN_ITEM   (XFS_MAX_BLOCKSIZE / XFS_BLF_CHUNK / 2 + 1)
8984be0ffcSDave Chinner 
9084be0ffcSDave Chinner 
9184be0ffcSDave Chinner /*
9284be0ffcSDave Chinner  * item headers are in ri_buf[0].  Additional buffers follow.
9384be0ffcSDave Chinner  */
9435f4521fSDarrick J. Wong struct xlog_recover_item {
9584be0ffcSDave Chinner 	struct list_head	ri_list;
9684be0ffcSDave Chinner 	int			ri_cnt;	/* count of regions found */
9784be0ffcSDave Chinner 	int			ri_total;	/* total regions */
9886ffa471SDarrick J. Wong 	struct xfs_log_iovec	*ri_buf;	/* ptr to regions buffer */
9986ffa471SDarrick J. Wong 	const struct xlog_recover_item_ops *ri_ops;
10035f4521fSDarrick J. Wong };
10184be0ffcSDave Chinner 
10235dab307SEric Sandeen struct xlog_recover {
10384be0ffcSDave Chinner 	struct hlist_node	r_list;
10484be0ffcSDave Chinner 	xlog_tid_t		r_log_tid;	/* log's transaction id */
10584be0ffcSDave Chinner 	xfs_trans_header_t	r_theader;	/* trans header for partial */
10684be0ffcSDave Chinner 	int			r_state;	/* not needed */
10784be0ffcSDave Chinner 	xfs_lsn_t		r_lsn;		/* xact lsn */
10884be0ffcSDave Chinner 	struct list_head	r_itemq;	/* q for items */
10935dab307SEric Sandeen };
11084be0ffcSDave Chinner 
111755c7bf5SDarrick J. Wong #define ITEM_TYPE(i)	(*(unsigned short *)(i)->ri_buf[0].i_addr)
11284be0ffcSDave Chinner 
1136528250bSBrian Foster #define	XLOG_RECOVER_CRCPASS	0
11484be0ffcSDave Chinner #define	XLOG_RECOVER_PASS1	1
11584be0ffcSDave Chinner #define	XLOG_RECOVER_PASS2	2
11684be0ffcSDave Chinner 
1178ea5682dSDarrick J. Wong void xlog_buf_readahead(struct xlog *log, xfs_daddr_t blkno, uint len,
1188ea5682dSDarrick J. Wong 		const struct xfs_buf_ops *ops);
1191094d3f1SDarrick J. Wong bool xlog_is_buffer_cancelled(struct xlog *log, xfs_daddr_t blkno, uint len);
1208ea5682dSDarrick J. Wong 
1214bc61983SDarrick J. Wong int xlog_recover_iget(struct xfs_mount *mp, xfs_ino_t ino,
1224bc61983SDarrick J. Wong 		struct xfs_inode **ipp);
123154c733aSDarrick J. Wong void xlog_recover_release_intent(struct xlog *log, unsigned short intent_type,
124154c733aSDarrick J. Wong 		uint64_t intent_id);
125910bbdf2SDarrick J. Wong int xlog_alloc_buf_cancel_table(struct xlog *log);
12627232349SDarrick J. Wong void xlog_free_buf_cancel_table(struct xlog *log);
12727232349SDarrick J. Wong 
12827232349SDarrick J. Wong #ifdef DEBUG
12927232349SDarrick J. Wong void xlog_check_buf_cancel_table(struct xlog *log);
13027232349SDarrick J. Wong #else
13127232349SDarrick J. Wong #define xlog_check_buf_cancel_table(log) do { } while (0)
13227232349SDarrick J. Wong #endif
133154c733aSDarrick J. Wong 
1343c919b09SDarrick J. Wong /*
1353c919b09SDarrick J. Wong  * Transform a regular reservation into one suitable for recovery of a log
1363c919b09SDarrick J. Wong  * intent item.
1373c919b09SDarrick J. Wong  *
1383c919b09SDarrick J. Wong  * Intent recovery only runs a single step of the transaction chain and defers
1393c919b09SDarrick J. Wong  * the rest to a separate transaction.  Therefore, we reduce logcount to 1 here
1403c919b09SDarrick J. Wong  * to avoid livelocks if the log grant space is nearly exhausted due to the
1413c919b09SDarrick J. Wong  * recovered intent pinning the tail.  Keep the same logflags to avoid tripping
1423c919b09SDarrick J. Wong  * asserts elsewhere.  Struct copies abound below.
1433c919b09SDarrick J. Wong  */
1443c919b09SDarrick J. Wong static inline struct xfs_trans_res
xlog_recover_resv(const struct xfs_trans_res * r)1453c919b09SDarrick J. Wong xlog_recover_resv(const struct xfs_trans_res *r)
1463c919b09SDarrick J. Wong {
1473c919b09SDarrick J. Wong 	struct xfs_trans_res ret = {
1483c919b09SDarrick J. Wong 		.tr_logres	= r->tr_logres,
1493c919b09SDarrick J. Wong 		.tr_logcount	= 1,
1503c919b09SDarrick J. Wong 		.tr_logflags	= r->tr_logflags,
1513c919b09SDarrick J. Wong 	};
1523c919b09SDarrick J. Wong 
1533c919b09SDarrick J. Wong 	return ret;
1543c919b09SDarrick J. Wong }
1553c919b09SDarrick J. Wong 
156cd3c2cf3SDarrick J. Wong void xlog_recover_intent_item(struct xlog *log, struct xfs_log_item *lip,
157cd3c2cf3SDarrick J. Wong 		xfs_lsn_t lsn, unsigned int dfp_type);
158*680776e5SDarrick J. Wong void xlog_recover_transfer_intent(struct xfs_trans *tp,
159*680776e5SDarrick J. Wong 		struct xfs_defer_pending *dfp);
160cd3c2cf3SDarrick J. Wong 
16184be0ffcSDave Chinner #endif	/* __XFS_LOG_RECOVER_H__ */
162