1
2
3
4
5
6
7
8
9
10#ifndef OCFS2_JOURNAL_H
11#define OCFS2_JOURNAL_H
12
13#include <linux/fs.h>
14#include <linux/jbd2.h>
15
16enum ocfs2_journal_state {
17 OCFS2_JOURNAL_FREE = 0,
18 OCFS2_JOURNAL_LOADED,
19 OCFS2_JOURNAL_IN_SHUTDOWN,
20};
21
22struct ocfs2_super;
23struct ocfs2_dinode;
24
25
26
27
28
29
30struct ocfs2_recovery_map {
31 unsigned int rm_used;
32 unsigned int *rm_entries;
33};
34
35
36struct ocfs2_journal {
37 enum ocfs2_journal_state j_state;
38
39 journal_t *j_journal;
40 struct inode *j_inode;
41
42 struct ocfs2_super *j_osb;
43
44
45
46
47
48
49
50
51 struct buffer_head *j_bh;
52 atomic_t j_num_trans;
53
54 spinlock_t j_lock;
55 unsigned long j_trans_id;
56 struct rw_semaphore j_trans_barrier;
57 wait_queue_head_t j_checkpointed;
58
59
60 struct list_head j_la_cleanups;
61 struct work_struct j_recovery_work;
62};
63
64extern spinlock_t trans_inc_lock;
65
66
67static inline unsigned long ocfs2_inc_trans_id(struct ocfs2_journal *j)
68{
69 unsigned long old_id;
70 spin_lock(&trans_inc_lock);
71 old_id = j->j_trans_id++;
72 if (unlikely(!j->j_trans_id))
73 j->j_trans_id = 1;
74 spin_unlock(&trans_inc_lock);
75 return old_id;
76}
77
78static inline void ocfs2_set_ci_lock_trans(struct ocfs2_journal *journal,
79 struct ocfs2_caching_info *ci)
80{
81 spin_lock(&trans_inc_lock);
82 ci->ci_last_trans = journal->j_trans_id;
83 spin_unlock(&trans_inc_lock);
84}
85
86
87
88
89
90
91static inline int ocfs2_ci_fully_checkpointed(struct ocfs2_caching_info *ci)
92{
93 int ret;
94 struct ocfs2_journal *journal =
95 OCFS2_SB(ocfs2_metadata_cache_get_super(ci))->journal;
96
97 spin_lock(&trans_inc_lock);
98 ret = time_after(journal->j_trans_id, ci->ci_last_trans);
99 spin_unlock(&trans_inc_lock);
100 return ret;
101}
102
103
104
105
106
107static inline int ocfs2_ci_is_new(struct ocfs2_caching_info *ci)
108{
109 int ret;
110 struct ocfs2_journal *journal =
111 OCFS2_SB(ocfs2_metadata_cache_get_super(ci))->journal;
112
113 spin_lock(&trans_inc_lock);
114 ret = !(time_after(journal->j_trans_id, ci->ci_created_trans));
115 if (!ret)
116 ci->ci_created_trans = 0;
117 spin_unlock(&trans_inc_lock);
118 return ret;
119}
120
121
122static inline int ocfs2_inode_is_new(struct inode *inode)
123{
124
125
126
127 if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SYSTEM_FILE)
128 return 0;
129
130 return ocfs2_ci_is_new(INODE_CACHE(inode));
131}
132
133static inline void ocfs2_ci_set_new(struct ocfs2_super *osb,
134 struct ocfs2_caching_info *ci)
135{
136 spin_lock(&trans_inc_lock);
137 ci->ci_created_trans = osb->journal->j_trans_id;
138 spin_unlock(&trans_inc_lock);
139}
140
141
142void ocfs2_orphan_scan_init(struct ocfs2_super *osb);
143void ocfs2_orphan_scan_start(struct ocfs2_super *osb);
144void ocfs2_orphan_scan_stop(struct ocfs2_super *osb);
145
146void ocfs2_complete_recovery(struct work_struct *work);
147void ocfs2_wait_for_recovery(struct ocfs2_super *osb);
148
149int ocfs2_recovery_init(struct ocfs2_super *osb);
150void ocfs2_recovery_exit(struct ocfs2_super *osb);
151
152int ocfs2_compute_replay_slots(struct ocfs2_super *osb);
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170void ocfs2_set_journal_params(struct ocfs2_super *osb);
171int ocfs2_journal_alloc(struct ocfs2_super *osb);
172int ocfs2_journal_init(struct ocfs2_super *osb, int *dirty);
173void ocfs2_journal_shutdown(struct ocfs2_super *osb);
174int ocfs2_journal_wipe(struct ocfs2_journal *journal,
175 int full);
176int ocfs2_journal_load(struct ocfs2_journal *journal, int local,
177 int replayed);
178int ocfs2_check_journals_nolocks(struct ocfs2_super *osb);
179void ocfs2_recovery_thread(struct ocfs2_super *osb,
180 int node_num);
181int ocfs2_mark_dead_nodes(struct ocfs2_super *osb);
182void ocfs2_complete_mount_recovery(struct ocfs2_super *osb);
183void ocfs2_complete_quota_recovery(struct ocfs2_super *osb);
184
185static inline void ocfs2_start_checkpoint(struct ocfs2_super *osb)
186{
187 wake_up(&osb->checkpoint_event);
188}
189
190static inline void ocfs2_checkpoint_inode(struct inode *inode)
191{
192 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
193
194 if (ocfs2_mount_local(osb))
195 return;
196
197 if (!ocfs2_ci_fully_checkpointed(INODE_CACHE(inode))) {
198
199
200
201
202
203
204 ocfs2_start_checkpoint(osb);
205
206 wait_event(osb->journal->j_checkpointed,
207 ocfs2_ci_fully_checkpointed(INODE_CACHE(inode)));
208 }
209}
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240handle_t *ocfs2_start_trans(struct ocfs2_super *osb,
241 int max_buffs);
242int ocfs2_commit_trans(struct ocfs2_super *osb,
243 handle_t *handle);
244int ocfs2_extend_trans(handle_t *handle, int nblocks);
245int ocfs2_allocate_extend_trans(handle_t *handle,
246 int thresh);
247
248
249
250
251
252
253
254
255#define OCFS2_MAX_TRANS_DATA 64U
256
257
258
259
260
261
262
263
264
265
266
267
268#define OCFS2_JOURNAL_ACCESS_CREATE 0
269#define OCFS2_JOURNAL_ACCESS_WRITE 1
270#define OCFS2_JOURNAL_ACCESS_UNDO 2
271
272
273
274int ocfs2_journal_access_di(handle_t *handle, struct ocfs2_caching_info *ci,
275 struct buffer_head *bh, int type);
276
277int ocfs2_journal_access_eb(handle_t *handle, struct ocfs2_caching_info *ci,
278 struct buffer_head *bh, int type);
279
280int ocfs2_journal_access_rb(handle_t *handle, struct ocfs2_caching_info *ci,
281 struct buffer_head *bh, int type);
282
283int ocfs2_journal_access_gd(handle_t *handle, struct ocfs2_caching_info *ci,
284 struct buffer_head *bh, int type);
285
286int ocfs2_journal_access_xb(handle_t *handle, struct ocfs2_caching_info *ci,
287 struct buffer_head *bh, int type);
288
289int ocfs2_journal_access_dq(handle_t *handle, struct ocfs2_caching_info *ci,
290 struct buffer_head *bh, int type);
291
292int ocfs2_journal_access_db(handle_t *handle, struct ocfs2_caching_info *ci,
293 struct buffer_head *bh, int type);
294
295int ocfs2_journal_access_dr(handle_t *handle, struct ocfs2_caching_info *ci,
296 struct buffer_head *bh, int type);
297
298int ocfs2_journal_access_dl(handle_t *handle, struct ocfs2_caching_info *ci,
299 struct buffer_head *bh, int type);
300
301int ocfs2_journal_access(handle_t *handle, struct ocfs2_caching_info *ci,
302 struct buffer_head *bh, int type);
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323void ocfs2_journal_dirty(handle_t *handle, struct buffer_head *bh);
324
325
326
327
328
329
330
331
332
333
334
335#define OCFS2_INODE_UPDATE_CREDITS 1
336
337
338#define OCFS2_XATTR_BLOCK_UPDATE_CREDITS 1
339
340
341#define OCFS2_QUOTA_BLOCK_UPDATE_CREDITS 1
342
343
344#define OCFS2_QINFO_WRITE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + \
345 OCFS2_QUOTA_BLOCK_UPDATE_CREDITS)
346
347#define OCFS2_LOCAL_QINFO_WRITE_CREDITS OCFS2_QUOTA_BLOCK_UPDATE_CREDITS
348
349
350
351
352
353
354#define OCFS2_QWRITE_CREDITS (OCFS2_QINFO_WRITE_CREDITS + \
355 OCFS2_QUOTA_BLOCK_UPDATE_CREDITS)
356
357
358
359#define OCFS2_QSYNC_CREDITS (OCFS2_QINFO_WRITE_CREDITS + \
360 2 * OCFS2_QUOTA_BLOCK_UPDATE_CREDITS)
361
362static inline int ocfs2_quota_trans_credits(struct super_block *sb)
363{
364 int credits = 0;
365
366 if (OCFS2_HAS_RO_COMPAT_FEATURE(sb, OCFS2_FEATURE_RO_COMPAT_USRQUOTA))
367 credits += OCFS2_QWRITE_CREDITS;
368 if (OCFS2_HAS_RO_COMPAT_FEATURE(sb, OCFS2_FEATURE_RO_COMPAT_GRPQUOTA))
369 credits += OCFS2_QWRITE_CREDITS;
370 return credits;
371}
372
373
374#define OCFS2_GROUP_EXTEND_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1)
375
376
377#define OCFS2_GROUP_ADD_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1)
378
379
380
381#define OCFS2_SUBALLOC_ALLOC (3)
382
383static inline int ocfs2_inline_to_extents_credits(struct super_block *sb)
384{
385 return OCFS2_SUBALLOC_ALLOC + OCFS2_INODE_UPDATE_CREDITS +
386 ocfs2_quota_trans_credits(sb);
387}
388
389
390#define OCFS2_SUBALLOC_FREE (2)
391
392#define OCFS2_TRUNCATE_LOG_UPDATE OCFS2_INODE_UPDATE_CREDITS
393#define OCFS2_TRUNCATE_LOG_FLUSH_ONE_REC (OCFS2_SUBALLOC_FREE \
394 + OCFS2_TRUNCATE_LOG_UPDATE)
395
396static inline int ocfs2_remove_extent_credits(struct super_block *sb)
397{
398 return OCFS2_TRUNCATE_LOG_UPDATE + OCFS2_INODE_UPDATE_CREDITS +
399 ocfs2_quota_trans_credits(sb);
400}
401
402
403
404#define OCFS2_DIR_LINK_ADDITIONAL_CREDITS (1 + OCFS2_SUBALLOC_ALLOC + 1)
405
406static inline int ocfs2_add_dir_index_credits(struct super_block *sb)
407{
408
409
410 return 1 + 2 * OCFS2_SUBALLOC_ALLOC +
411 ocfs2_clusters_to_blocks(sb, 1);
412}
413
414
415
416
417static inline int ocfs2_mknod_credits(struct super_block *sb, int is_dir,
418 int xattr_credits)
419{
420 int dir_credits = OCFS2_DIR_LINK_ADDITIONAL_CREDITS;
421
422 if (is_dir)
423 dir_credits += ocfs2_add_dir_index_credits(sb);
424
425 return 4 + OCFS2_SUBALLOC_ALLOC + dir_credits + xattr_credits +
426 ocfs2_quota_trans_credits(sb);
427}
428
429
430#define OCFS2_WINDOW_MOVE_CREDITS (OCFS2_INODE_UPDATE_CREDITS \
431 + OCFS2_SUBALLOC_ALLOC + OCFS2_SUBALLOC_FREE)
432
433
434
435#define OCFS2_SIMPLE_DIR_EXTEND_CREDITS (2)
436
437
438
439
440static inline int ocfs2_link_credits(struct super_block *sb)
441{
442 return 2 * OCFS2_INODE_UPDATE_CREDITS + 4 +
443 ocfs2_quota_trans_credits(sb);
444}
445
446
447
448static inline int ocfs2_unlink_credits(struct super_block *sb)
449{
450
451 return 2 * OCFS2_INODE_UPDATE_CREDITS + 3 + ocfs2_link_credits(sb);
452}
453
454
455
456
457#define OCFS2_DELETE_INODE_CREDITS (3 * OCFS2_INODE_UPDATE_CREDITS + 4)
458
459
460
461#define OCFS2_INODE_ADD_TO_ORPHAN_CREDITS (2 * OCFS2_INODE_UPDATE_CREDITS + 4)
462#define OCFS2_INODE_DEL_FROM_ORPHAN_CREDITS OCFS2_INODE_ADD_TO_ORPHAN_CREDITS
463
464
465
466
467static inline int ocfs2_rename_credits(struct super_block *sb)
468{
469 return 3 * OCFS2_INODE_UPDATE_CREDITS + 6 + ocfs2_unlink_credits(sb);
470}
471
472
473
474
475#define OCFS2_XATTR_BLOCK_CREATE_CREDITS (OCFS2_SUBALLOC_ALLOC * 2 + \
476 + OCFS2_INODE_UPDATE_CREDITS \
477 + OCFS2_XATTR_BLOCK_UPDATE_CREDITS)
478
479
480#define OCFS2_DX_ROOT_REMOVE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + \
481 OCFS2_SUBALLOC_FREE)
482
483static inline int ocfs2_calc_dxi_expand_credits(struct super_block *sb)
484{
485 int credits = 1 + OCFS2_SUBALLOC_ALLOC;
486
487 credits += ocfs2_clusters_to_blocks(sb, 1);
488 credits += ocfs2_quota_trans_credits(sb);
489
490 return credits;
491}
492
493
494#define OCFS2_REFCOUNT_TREE_CREATE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1 \
495 + OCFS2_SUBALLOC_ALLOC)
496
497
498#define OCFS2_REFCOUNT_TREE_SET_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1)
499
500
501
502
503
504
505#define OCFS2_REFCOUNT_TREE_REMOVE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1)
506
507
508#define OCFS2_EXPAND_REFCOUNT_TREE_CREDITS (OCFS2_SUBALLOC_ALLOC * 2 + 3)
509
510
511
512
513
514
515static inline int ocfs2_calc_extend_credits(struct super_block *sb,
516 struct ocfs2_extent_list *root_el)
517{
518 int bitmap_blocks, sysfile_bitmap_blocks, extent_blocks;
519
520
521 bitmap_blocks = OCFS2_SUBALLOC_ALLOC;
522
523
524
525
526
527
528 sysfile_bitmap_blocks = 1 +
529 (OCFS2_SUBALLOC_ALLOC - 1) * ocfs2_extend_meta_needed(root_el);
530
531
532
533
534
535
536 extent_blocks = 1 + 1 + le16_to_cpu(root_el->l_tree_depth);
537
538 return bitmap_blocks + sysfile_bitmap_blocks + extent_blocks +
539 ocfs2_quota_trans_credits(sb);
540}
541
542static inline int ocfs2_calc_symlink_credits(struct super_block *sb)
543{
544 int blocks = ocfs2_mknod_credits(sb, 0, 0);
545
546
547
548 blocks += ocfs2_clusters_to_blocks(sb, 1);
549
550 return blocks + ocfs2_quota_trans_credits(sb);
551}
552
553static inline int ocfs2_calc_group_alloc_credits(struct super_block *sb,
554 unsigned int cpg)
555{
556 int blocks;
557 int bitmap_blocks = OCFS2_SUBALLOC_ALLOC + 1;
558
559
560 blocks = 1 + 1 + 1 + bitmap_blocks;
561 return blocks;
562}
563
564
565
566
567
568
569
570
571static inline int ocfs2_calc_bg_discontig_credits(struct super_block *sb)
572{
573 return ocfs2_extent_recs_per_gd(sb);
574}
575
576static inline int ocfs2_jbd2_inode_add_write(handle_t *handle, struct inode *inode,
577 loff_t start_byte, loff_t length)
578{
579 return jbd2_journal_inode_ranged_write(handle,
580 &OCFS2_I(inode)->ip_jinode,
581 start_byte, length);
582}
583
584static inline int ocfs2_begin_ordered_truncate(struct inode *inode,
585 loff_t new_size)
586{
587 return jbd2_journal_begin_ordered_truncate(
588 OCFS2_SB(inode->i_sb)->journal->j_journal,
589 &OCFS2_I(inode)->ip_jinode,
590 new_size);
591}
592
593static inline void ocfs2_update_inode_fsync_trans(handle_t *handle,
594 struct inode *inode,
595 int datasync)
596{
597 struct ocfs2_inode_info *oi = OCFS2_I(inode);
598
599 if (!is_handle_aborted(handle)) {
600 oi->i_sync_tid = handle->h_transaction->t_tid;
601 if (datasync)
602 oi->i_datasync_tid = handle->h_transaction->t_tid;
603 }
604}
605
606#endif
607