162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. 462306a36Sopenharmony_ci * All Rights Reserved. 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci#ifndef __XFS_TRANS_H__ 762306a36Sopenharmony_ci#define __XFS_TRANS_H__ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci/* kernel only transaction subsystem defines */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_cistruct xlog; 1262306a36Sopenharmony_cistruct xfs_buf; 1362306a36Sopenharmony_cistruct xfs_buftarg; 1462306a36Sopenharmony_cistruct xfs_efd_log_item; 1562306a36Sopenharmony_cistruct xfs_efi_log_item; 1662306a36Sopenharmony_cistruct xfs_inode; 1762306a36Sopenharmony_cistruct xfs_item_ops; 1862306a36Sopenharmony_cistruct xfs_log_iovec; 1962306a36Sopenharmony_cistruct xfs_mount; 2062306a36Sopenharmony_cistruct xfs_trans; 2162306a36Sopenharmony_cistruct xfs_trans_res; 2262306a36Sopenharmony_cistruct xfs_dquot_acct; 2362306a36Sopenharmony_cistruct xfs_rud_log_item; 2462306a36Sopenharmony_cistruct xfs_rui_log_item; 2562306a36Sopenharmony_cistruct xfs_btree_cur; 2662306a36Sopenharmony_cistruct xfs_cui_log_item; 2762306a36Sopenharmony_cistruct xfs_cud_log_item; 2862306a36Sopenharmony_cistruct xfs_bui_log_item; 2962306a36Sopenharmony_cistruct xfs_bud_log_item; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistruct xfs_log_item { 3262306a36Sopenharmony_ci struct list_head li_ail; /* AIL pointers */ 3362306a36Sopenharmony_ci struct list_head li_trans; /* transaction list */ 3462306a36Sopenharmony_ci xfs_lsn_t li_lsn; /* last on-disk lsn */ 3562306a36Sopenharmony_ci struct xlog *li_log; 3662306a36Sopenharmony_ci struct xfs_ail *li_ailp; /* ptr to AIL */ 3762306a36Sopenharmony_ci uint li_type; /* item type */ 3862306a36Sopenharmony_ci unsigned long li_flags; /* misc flags */ 3962306a36Sopenharmony_ci struct xfs_buf *li_buf; /* real buffer pointer */ 4062306a36Sopenharmony_ci struct list_head li_bio_list; /* buffer item list */ 4162306a36Sopenharmony_ci const struct xfs_item_ops *li_ops; /* function list */ 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci /* delayed logging */ 4462306a36Sopenharmony_ci struct list_head li_cil; /* CIL pointers */ 4562306a36Sopenharmony_ci struct xfs_log_vec *li_lv; /* active log vector */ 4662306a36Sopenharmony_ci struct xfs_log_vec *li_lv_shadow; /* standby vector */ 4762306a36Sopenharmony_ci xfs_csn_t li_seq; /* CIL commit seq */ 4862306a36Sopenharmony_ci uint32_t li_order_id; /* CIL commit order */ 4962306a36Sopenharmony_ci}; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci/* 5262306a36Sopenharmony_ci * li_flags use the (set/test/clear)_bit atomic interfaces because updates can 5362306a36Sopenharmony_ci * race with each other and we don't want to have to use the AIL lock to 5462306a36Sopenharmony_ci * serialise all updates. 5562306a36Sopenharmony_ci */ 5662306a36Sopenharmony_ci#define XFS_LI_IN_AIL 0 5762306a36Sopenharmony_ci#define XFS_LI_ABORTED 1 5862306a36Sopenharmony_ci#define XFS_LI_FAILED 2 5962306a36Sopenharmony_ci#define XFS_LI_DIRTY 3 6062306a36Sopenharmony_ci#define XFS_LI_WHITEOUT 4 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci#define XFS_LI_FLAGS \ 6362306a36Sopenharmony_ci { (1u << XFS_LI_IN_AIL), "IN_AIL" }, \ 6462306a36Sopenharmony_ci { (1u << XFS_LI_ABORTED), "ABORTED" }, \ 6562306a36Sopenharmony_ci { (1u << XFS_LI_FAILED), "FAILED" }, \ 6662306a36Sopenharmony_ci { (1u << XFS_LI_DIRTY), "DIRTY" }, \ 6762306a36Sopenharmony_ci { (1u << XFS_LI_WHITEOUT), "WHITEOUT" } 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_cistruct xfs_item_ops { 7062306a36Sopenharmony_ci unsigned flags; 7162306a36Sopenharmony_ci void (*iop_size)(struct xfs_log_item *, int *, int *); 7262306a36Sopenharmony_ci void (*iop_format)(struct xfs_log_item *, struct xfs_log_vec *); 7362306a36Sopenharmony_ci void (*iop_pin)(struct xfs_log_item *); 7462306a36Sopenharmony_ci void (*iop_unpin)(struct xfs_log_item *, int remove); 7562306a36Sopenharmony_ci uint64_t (*iop_sort)(struct xfs_log_item *lip); 7662306a36Sopenharmony_ci int (*iop_precommit)(struct xfs_trans *tp, struct xfs_log_item *lip); 7762306a36Sopenharmony_ci void (*iop_committing)(struct xfs_log_item *lip, xfs_csn_t seq); 7862306a36Sopenharmony_ci xfs_lsn_t (*iop_committed)(struct xfs_log_item *, xfs_lsn_t); 7962306a36Sopenharmony_ci uint (*iop_push)(struct xfs_log_item *, struct list_head *); 8062306a36Sopenharmony_ci void (*iop_release)(struct xfs_log_item *); 8162306a36Sopenharmony_ci int (*iop_recover)(struct xfs_log_item *lip, 8262306a36Sopenharmony_ci struct list_head *capture_list); 8362306a36Sopenharmony_ci bool (*iop_match)(struct xfs_log_item *item, uint64_t id); 8462306a36Sopenharmony_ci struct xfs_log_item *(*iop_relog)(struct xfs_log_item *intent, 8562306a36Sopenharmony_ci struct xfs_trans *tp); 8662306a36Sopenharmony_ci struct xfs_log_item *(*iop_intent)(struct xfs_log_item *intent_done); 8762306a36Sopenharmony_ci}; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci/* 9062306a36Sopenharmony_ci * Log item ops flags 9162306a36Sopenharmony_ci */ 9262306a36Sopenharmony_ci/* 9362306a36Sopenharmony_ci * Release the log item when the journal commits instead of inserting into the 9462306a36Sopenharmony_ci * AIL for writeback tracking and/or log tail pinning. 9562306a36Sopenharmony_ci */ 9662306a36Sopenharmony_ci#define XFS_ITEM_RELEASE_WHEN_COMMITTED (1 << 0) 9762306a36Sopenharmony_ci#define XFS_ITEM_INTENT (1 << 1) 9862306a36Sopenharmony_ci#define XFS_ITEM_INTENT_DONE (1 << 2) 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_cistatic inline bool 10162306a36Sopenharmony_cixlog_item_is_intent(struct xfs_log_item *lip) 10262306a36Sopenharmony_ci{ 10362306a36Sopenharmony_ci return lip->li_ops->flags & XFS_ITEM_INTENT; 10462306a36Sopenharmony_ci} 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_cistatic inline bool 10762306a36Sopenharmony_cixlog_item_is_intent_done(struct xfs_log_item *lip) 10862306a36Sopenharmony_ci{ 10962306a36Sopenharmony_ci return lip->li_ops->flags & XFS_ITEM_INTENT_DONE; 11062306a36Sopenharmony_ci} 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_civoid xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item, 11362306a36Sopenharmony_ci int type, const struct xfs_item_ops *ops); 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci/* 11662306a36Sopenharmony_ci * Return values for the iop_push() routines. 11762306a36Sopenharmony_ci */ 11862306a36Sopenharmony_ci#define XFS_ITEM_SUCCESS 0 11962306a36Sopenharmony_ci#define XFS_ITEM_PINNED 1 12062306a36Sopenharmony_ci#define XFS_ITEM_LOCKED 2 12162306a36Sopenharmony_ci#define XFS_ITEM_FLUSHING 3 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci/* 12462306a36Sopenharmony_ci * This is the structure maintained for every active transaction. 12562306a36Sopenharmony_ci */ 12662306a36Sopenharmony_citypedef struct xfs_trans { 12762306a36Sopenharmony_ci unsigned int t_magic; /* magic number */ 12862306a36Sopenharmony_ci unsigned int t_log_res; /* amt of log space resvd */ 12962306a36Sopenharmony_ci unsigned int t_log_count; /* count for perm log res */ 13062306a36Sopenharmony_ci unsigned int t_blk_res; /* # of blocks resvd */ 13162306a36Sopenharmony_ci unsigned int t_blk_res_used; /* # of resvd blocks used */ 13262306a36Sopenharmony_ci unsigned int t_rtx_res; /* # of rt extents resvd */ 13362306a36Sopenharmony_ci unsigned int t_rtx_res_used; /* # of resvd rt extents used */ 13462306a36Sopenharmony_ci unsigned int t_flags; /* misc flags */ 13562306a36Sopenharmony_ci xfs_agnumber_t t_highest_agno; /* highest AGF locked */ 13662306a36Sopenharmony_ci struct xlog_ticket *t_ticket; /* log mgr ticket */ 13762306a36Sopenharmony_ci struct xfs_mount *t_mountp; /* ptr to fs mount struct */ 13862306a36Sopenharmony_ci struct xfs_dquot_acct *t_dqinfo; /* acctg info for dquots */ 13962306a36Sopenharmony_ci int64_t t_icount_delta; /* superblock icount change */ 14062306a36Sopenharmony_ci int64_t t_ifree_delta; /* superblock ifree change */ 14162306a36Sopenharmony_ci int64_t t_fdblocks_delta; /* superblock fdblocks chg */ 14262306a36Sopenharmony_ci int64_t t_res_fdblocks_delta; /* on-disk only chg */ 14362306a36Sopenharmony_ci int64_t t_frextents_delta;/* superblock freextents chg*/ 14462306a36Sopenharmony_ci int64_t t_res_frextents_delta; /* on-disk only chg */ 14562306a36Sopenharmony_ci int64_t t_dblocks_delta;/* superblock dblocks change */ 14662306a36Sopenharmony_ci int64_t t_agcount_delta;/* superblock agcount change */ 14762306a36Sopenharmony_ci int64_t t_imaxpct_delta;/* superblock imaxpct change */ 14862306a36Sopenharmony_ci int64_t t_rextsize_delta;/* superblock rextsize chg */ 14962306a36Sopenharmony_ci int64_t t_rbmblocks_delta;/* superblock rbmblocks chg */ 15062306a36Sopenharmony_ci int64_t t_rblocks_delta;/* superblock rblocks change */ 15162306a36Sopenharmony_ci int64_t t_rextents_delta;/* superblocks rextents chg */ 15262306a36Sopenharmony_ci int64_t t_rextslog_delta;/* superblocks rextslog chg */ 15362306a36Sopenharmony_ci struct list_head t_items; /* log item descriptors */ 15462306a36Sopenharmony_ci struct list_head t_busy; /* list of busy extents */ 15562306a36Sopenharmony_ci struct list_head t_dfops; /* deferred operations */ 15662306a36Sopenharmony_ci unsigned long t_pflags; /* saved process flags state */ 15762306a36Sopenharmony_ci} xfs_trans_t; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci/* 16062306a36Sopenharmony_ci * XFS transaction mechanism exported interfaces that are 16162306a36Sopenharmony_ci * actually macros. 16262306a36Sopenharmony_ci */ 16362306a36Sopenharmony_ci#define xfs_trans_set_sync(tp) ((tp)->t_flags |= XFS_TRANS_SYNC) 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci/* 16662306a36Sopenharmony_ci * XFS transaction mechanism exported interfaces. 16762306a36Sopenharmony_ci */ 16862306a36Sopenharmony_ciint xfs_trans_alloc(struct xfs_mount *mp, struct xfs_trans_res *resp, 16962306a36Sopenharmony_ci uint blocks, uint rtextents, uint flags, 17062306a36Sopenharmony_ci struct xfs_trans **tpp); 17162306a36Sopenharmony_ciint xfs_trans_alloc_empty(struct xfs_mount *mp, 17262306a36Sopenharmony_ci struct xfs_trans **tpp); 17362306a36Sopenharmony_civoid xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t); 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ciint xfs_trans_get_buf_map(struct xfs_trans *tp, struct xfs_buftarg *target, 17662306a36Sopenharmony_ci struct xfs_buf_map *map, int nmaps, xfs_buf_flags_t flags, 17762306a36Sopenharmony_ci struct xfs_buf **bpp); 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_cistatic inline int 18062306a36Sopenharmony_cixfs_trans_get_buf( 18162306a36Sopenharmony_ci struct xfs_trans *tp, 18262306a36Sopenharmony_ci struct xfs_buftarg *target, 18362306a36Sopenharmony_ci xfs_daddr_t blkno, 18462306a36Sopenharmony_ci int numblks, 18562306a36Sopenharmony_ci xfs_buf_flags_t flags, 18662306a36Sopenharmony_ci struct xfs_buf **bpp) 18762306a36Sopenharmony_ci{ 18862306a36Sopenharmony_ci DEFINE_SINGLE_BUF_MAP(map, blkno, numblks); 18962306a36Sopenharmony_ci return xfs_trans_get_buf_map(tp, target, &map, 1, flags, bpp); 19062306a36Sopenharmony_ci} 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ciint xfs_trans_read_buf_map(struct xfs_mount *mp, 19362306a36Sopenharmony_ci struct xfs_trans *tp, 19462306a36Sopenharmony_ci struct xfs_buftarg *target, 19562306a36Sopenharmony_ci struct xfs_buf_map *map, int nmaps, 19662306a36Sopenharmony_ci xfs_buf_flags_t flags, 19762306a36Sopenharmony_ci struct xfs_buf **bpp, 19862306a36Sopenharmony_ci const struct xfs_buf_ops *ops); 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_cistatic inline int 20162306a36Sopenharmony_cixfs_trans_read_buf( 20262306a36Sopenharmony_ci struct xfs_mount *mp, 20362306a36Sopenharmony_ci struct xfs_trans *tp, 20462306a36Sopenharmony_ci struct xfs_buftarg *target, 20562306a36Sopenharmony_ci xfs_daddr_t blkno, 20662306a36Sopenharmony_ci int numblks, 20762306a36Sopenharmony_ci xfs_buf_flags_t flags, 20862306a36Sopenharmony_ci struct xfs_buf **bpp, 20962306a36Sopenharmony_ci const struct xfs_buf_ops *ops) 21062306a36Sopenharmony_ci{ 21162306a36Sopenharmony_ci DEFINE_SINGLE_BUF_MAP(map, blkno, numblks); 21262306a36Sopenharmony_ci return xfs_trans_read_buf_map(mp, tp, target, &map, 1, 21362306a36Sopenharmony_ci flags, bpp, ops); 21462306a36Sopenharmony_ci} 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_cistruct xfs_buf *xfs_trans_getsb(struct xfs_trans *); 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_civoid xfs_trans_brelse(xfs_trans_t *, struct xfs_buf *); 21962306a36Sopenharmony_civoid xfs_trans_bjoin(xfs_trans_t *, struct xfs_buf *); 22062306a36Sopenharmony_civoid xfs_trans_bhold(xfs_trans_t *, struct xfs_buf *); 22162306a36Sopenharmony_civoid xfs_trans_bhold_release(xfs_trans_t *, struct xfs_buf *); 22262306a36Sopenharmony_civoid xfs_trans_binval(xfs_trans_t *, struct xfs_buf *); 22362306a36Sopenharmony_civoid xfs_trans_inode_buf(xfs_trans_t *, struct xfs_buf *); 22462306a36Sopenharmony_civoid xfs_trans_stale_inode_buf(xfs_trans_t *, struct xfs_buf *); 22562306a36Sopenharmony_cibool xfs_trans_ordered_buf(xfs_trans_t *, struct xfs_buf *); 22662306a36Sopenharmony_civoid xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint); 22762306a36Sopenharmony_civoid xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *); 22862306a36Sopenharmony_civoid xfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int); 22962306a36Sopenharmony_civoid xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *, uint); 23062306a36Sopenharmony_civoid xfs_trans_log_buf(struct xfs_trans *, struct xfs_buf *, uint, 23162306a36Sopenharmony_ci uint); 23262306a36Sopenharmony_civoid xfs_trans_dirty_buf(struct xfs_trans *, struct xfs_buf *); 23362306a36Sopenharmony_cibool xfs_trans_buf_is_dirty(struct xfs_buf *bp); 23462306a36Sopenharmony_civoid xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint); 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ciint xfs_trans_commit(struct xfs_trans *); 23762306a36Sopenharmony_ciint xfs_trans_roll(struct xfs_trans **); 23862306a36Sopenharmony_ciint xfs_trans_roll_inode(struct xfs_trans **, struct xfs_inode *); 23962306a36Sopenharmony_civoid xfs_trans_cancel(xfs_trans_t *); 24062306a36Sopenharmony_ciint xfs_trans_ail_init(struct xfs_mount *); 24162306a36Sopenharmony_civoid xfs_trans_ail_destroy(struct xfs_mount *); 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_civoid xfs_trans_buf_set_type(struct xfs_trans *, struct xfs_buf *, 24462306a36Sopenharmony_ci enum xfs_blft); 24562306a36Sopenharmony_civoid xfs_trans_buf_copy_type(struct xfs_buf *dst_bp, 24662306a36Sopenharmony_ci struct xfs_buf *src_bp); 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ciextern struct kmem_cache *xfs_trans_cache; 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_cistatic inline struct xfs_log_item * 25162306a36Sopenharmony_cixfs_trans_item_relog( 25262306a36Sopenharmony_ci struct xfs_log_item *lip, 25362306a36Sopenharmony_ci struct xfs_trans *tp) 25462306a36Sopenharmony_ci{ 25562306a36Sopenharmony_ci return lip->li_ops->iop_relog(lip, tp); 25662306a36Sopenharmony_ci} 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_cistruct xfs_dquot; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ciint xfs_trans_alloc_inode(struct xfs_inode *ip, struct xfs_trans_res *resv, 26162306a36Sopenharmony_ci unsigned int dblocks, unsigned int rblocks, bool force, 26262306a36Sopenharmony_ci struct xfs_trans **tpp); 26362306a36Sopenharmony_ciint xfs_trans_alloc_icreate(struct xfs_mount *mp, struct xfs_trans_res *resv, 26462306a36Sopenharmony_ci struct xfs_dquot *udqp, struct xfs_dquot *gdqp, 26562306a36Sopenharmony_ci struct xfs_dquot *pdqp, unsigned int dblocks, 26662306a36Sopenharmony_ci struct xfs_trans **tpp); 26762306a36Sopenharmony_ciint xfs_trans_alloc_ichange(struct xfs_inode *ip, struct xfs_dquot *udqp, 26862306a36Sopenharmony_ci struct xfs_dquot *gdqp, struct xfs_dquot *pdqp, bool force, 26962306a36Sopenharmony_ci struct xfs_trans **tpp); 27062306a36Sopenharmony_ciint xfs_trans_alloc_dir(struct xfs_inode *dp, struct xfs_trans_res *resv, 27162306a36Sopenharmony_ci struct xfs_inode *ip, unsigned int *dblocks, 27262306a36Sopenharmony_ci struct xfs_trans **tpp, int *nospace_error); 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_cistatic inline void 27562306a36Sopenharmony_cixfs_trans_set_context( 27662306a36Sopenharmony_ci struct xfs_trans *tp) 27762306a36Sopenharmony_ci{ 27862306a36Sopenharmony_ci ASSERT(current->journal_info == NULL); 27962306a36Sopenharmony_ci tp->t_pflags = memalloc_nofs_save(); 28062306a36Sopenharmony_ci current->journal_info = tp; 28162306a36Sopenharmony_ci} 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_cistatic inline void 28462306a36Sopenharmony_cixfs_trans_clear_context( 28562306a36Sopenharmony_ci struct xfs_trans *tp) 28662306a36Sopenharmony_ci{ 28762306a36Sopenharmony_ci if (current->journal_info == tp) { 28862306a36Sopenharmony_ci memalloc_nofs_restore(tp->t_pflags); 28962306a36Sopenharmony_ci current->journal_info = NULL; 29062306a36Sopenharmony_ci } 29162306a36Sopenharmony_ci} 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_cistatic inline void 29462306a36Sopenharmony_cixfs_trans_switch_context( 29562306a36Sopenharmony_ci struct xfs_trans *old_tp, 29662306a36Sopenharmony_ci struct xfs_trans *new_tp) 29762306a36Sopenharmony_ci{ 29862306a36Sopenharmony_ci ASSERT(current->journal_info == old_tp); 29962306a36Sopenharmony_ci new_tp->t_pflags = old_tp->t_pflags; 30062306a36Sopenharmony_ci old_tp->t_pflags = 0; 30162306a36Sopenharmony_ci current->journal_info = new_tp; 30262306a36Sopenharmony_ci} 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci#endif /* __XFS_TRANS_H__ */ 305