xfs_trans.h 9.78 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
Linus Torvalds's avatar
Linus Torvalds committed
2
/*
3 4
 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
 * All Rights Reserved.
Linus Torvalds's avatar
Linus Torvalds committed
5 6 7 8
 */
#ifndef	__XFS_TRANS_H__
#define	__XFS_TRANS_H__

9
/* kernel only transaction subsystem defines */
10

11
struct xlog;
12 13 14 15 16 17 18 19 20
struct xfs_buf;
struct xfs_buftarg;
struct xfs_efd_log_item;
struct xfs_efi_log_item;
struct xfs_inode;
struct xfs_item_ops;
struct xfs_log_iovec;
struct xfs_mount;
struct xfs_trans;
21
struct xfs_trans_res;
22
struct xfs_dquot_acct;
23 24
struct xfs_rud_log_item;
struct xfs_rui_log_item;
25
struct xfs_btree_cur;
26
struct xfs_cui_log_item;
27
struct xfs_cud_log_item;
Darrick J. Wong's avatar
Darrick J. Wong committed
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 */
Dave Chinner's avatar
Dave Chinner committed
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 */
Christoph Hellwig's avatar
Christoph Hellwig committed
41
	const struct xfs_item_ops	*li_ops;	/* function list */
42 43 44 45

	/* delayed logging */
	struct list_head		li_cil;		/* CIL pointers */
	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

Dave Chinner's avatar
Dave Chinner committed
51 52 53 54 55 56 57 58
/*
 * li_flags use the (set/test/clear)_bit atomic interfaces because updates can
 * race with each other and we don't want to have to use the AIL lock to
 * serialise all updates.
 */
#define	XFS_LI_IN_AIL	0
#define	XFS_LI_ABORTED	1
#define	XFS_LI_FAILED	2
Dave Chinner's avatar
Dave Chinner committed
59 60
#define	XFS_LI_DIRTY	3
#define	XFS_LI_WHITEOUT	4
61

Christoph Hellwig's avatar
Christoph Hellwig committed
62
#define XFS_LI_FLAGS \
63 64 65
	{ (1u << XFS_LI_IN_AIL),	"IN_AIL" }, \
	{ (1u << XFS_LI_ABORTED),	"ABORTED" }, \
	{ (1u << XFS_LI_FAILED),	"FAILED" }, \
Dave Chinner's avatar
Dave Chinner committed
66 67
	{ (1u << XFS_LI_DIRTY),		"DIRTY" }, \
	{ (1u << XFS_LI_WHITEOUT),	"WHITEOUT" }
Christoph Hellwig's avatar
Christoph Hellwig committed
68

Christoph Hellwig's avatar
Christoph Hellwig committed
69
struct xfs_item_ops {
70
	unsigned flags;
71 72 73 74
	void (*iop_size)(struct xfs_log_item *, int *, int *);
	void (*iop_format)(struct xfs_log_item *, struct xfs_log_vec *);
	void (*iop_pin)(struct xfs_log_item *);
	void (*iop_unpin)(struct xfs_log_item *, int remove);
75
	uint (*iop_push)(struct xfs_log_item *, struct list_head *);
76
	void (*iop_committing)(struct xfs_log_item *lip, xfs_csn_t seq);
Christoph Hellwig's avatar
Christoph Hellwig committed
77
	void (*iop_release)(struct xfs_log_item *);
78
	xfs_lsn_t (*iop_committed)(struct xfs_log_item *, xfs_lsn_t);
79 80
	int (*iop_recover)(struct xfs_log_item *lip,
			   struct list_head *capture_list);
81
	bool (*iop_match)(struct xfs_log_item *item, uint64_t id);
82 83
	struct xfs_log_item *(*iop_relog)(struct xfs_log_item *intent,
			struct xfs_trans *tp);
84
	struct xfs_log_item *(*iop_intent)(struct xfs_log_item *intent_done);
Christoph Hellwig's avatar
Christoph Hellwig committed
85
};
86

87 88 89 90 91 92 93 94 95 96 97
/*
 * Log item ops flags
 */
/*
 * Release the log item when the journal commits instead of inserting into the
 * AIL for writeback tracking and/or log tail pinning.
 */
#define XFS_ITEM_RELEASE_WHEN_COMMITTED	(1 << 0)
#define XFS_ITEM_INTENT			(1 << 1)
#define XFS_ITEM_INTENT_DONE		(1 << 2)

98 99 100
static inline bool
xlog_item_is_intent(struct xfs_log_item *lip)
{
101
	return lip->li_ops->flags & XFS_ITEM_INTENT;
102 103 104 105 106
}

static inline bool
xlog_item_is_intent_done(struct xfs_log_item *lip)
{
107
	return lip->li_ops->flags & XFS_ITEM_INTENT_DONE;
108 109
}

110 111 112
void	xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item,
			  int type, const struct xfs_item_ops *ops);

113
/*
114
 * Return values for the iop_push() routines.
115
 */
116 117 118 119
#define XFS_ITEM_SUCCESS	0
#define XFS_ITEM_PINNED		1
#define XFS_ITEM_LOCKED		2
#define XFS_ITEM_FLUSHING	3
120 121 122 123 124 125 126 127 128 129 130 131

/*
 * This is the structure maintained for every active transaction.
 */
typedef struct xfs_trans {
	unsigned int		t_magic;	/* magic number */
	unsigned int		t_log_res;	/* amt of log space resvd */
	unsigned int		t_log_count;	/* count for perm log res */
	unsigned int		t_blk_res;	/* # of blocks resvd */
	unsigned int		t_blk_res_used;	/* # of resvd blocks used */
	unsigned int		t_rtx_res;	/* # of rt extents resvd */
	unsigned int		t_rtx_res_used;	/* # of resvd rt extents used */
132
	unsigned int		t_flags;	/* misc flags */
133
	xfs_fsblock_t		t_firstblock;	/* first block allocated */
134
	struct xlog_ticket	*t_ticket;	/* log mgr ticket */
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
	struct xfs_mount	*t_mountp;	/* ptr to fs mount struct */
	struct xfs_dquot_acct   *t_dqinfo;	/* acctg info for dquots */
	int64_t			t_icount_delta;	/* superblock icount change */
	int64_t			t_ifree_delta;	/* superblock ifree change */
	int64_t			t_fdblocks_delta; /* superblock fdblocks chg */
	int64_t			t_res_fdblocks_delta; /* on-disk only chg */
	int64_t			t_frextents_delta;/* superblock freextents chg*/
	int64_t			t_res_frextents_delta; /* on-disk only chg */
	int64_t			t_dblocks_delta;/* superblock dblocks change */
	int64_t			t_agcount_delta;/* superblock agcount change */
	int64_t			t_imaxpct_delta;/* superblock imaxpct change */
	int64_t			t_rextsize_delta;/* superblock rextsize chg */
	int64_t			t_rbmblocks_delta;/* superblock rbmblocks chg */
	int64_t			t_rblocks_delta;/* superblock rblocks change */
	int64_t			t_rextents_delta;/* superblocks rextents chg */
	int64_t			t_rextslog_delta;/* superblocks rextslog chg */
151
	struct list_head	t_items;	/* log item descriptors */
152
	struct list_head	t_busy;		/* list of busy extents */
153
	struct list_head	t_dfops;	/* deferred operations */
154 155 156
	unsigned long		t_pflags;	/* saved process flags state */
} xfs_trans_t;

Linus Torvalds's avatar
Linus Torvalds committed
157 158 159 160 161 162 163 164 165
/*
 * XFS transaction mechanism exported interfaces that are
 * actually macros.
 */
#define	xfs_trans_set_sync(tp)		((tp)->t_flags |= XFS_TRANS_SYNC)

/*
 * XFS transaction mechanism exported interfaces.
 */
166 167 168
int		xfs_trans_alloc(struct xfs_mount *mp, struct xfs_trans_res *resp,
			uint blocks, uint rtextents, uint flags,
			struct xfs_trans **tpp);
169 170
int		xfs_trans_alloc_empty(struct xfs_mount *mp,
			struct xfs_trans **tpp);
171
void		xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t);
172

173 174 175
int xfs_trans_get_buf_map(struct xfs_trans *tp, struct xfs_buftarg *target,
		struct xfs_buf_map *map, int nmaps, xfs_buf_flags_t flags,
		struct xfs_buf **bpp);
176

177
static inline int
178 179 180 181 182
xfs_trans_get_buf(
	struct xfs_trans	*tp,
	struct xfs_buftarg	*target,
	xfs_daddr_t		blkno,
	int			numblks,
183
	xfs_buf_flags_t		flags,
184
	struct xfs_buf		**bpp)
185
{
186
	DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
187
	return xfs_trans_get_buf_map(tp, target, &map, 1, flags, bpp);
188 189 190 191 192 193 194
}

int		xfs_trans_read_buf_map(struct xfs_mount *mp,
				       struct xfs_trans *tp,
				       struct xfs_buftarg *target,
				       struct xfs_buf_map *map, int nmaps,
				       xfs_buf_flags_t flags,
195
				       struct xfs_buf **bpp,
196
				       const struct xfs_buf_ops *ops);
197 198 199 200 201 202 203 204 205

static inline int
xfs_trans_read_buf(
	struct xfs_mount	*mp,
	struct xfs_trans	*tp,
	struct xfs_buftarg	*target,
	xfs_daddr_t		blkno,
	int			numblks,
	xfs_buf_flags_t		flags,
206
	struct xfs_buf		**bpp,
207
	const struct xfs_buf_ops *ops)
208
{
209 210
	DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
	return xfs_trans_read_buf_map(mp, tp, target, &map, 1,
211
				      flags, bpp, ops);
212 213
}

214
struct xfs_buf	*xfs_trans_getsb(struct xfs_trans *);
Linus Torvalds's avatar
Linus Torvalds committed
215 216 217 218

void		xfs_trans_brelse(xfs_trans_t *, struct xfs_buf *);
void		xfs_trans_bjoin(xfs_trans_t *, struct xfs_buf *);
void		xfs_trans_bhold(xfs_trans_t *, struct xfs_buf *);
219
void		xfs_trans_bhold_release(xfs_trans_t *, struct xfs_buf *);
Linus Torvalds's avatar
Linus Torvalds committed
220 221 222
void		xfs_trans_binval(xfs_trans_t *, struct xfs_buf *);
void		xfs_trans_inode_buf(xfs_trans_t *, struct xfs_buf *);
void		xfs_trans_stale_inode_buf(xfs_trans_t *, struct xfs_buf *);
223
bool		xfs_trans_ordered_buf(xfs_trans_t *, struct xfs_buf *);
Linus Torvalds's avatar
Linus Torvalds committed
224 225
void		xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint);
void		xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *);
226
void		xfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int);
227
void		xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *, uint);
228 229 230
void		xfs_trans_log_buf(struct xfs_trans *, struct xfs_buf *, uint,
				  uint);
void		xfs_trans_dirty_buf(struct xfs_trans *, struct xfs_buf *);
231
bool		xfs_trans_buf_is_dirty(struct xfs_buf *bp);
Linus Torvalds's avatar
Linus Torvalds committed
232
void		xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint);
233

234
int		xfs_trans_commit(struct xfs_trans *);
235 236
int		xfs_trans_roll(struct xfs_trans **);
int		xfs_trans_roll_inode(struct xfs_trans **, struct xfs_inode *);
237
void		xfs_trans_cancel(xfs_trans_t *);
238 239
int		xfs_trans_ail_init(struct xfs_mount *);
void		xfs_trans_ail_destroy(struct xfs_mount *);
Linus Torvalds's avatar
Linus Torvalds committed
240

241 242 243 244 245
void		xfs_trans_buf_set_type(struct xfs_trans *, struct xfs_buf *,
				       enum xfs_blft);
void		xfs_trans_buf_copy_type(struct xfs_buf *dst_bp,
					struct xfs_buf *src_bp);

246
extern struct kmem_cache	*xfs_trans_cache;
David Chinner's avatar
David Chinner committed
247

248 249 250 251 252 253 254 255
static inline struct xfs_log_item *
xfs_trans_item_relog(
	struct xfs_log_item	*lip,
	struct xfs_trans	*tp)
{
	return lip->li_ops->iop_relog(lip, tp);
}

256 257
struct xfs_dquot;

258
int xfs_trans_alloc_inode(struct xfs_inode *ip, struct xfs_trans_res *resv,
259 260
		unsigned int dblocks, unsigned int rblocks, bool force,
		struct xfs_trans **tpp);
261 262 263 264
int xfs_trans_alloc_icreate(struct xfs_mount *mp, struct xfs_trans_res *resv,
		struct xfs_dquot *udqp, struct xfs_dquot *gdqp,
		struct xfs_dquot *pdqp, unsigned int dblocks,
		struct xfs_trans **tpp);
265 266 267
int xfs_trans_alloc_ichange(struct xfs_inode *ip, struct xfs_dquot *udqp,
		struct xfs_dquot *gdqp, struct xfs_dquot *pdqp, bool force,
		struct xfs_trans **tpp);
268 269 270
int xfs_trans_alloc_dir(struct xfs_inode *dp, struct xfs_trans_res *resv,
		struct xfs_inode *ip, unsigned int *dblocks,
		struct xfs_trans **tpp, int *nospace_error);
271

272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
static inline void
xfs_trans_set_context(
	struct xfs_trans	*tp)
{
	ASSERT(current->journal_info == NULL);
	tp->t_pflags = memalloc_nofs_save();
	current->journal_info = tp;
}

static inline void
xfs_trans_clear_context(
	struct xfs_trans	*tp)
{
	if (current->journal_info == tp) {
		memalloc_nofs_restore(tp->t_pflags);
		current->journal_info = NULL;
	}
}

static inline void
xfs_trans_switch_context(
	struct xfs_trans	*old_tp,
	struct xfs_trans	*new_tp)
{
	ASSERT(current->journal_info == old_tp);
	new_tp->t_pflags = old_tp->t_pflags;
	old_tp->t_pflags = 0;
	current->journal_info = new_tp;
}

Linus Torvalds's avatar
Linus Torvalds committed
302
#endif	/* __XFS_TRANS_H__ */