Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
4 : * All Rights Reserved.
5 : */
6 : #ifndef __XFS_TRANS_H__
7 : #define __XFS_TRANS_H__
8 :
9 : /* kernel only transaction subsystem defines */
10 :
11 : struct xlog;
12 : struct xfs_buf;
13 : struct xfs_buftarg;
14 : struct xfs_efd_log_item;
15 : struct xfs_efi_log_item;
16 : struct xfs_inode;
17 : struct xfs_item_ops;
18 : struct xfs_log_iovec;
19 : struct xfs_mount;
20 : struct xfs_trans;
21 : struct xfs_trans_res;
22 : struct xfs_dquot_acct;
23 : struct xfs_rud_log_item;
24 : struct xfs_rui_log_item;
25 : struct xfs_btree_cur;
26 : struct xfs_cui_log_item;
27 : struct xfs_cud_log_item;
28 : struct xfs_bui_log_item;
29 : struct xfs_bud_log_item;
30 :
31 : struct xfs_log_item {
32 : struct list_head li_ail; /* AIL pointers */
33 : struct list_head li_trans; /* transaction list */
34 : xfs_lsn_t li_lsn; /* last on-disk lsn */
35 : struct xlog *li_log;
36 : struct xfs_ail *li_ailp; /* ptr to AIL */
37 : uint li_type; /* item type */
38 : unsigned long li_flags; /* misc flags */
39 : struct xfs_buf *li_buf; /* real buffer pointer */
40 : struct list_head li_bio_list; /* buffer item list */
41 : const struct xfs_item_ops *li_ops; /* function list */
42 :
43 : /* delayed logging */
44 : struct list_head li_cil; /* CIL pointers */
45 : struct xfs_log_vec *li_lv; /* active log vector */
46 : struct xfs_log_vec *li_lv_shadow; /* standby vector */
47 : xfs_csn_t li_seq; /* CIL commit seq */
48 : uint32_t li_order_id; /* CIL commit order */
49 : };
50 :
51 : /*
52 : * li_flags use the (set/test/clear)_bit atomic interfaces because updates can
53 : * race with each other and we don't want to have to use the AIL lock to
54 : * serialise all updates.
55 : */
56 : #define XFS_LI_IN_AIL 0
57 : #define XFS_LI_ABORTED 1
58 : #define XFS_LI_FAILED 2
59 : #define XFS_LI_DIRTY 3
60 : #define XFS_LI_WHITEOUT 4
61 :
62 : #define XFS_LI_FLAGS \
63 : { (1u << XFS_LI_IN_AIL), "IN_AIL" }, \
64 : { (1u << XFS_LI_ABORTED), "ABORTED" }, \
65 : { (1u << XFS_LI_FAILED), "FAILED" }, \
66 : { (1u << XFS_LI_DIRTY), "DIRTY" }, \
67 : { (1u << XFS_LI_WHITEOUT), "WHITEOUT" }
68 :
69 : struct xfs_item_ops {
70 : unsigned flags;
71 : void (*iop_size)(struct xfs_log_item *, int *, int *);
72 : void (*iop_format)(struct xfs_log_item *, struct xfs_log_vec *);
73 : void (*iop_pin)(struct xfs_log_item *);
74 : void (*iop_unpin)(struct xfs_log_item *, int remove);
75 : uint64_t (*iop_sort)(struct xfs_log_item *lip);
76 : int (*iop_precommit)(struct xfs_trans *tp, struct xfs_log_item *lip);
77 : void (*iop_committing)(struct xfs_log_item *lip, xfs_csn_t seq);
78 : xfs_lsn_t (*iop_committed)(struct xfs_log_item *, xfs_lsn_t);
79 : uint (*iop_push)(struct xfs_log_item *, struct list_head *);
80 : void (*iop_release)(struct xfs_log_item *);
81 : int (*iop_recover)(struct xfs_log_item *lip,
82 : struct list_head *capture_list);
83 : bool (*iop_match)(struct xfs_log_item *item, uint64_t id);
84 : struct xfs_log_item *(*iop_relog)(struct xfs_log_item *intent,
85 : struct xfs_trans *tp);
86 : struct xfs_log_item *(*iop_intent)(struct xfs_log_item *intent_done);
87 : };
88 :
89 : /*
90 : * Log item ops flags
91 : */
92 : /*
93 : * Release the log item when the journal commits instead of inserting into the
94 : * AIL for writeback tracking and/or log tail pinning.
95 : */
96 : #define XFS_ITEM_RELEASE_WHEN_COMMITTED (1 << 0)
97 : #define XFS_ITEM_INTENT (1 << 1)
98 : #define XFS_ITEM_INTENT_DONE (1 << 2)
99 :
100 : static inline bool
101 : xlog_item_is_intent(struct xfs_log_item *lip)
102 : {
103 5085 : return lip->li_ops->flags & XFS_ITEM_INTENT;
104 : }
105 :
106 : static inline bool
107 : xlog_item_is_intent_done(struct xfs_log_item *lip)
108 : {
109 593061821 : return lip->li_ops->flags & XFS_ITEM_INTENT_DONE;
110 : }
111 :
112 : void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item,
113 : int type, const struct xfs_item_ops *ops);
114 :
115 : /*
116 : * Return values for the iop_push() routines.
117 : */
118 : #define XFS_ITEM_SUCCESS 0
119 : #define XFS_ITEM_PINNED 1
120 : #define XFS_ITEM_LOCKED 2
121 : #define XFS_ITEM_FLUSHING 3
122 :
123 : /*
124 : * This is the structure maintained for every active transaction.
125 : */
126 : typedef struct xfs_trans {
127 : unsigned int t_magic; /* magic number */
128 : unsigned int t_log_res; /* amt of log space resvd */
129 : unsigned int t_log_count; /* count for perm log res */
130 : unsigned int t_blk_res; /* # of blocks resvd */
131 : unsigned int t_blk_res_used; /* # of resvd blocks used */
132 : unsigned int t_rtx_res; /* # of rt extents resvd */
133 : unsigned int t_rtx_res_used; /* # of resvd rt extents used */
134 : unsigned int t_flags; /* misc flags */
135 : xfs_agnumber_t t_highest_agno; /* highest AGF locked */
136 : struct xlog_ticket *t_ticket; /* log mgr ticket */
137 : struct xfs_mount *t_mountp; /* ptr to fs mount struct */
138 : struct xfs_dquot_acct *t_dqinfo; /* acctg info for dquots */
139 : int64_t t_icount_delta; /* superblock icount change */
140 : int64_t t_ifree_delta; /* superblock ifree change */
141 : int64_t t_fdblocks_delta; /* superblock fdblocks chg */
142 : int64_t t_res_fdblocks_delta; /* on-disk only chg */
143 : int64_t t_frextents_delta;/* superblock freextents chg*/
144 : int64_t t_res_frextents_delta; /* on-disk only chg */
145 : int64_t t_dblocks_delta;/* superblock dblocks change */
146 : int64_t t_agcount_delta;/* superblock agcount change */
147 : int64_t t_imaxpct_delta;/* superblock imaxpct change */
148 : int64_t t_rextsize_delta;/* superblock rextsize chg */
149 : int64_t t_rbmblocks_delta;/* superblock rbmblocks chg */
150 : int64_t t_rblocks_delta;/* superblock rblocks change */
151 : int64_t t_rextents_delta;/* superblocks rextents chg */
152 : int64_t t_rextslog_delta;/* superblocks rextslog chg */
153 : int64_t t_rgcount_delta; /* realtime group count */
154 : struct list_head t_items; /* log item descriptors */
155 : struct list_head t_busy; /* list of busy extents */
156 : struct list_head t_dfops; /* deferred operations */
157 : unsigned long t_pflags; /* saved process flags state */
158 :
159 : /* Count of deferred ops attached to transaction. */
160 : unsigned int t_dfops_nr;
161 : /* Maximum t_dfops_nr seen in a loop. */
162 : unsigned int t_dfops_nr_max;
163 : /* Number of dfops finished. */
164 : unsigned int t_dfops_finished;
165 : } xfs_trans_t;
166 :
167 : /*
168 : * XFS transaction mechanism exported interfaces that are
169 : * actually macros.
170 : */
171 : #define xfs_trans_set_sync(tp) ((tp)->t_flags |= XFS_TRANS_SYNC)
172 :
173 : /*
174 : * XFS transaction mechanism exported interfaces.
175 : */
176 : int xfs_trans_alloc(struct xfs_mount *mp, struct xfs_trans_res *resp,
177 : uint blocks, uint rtextents, uint flags,
178 : struct xfs_trans **tpp);
179 : int xfs_trans_reserve_more(struct xfs_trans *tp,
180 : unsigned int blocks, unsigned int rtextents);
181 : int xfs_trans_alloc_empty(struct xfs_mount *mp,
182 : struct xfs_trans **tpp);
183 : void xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t);
184 :
185 : int xfs_trans_get_buf_map(struct xfs_trans *tp, struct xfs_buftarg *target,
186 : struct xfs_buf_map *map, int nmaps, xfs_buf_flags_t flags,
187 : struct xfs_buf **bpp);
188 :
189 : static inline int
190 : xfs_trans_get_buf(
191 : struct xfs_trans *tp,
192 : struct xfs_buftarg *target,
193 : xfs_daddr_t blkno,
194 : int numblks,
195 : xfs_buf_flags_t flags,
196 : struct xfs_buf **bpp)
197 : {
198 72992441 : DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
199 72992441 : return xfs_trans_get_buf_map(tp, target, &map, 1, flags, bpp);
200 : }
201 :
202 : int xfs_trans_read_buf_map(struct xfs_mount *mp,
203 : struct xfs_trans *tp,
204 : struct xfs_buftarg *target,
205 : struct xfs_buf_map *map, int nmaps,
206 : xfs_buf_flags_t flags,
207 : struct xfs_buf **bpp,
208 : const struct xfs_buf_ops *ops);
209 :
210 : static inline int
211 : xfs_trans_read_buf(
212 : struct xfs_mount *mp,
213 : struct xfs_trans *tp,
214 : struct xfs_buftarg *target,
215 : xfs_daddr_t blkno,
216 : int numblks,
217 : xfs_buf_flags_t flags,
218 : struct xfs_buf **bpp,
219 : const struct xfs_buf_ops *ops)
220 : {
221 34905099720 : DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
222 34905099720 : return xfs_trans_read_buf_map(mp, tp, target, &map, 1,
223 : flags, bpp, ops);
224 : }
225 :
226 : struct xfs_buf *xfs_trans_getsb(struct xfs_trans *);
227 : struct xfs_buf *xfs_trans_getrtsb(struct xfs_trans *tp);
228 :
229 : void xfs_trans_brelse(xfs_trans_t *, struct xfs_buf *);
230 : void xfs_trans_bjoin(xfs_trans_t *, struct xfs_buf *);
231 : void xfs_trans_bdetach(struct xfs_trans *tp, struct xfs_buf *bp);
232 : void xfs_trans_bhold(xfs_trans_t *, struct xfs_buf *);
233 : void xfs_trans_bhold_release(xfs_trans_t *, struct xfs_buf *);
234 : void xfs_trans_binval(xfs_trans_t *, struct xfs_buf *);
235 : void xfs_trans_inode_buf(xfs_trans_t *, struct xfs_buf *);
236 : void xfs_trans_stale_inode_buf(xfs_trans_t *, struct xfs_buf *);
237 : bool xfs_trans_ordered_buf(xfs_trans_t *, struct xfs_buf *);
238 : void xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint);
239 : void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *);
240 : void xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *, uint);
241 : void xfs_trans_log_buf(struct xfs_trans *, struct xfs_buf *, uint,
242 : uint);
243 : void xfs_trans_dirty_buf(struct xfs_trans *, struct xfs_buf *);
244 : bool xfs_trans_buf_is_dirty(struct xfs_buf *bp);
245 : void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint);
246 :
247 : int xfs_trans_commit(struct xfs_trans *);
248 : int xfs_trans_roll(struct xfs_trans **);
249 : int xfs_trans_roll_inode(struct xfs_trans **, struct xfs_inode *);
250 : void xfs_trans_cancel(xfs_trans_t *);
251 : int xfs_trans_ail_init(struct xfs_mount *);
252 : void xfs_trans_ail_destroy(struct xfs_mount *);
253 :
254 : void xfs_trans_buf_set_type(struct xfs_trans *, struct xfs_buf *,
255 : enum xfs_blft);
256 : void xfs_trans_buf_copy_type(struct xfs_buf *dst_bp,
257 : struct xfs_buf *src_bp);
258 :
259 : extern struct kmem_cache *xfs_trans_cache;
260 :
261 : static inline struct xfs_log_item *
262 : xfs_trans_item_relog(
263 : struct xfs_log_item *lip,
264 : struct xfs_trans *tp)
265 : {
266 126625 : return lip->li_ops->iop_relog(lip, tp);
267 : }
268 :
269 : struct xfs_dquot;
270 :
271 : int xfs_trans_alloc_inode(struct xfs_inode *ip, struct xfs_trans_res *resv,
272 : unsigned int dblocks, unsigned int rblocks, bool force,
273 : struct xfs_trans **tpp);
274 : int xfs_trans_reserve_more_inode(struct xfs_trans *tp, struct xfs_inode *ip,
275 : unsigned int dblocks, unsigned int rblocks, bool force_quota);
276 : int xfs_trans_alloc_icreate(struct xfs_mount *mp, struct xfs_trans_res *resv,
277 : struct xfs_dquot *udqp, struct xfs_dquot *gdqp,
278 : struct xfs_dquot *pdqp, unsigned int dblocks,
279 : struct xfs_trans **tpp);
280 : int xfs_trans_alloc_ichange(struct xfs_inode *ip, struct xfs_dquot *udqp,
281 : struct xfs_dquot *gdqp, struct xfs_dquot *pdqp, bool force,
282 : struct xfs_trans **tpp);
283 : int xfs_trans_alloc_dir(struct xfs_inode *dp, struct xfs_trans_res *resv,
284 : struct xfs_inode *ip, unsigned int *dblocks,
285 : struct xfs_trans **tpp, int *nospace_error);
286 :
287 : static inline void
288 3494662534 : xfs_trans_set_context(
289 : struct xfs_trans *tp)
290 : {
291 3494662534 : ASSERT(current->journal_info == NULL);
292 3494662534 : tp->t_pflags = memalloc_nofs_save();
293 3494662534 : current->journal_info = tp;
294 3494662534 : }
295 :
296 : static inline void
297 5457478976 : xfs_trans_clear_context(
298 : struct xfs_trans *tp)
299 : {
300 5457478976 : if (current->journal_info == tp) {
301 3495670681 : memalloc_nofs_restore(tp->t_pflags);
302 3495670681 : current->journal_info = NULL;
303 : }
304 5457478976 : }
305 :
306 : static inline void
307 1962462323 : xfs_trans_switch_context(
308 : struct xfs_trans *old_tp,
309 : struct xfs_trans *new_tp)
310 : {
311 1962462323 : ASSERT(current->journal_info == old_tp);
312 1962462323 : new_tp->t_pflags = old_tp->t_pflags;
313 1962462323 : old_tp->t_pflags = 0;
314 1962462323 : current->journal_info = new_tp;
315 1962462323 : }
316 :
317 : #endif /* __XFS_TRANS_H__ */
|