1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#ifndef _EXT4_JBD2_H
16#define _EXT4_JBD2_H
17
18#include <linux/fs.h>
19#include <linux/jbd2.h>
20#include "ext4.h"
21
22#define EXT4_JOURNAL(inode) (EXT4_SB((inode)->i_sb)->s_journal)
23
24
25
26
27
28
29
30
31
32
33
34#define EXT4_SINGLEDATA_TRANS_BLOCKS(sb) \
35 (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS) \
36 ? 27U : 8U)
37
38
39
40
41
42#define EXT4_XATTR_TRANS_BLOCKS 6U
43
44
45
46
47
48
49
50#define EXT4_DATA_TRANS_BLOCKS(sb) (EXT4_SINGLEDATA_TRANS_BLOCKS(sb) + \
51 EXT4_XATTR_TRANS_BLOCKS - 2 + \
52 EXT4_MAXQUOTAS_TRANS_BLOCKS(sb))
53
54
55
56
57
58
59#define EXT4_META_TRANS_BLOCKS(sb) (EXT4_XATTR_TRANS_BLOCKS + \
60 EXT4_MAXQUOTAS_TRANS_BLOCKS(sb))
61
62
63
64
65
66#define EXT4_DELETE_TRANS_BLOCKS(sb) (2 * EXT4_DATA_TRANS_BLOCKS(sb) + 64)
67
68
69
70
71
72
73
74#define EXT4_MAX_TRANS_DATA 64U
75
76
77
78
79
80
81
82
83#define EXT4_RESERVE_TRANS_BLOCKS 12U
84
85#define EXT4_INDEX_EXTRA_TRANS_BLOCKS 8
86
87#ifdef CONFIG_QUOTA
88
89
90#define EXT4_QUOTA_TRANS_BLOCKS(sb) ((test_opt(sb, QUOTA) ||\
91 EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA)) ?\
92 1 : 0)
93
94
95#define EXT4_QUOTA_INIT_BLOCKS(sb) ((test_opt(sb, QUOTA) ||\
96 EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA)) ?\
97 (DQUOT_INIT_ALLOC*(EXT4_SINGLEDATA_TRANS_BLOCKS(sb)-3)\
98 +3+DQUOT_INIT_REWRITE) : 0)
99
100#define EXT4_QUOTA_DEL_BLOCKS(sb) ((test_opt(sb, QUOTA) ||\
101 EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA)) ?\
102 (DQUOT_DEL_ALLOC*(EXT4_SINGLEDATA_TRANS_BLOCKS(sb)-3)\
103 +3+DQUOT_DEL_REWRITE) : 0)
104#else
105#define EXT4_QUOTA_TRANS_BLOCKS(sb) 0
106#define EXT4_QUOTA_INIT_BLOCKS(sb) 0
107#define EXT4_QUOTA_DEL_BLOCKS(sb) 0
108#endif
109#define EXT4_MAXQUOTAS_TRANS_BLOCKS(sb) (MAXQUOTAS*EXT4_QUOTA_TRANS_BLOCKS(sb))
110#define EXT4_MAXQUOTAS_INIT_BLOCKS(sb) (MAXQUOTAS*EXT4_QUOTA_INIT_BLOCKS(sb))
111#define EXT4_MAXQUOTAS_DEL_BLOCKS(sb) (MAXQUOTAS*EXT4_QUOTA_DEL_BLOCKS(sb))
112
113
114
115
116
117
118
119
120
121struct ext4_journal_cb_entry {
122
123 struct list_head jce_list;
124
125
126 void (*jce_func)(struct super_block *sb,
127 struct ext4_journal_cb_entry *jce, int error);
128
129
130};
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153static inline void ext4_journal_callback_add(handle_t *handle,
154 void (*func)(struct super_block *sb,
155 struct ext4_journal_cb_entry *jce,
156 int rc),
157 struct ext4_journal_cb_entry *jce)
158{
159 struct ext4_sb_info *sbi =
160 EXT4_SB(handle->h_transaction->t_journal->j_private);
161
162
163 jce->jce_func = func;
164 spin_lock(&sbi->s_md_lock);
165 list_add_tail(&jce->jce_list, &handle->h_transaction->t_private_list);
166 spin_unlock(&sbi->s_md_lock);
167}
168
169
170
171
172
173
174static inline void ext4_journal_callback_del(handle_t *handle,
175 struct ext4_journal_cb_entry *jce)
176{
177 struct ext4_sb_info *sbi =
178 EXT4_SB(handle->h_transaction->t_journal->j_private);
179
180 spin_lock(&sbi->s_md_lock);
181 list_del_init(&jce->jce_list);
182 spin_unlock(&sbi->s_md_lock);
183}
184
185int
186ext4_mark_iloc_dirty(handle_t *handle,
187 struct inode *inode,
188 struct ext4_iloc *iloc);
189
190
191
192
193
194
195int ext4_reserve_inode_write(handle_t *handle, struct inode *inode,
196 struct ext4_iloc *iloc);
197
198int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode);
199
200
201
202
203void ext4_journal_abort_handle(const char *caller, unsigned int line,
204 const char *err_fn,
205 struct buffer_head *bh, handle_t *handle, int err);
206
207int __ext4_journal_get_write_access(const char *where, unsigned int line,
208 handle_t *handle, struct buffer_head *bh);
209
210int __ext4_forget(const char *where, unsigned int line, handle_t *handle,
211 int is_metadata, struct inode *inode,
212 struct buffer_head *bh, ext4_fsblk_t blocknr);
213
214int __ext4_journal_get_create_access(const char *where, unsigned int line,
215 handle_t *handle, struct buffer_head *bh);
216
217int __ext4_handle_dirty_metadata(const char *where, unsigned int line,
218 handle_t *handle, struct inode *inode,
219 struct buffer_head *bh);
220
221int __ext4_handle_dirty_super(const char *where, unsigned int line,
222 handle_t *handle, struct super_block *sb);
223
224#define ext4_journal_get_write_access(handle, bh) \
225 __ext4_journal_get_write_access(__func__, __LINE__, (handle), (bh))
226#define ext4_forget(handle, is_metadata, inode, bh, block_nr) \
227 __ext4_forget(__func__, __LINE__, (handle), (is_metadata), (inode), \
228 (bh), (block_nr))
229#define ext4_journal_get_create_access(handle, bh) \
230 __ext4_journal_get_create_access(__func__, __LINE__, (handle), (bh))
231#define ext4_handle_dirty_metadata(handle, inode, bh) \
232 __ext4_handle_dirty_metadata(__func__, __LINE__, (handle), (inode), \
233 (bh))
234#define ext4_handle_dirty_super(handle, sb) \
235 __ext4_handle_dirty_super(__func__, __LINE__, (handle), (sb))
236
237handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks);
238int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle);
239
240#define EXT4_NOJOURNAL_MAX_REF_COUNT ((unsigned long) 4096)
241
242
243
244static inline int ext4_handle_valid(handle_t *handle)
245{
246 if ((unsigned long)handle < EXT4_NOJOURNAL_MAX_REF_COUNT)
247 return 0;
248 return 1;
249}
250
251static inline void ext4_handle_sync(handle_t *handle)
252{
253 if (ext4_handle_valid(handle))
254 handle->h_sync = 1;
255}
256
257static inline void ext4_handle_release_buffer(handle_t *handle,
258 struct buffer_head *bh)
259{
260 if (ext4_handle_valid(handle))
261 jbd2_journal_release_buffer(handle, bh);
262}
263
264static inline int ext4_handle_is_aborted(handle_t *handle)
265{
266 if (ext4_handle_valid(handle))
267 return is_handle_aborted(handle);
268 return 0;
269}
270
271static inline int ext4_handle_has_enough_credits(handle_t *handle, int needed)
272{
273 if (ext4_handle_valid(handle) && handle->h_buffer_credits < needed)
274 return 0;
275 return 1;
276}
277
278static inline handle_t *ext4_journal_start(struct inode *inode, int nblocks)
279{
280 return ext4_journal_start_sb(inode->i_sb, nblocks);
281}
282
283#define ext4_journal_stop(handle) \
284 __ext4_journal_stop(__func__, __LINE__, (handle))
285
286static inline handle_t *ext4_journal_current_handle(void)
287{
288 return journal_current_handle();
289}
290
291static inline int ext4_journal_extend(handle_t *handle, int nblocks)
292{
293 if (ext4_handle_valid(handle))
294 return jbd2_journal_extend(handle, nblocks);
295 return 0;
296}
297
298static inline int ext4_journal_restart(handle_t *handle, int nblocks)
299{
300 if (ext4_handle_valid(handle))
301 return jbd2_journal_restart(handle, nblocks);
302 return 0;
303}
304
305static inline int ext4_journal_blocks_per_page(struct inode *inode)
306{
307 if (EXT4_JOURNAL(inode) != NULL)
308 return jbd2_journal_blocks_per_page(inode);
309 return 0;
310}
311
312static inline int ext4_journal_force_commit(journal_t *journal)
313{
314 if (journal)
315 return jbd2_journal_force_commit(journal);
316 return 0;
317}
318
319static inline int ext4_jbd2_file_inode(handle_t *handle, struct inode *inode)
320{
321 if (ext4_handle_valid(handle))
322 return jbd2_journal_file_inode(handle, EXT4_I(inode)->jinode);
323 return 0;
324}
325
326static inline void ext4_update_inode_fsync_trans(handle_t *handle,
327 struct inode *inode,
328 int datasync)
329{
330 struct ext4_inode_info *ei = EXT4_I(inode);
331
332 if (ext4_handle_valid(handle)) {
333 ei->i_sync_tid = handle->h_transaction->t_tid;
334 if (datasync)
335 ei->i_datasync_tid = handle->h_transaction->t_tid;
336 }
337}
338
339
340int ext4_force_commit(struct super_block *sb);
341
342
343
344
345#define EXT4_INODE_JOURNAL_DATA_MODE 0x01
346#define EXT4_INODE_ORDERED_DATA_MODE 0x02
347#define EXT4_INODE_WRITEBACK_DATA_MODE 0x04
348
349static inline int ext4_inode_journal_mode(struct inode *inode)
350{
351 if (EXT4_JOURNAL(inode) == NULL)
352 return EXT4_INODE_WRITEBACK_DATA_MODE;
353
354 if (!S_ISREG(inode->i_mode) ||
355 test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
356 return EXT4_INODE_JOURNAL_DATA_MODE;
357 if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA) &&
358 !test_opt(inode->i_sb, DELALLOC))
359 return EXT4_INODE_JOURNAL_DATA_MODE;
360 if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA)
361 return EXT4_INODE_ORDERED_DATA_MODE;
362 if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)
363 return EXT4_INODE_WRITEBACK_DATA_MODE;
364 else
365 BUG();
366}
367
368static inline int ext4_should_journal_data(struct inode *inode)
369{
370 return ext4_inode_journal_mode(inode) & EXT4_INODE_JOURNAL_DATA_MODE;
371}
372
373static inline int ext4_should_order_data(struct inode *inode)
374{
375 return ext4_inode_journal_mode(inode) & EXT4_INODE_ORDERED_DATA_MODE;
376}
377
378static inline int ext4_should_writeback_data(struct inode *inode)
379{
380 return ext4_inode_journal_mode(inode) & EXT4_INODE_WRITEBACK_DATA_MODE;
381}
382
383
384
385
386
387
388
389
390
391
392static inline int ext4_should_dioread_nolock(struct inode *inode)
393{
394 if (!test_opt(inode->i_sb, DIOREAD_NOLOCK))
395 return 0;
396 if (!S_ISREG(inode->i_mode))
397 return 0;
398 if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
399 return 0;
400 if (ext4_should_journal_data(inode))
401 return 0;
402 return 1;
403}
404
405#endif
406