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