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#define OCFS2_INODE_ADD_TO_ORPHAN_CREDITS (2 * OCFS2_INODE_UPDATE_CREDITS + 4)
478#define OCFS2_INODE_DEL_FROM_ORPHAN_CREDITS OCFS2_INODE_ADD_TO_ORPHAN_CREDITS
479
480
481
482
483static inline int ocfs2_rename_credits(struct super_block *sb)
484{
485 return 3 * OCFS2_INODE_UPDATE_CREDITS + 6 + ocfs2_unlink_credits(sb);
486}
487
488
489
490
491#define OCFS2_XATTR_BLOCK_CREATE_CREDITS (OCFS2_SUBALLOC_ALLOC * 2 + \
492 + OCFS2_INODE_UPDATE_CREDITS \
493 + OCFS2_XATTR_BLOCK_UPDATE_CREDITS)
494
495
496#define OCFS2_DX_ROOT_REMOVE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + \
497 OCFS2_SUBALLOC_FREE)
498
499static inline int ocfs2_calc_dxi_expand_credits(struct super_block *sb)
500{
501 int credits = 1 + OCFS2_SUBALLOC_ALLOC;
502
503 credits += ocfs2_clusters_to_blocks(sb, 1);
504 credits += ocfs2_quota_trans_credits(sb);
505
506 return credits;
507}
508
509
510#define OCFS2_REFCOUNT_TREE_CREATE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1 \
511 + OCFS2_SUBALLOC_ALLOC)
512
513
514#define OCFS2_REFCOUNT_TREE_SET_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1)
515
516
517
518
519
520
521#define OCFS2_REFCOUNT_TREE_REMOVE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1)
522
523
524#define OCFS2_EXPAND_REFCOUNT_TREE_CREDITS (OCFS2_SUBALLOC_ALLOC * 2 + 3)
525
526
527
528
529
530
531static inline int ocfs2_calc_extend_credits(struct super_block *sb,
532 struct ocfs2_extent_list *root_el)
533{
534 int bitmap_blocks, sysfile_bitmap_blocks, extent_blocks;
535
536
537 bitmap_blocks = OCFS2_SUBALLOC_ALLOC;
538
539
540
541
542
543
544 sysfile_bitmap_blocks = 1 +
545 (OCFS2_SUBALLOC_ALLOC - 1) * ocfs2_extend_meta_needed(root_el);
546
547
548
549
550
551
552 extent_blocks = 1 + 1 + le16_to_cpu(root_el->l_tree_depth);
553
554 return bitmap_blocks + sysfile_bitmap_blocks + extent_blocks +
555 ocfs2_quota_trans_credits(sb);
556}
557
558static inline int ocfs2_calc_symlink_credits(struct super_block *sb)
559{
560 int blocks = ocfs2_mknod_credits(sb, 0, 0);
561
562
563
564 blocks += ocfs2_clusters_to_blocks(sb, 1);
565
566 return blocks + ocfs2_quota_trans_credits(sb);
567}
568
569static inline int ocfs2_calc_group_alloc_credits(struct super_block *sb,
570 unsigned int cpg)
571{
572 int blocks;
573 int bitmap_blocks = OCFS2_SUBALLOC_ALLOC + 1;
574
575
576 blocks = 1 + 1 + 1 + bitmap_blocks;
577 return blocks;
578}
579
580
581
582
583
584
585
586
587static inline int ocfs2_calc_bg_discontig_credits(struct super_block *sb)
588{
589 return ocfs2_extent_recs_per_gd(sb);
590}
591
592static inline int ocfs2_calc_tree_trunc_credits(struct super_block *sb,
593 unsigned int clusters_to_del,
594 struct ocfs2_dinode *fe,
595 struct ocfs2_extent_list *last_el)
596{
597
598 u16 next_free = le16_to_cpu(last_el->l_next_free_rec);
599 u16 tree_depth = le16_to_cpu(fe->id2.i_list.l_tree_depth);
600 int credits = 1 + tree_depth + 1;
601 int i;
602
603 i = next_free - 1;
604 BUG_ON(i < 0);
605
606
607
608 if (tree_depth && next_free == 1 &&
609 ocfs2_rec_clusters(last_el, &last_el->l_recs[i]) == clusters_to_del)
610 credits += 1 + tree_depth;
611
612
613 credits += OCFS2_TRUNCATE_LOG_UPDATE;
614
615 credits += ocfs2_quota_trans_credits(sb);
616
617 return credits;
618}
619
620static inline int ocfs2_jbd2_file_inode(handle_t *handle, struct inode *inode)
621{
622 return jbd2_journal_inode_add_write(handle, &OCFS2_I(inode)->ip_jinode);
623}
624
625static inline int ocfs2_begin_ordered_truncate(struct inode *inode,
626 loff_t new_size)
627{
628 return jbd2_journal_begin_ordered_truncate(
629 OCFS2_SB(inode->i_sb)->journal->j_journal,
630 &OCFS2_I(inode)->ip_jinode,
631 new_size);
632}
633
634static inline void ocfs2_update_inode_fsync_trans(handle_t *handle,
635 struct inode *inode,
636 int datasync)
637{
638 struct ocfs2_inode_info *oi = OCFS2_I(inode);
639
640 oi->i_sync_tid = handle->h_transaction->t_tid;
641 if (datasync)
642 oi->i_datasync_tid = handle->h_transaction->t_tid;
643}
644
645#endif
646