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 atomic_set(&osb->needs_checkpoint, 1);
204 wake_up(&osb->checkpoint_event);
205}
206
207static inline void ocfs2_checkpoint_inode(struct inode *inode)
208{
209 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
210
211 if (ocfs2_mount_local(osb))
212 return;
213
214 if (!ocfs2_ci_fully_checkpointed(INODE_CACHE(inode))) {
215
216
217
218
219
220
221 ocfs2_start_checkpoint(osb);
222
223 wait_event(osb->journal->j_checkpointed,
224 ocfs2_ci_fully_checkpointed(INODE_CACHE(inode)));
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
256
257handle_t *ocfs2_start_trans(struct ocfs2_super *osb,
258 int max_buffs);
259int ocfs2_commit_trans(struct ocfs2_super *osb,
260 handle_t *handle);
261int ocfs2_extend_trans(handle_t *handle, int nblocks);
262
263
264
265
266
267
268
269
270
271
272
273
274#define OCFS2_JOURNAL_ACCESS_CREATE 0
275#define OCFS2_JOURNAL_ACCESS_WRITE 1
276#define OCFS2_JOURNAL_ACCESS_UNDO 2
277
278
279
280int ocfs2_journal_access_di(handle_t *handle, struct ocfs2_caching_info *ci,
281 struct buffer_head *bh, int type);
282
283int ocfs2_journal_access_eb(handle_t *handle, struct ocfs2_caching_info *ci,
284 struct buffer_head *bh, int type);
285
286int ocfs2_journal_access_rb(handle_t *handle, struct ocfs2_caching_info *ci,
287 struct buffer_head *bh, int type);
288
289int ocfs2_journal_access_gd(handle_t *handle, struct ocfs2_caching_info *ci,
290 struct buffer_head *bh, int type);
291
292int ocfs2_journal_access_xb(handle_t *handle, struct ocfs2_caching_info *ci,
293 struct buffer_head *bh, int type);
294
295int ocfs2_journal_access_dq(handle_t *handle, struct ocfs2_caching_info *ci,
296 struct buffer_head *bh, int type);
297
298int ocfs2_journal_access_db(handle_t *handle, struct ocfs2_caching_info *ci,
299 struct buffer_head *bh, int type);
300
301int ocfs2_journal_access_dr(handle_t *handle, struct ocfs2_caching_info *ci,
302 struct buffer_head *bh, int type);
303
304int ocfs2_journal_access_dl(handle_t *handle, struct ocfs2_caching_info *ci,
305 struct buffer_head *bh, int type);
306
307int ocfs2_journal_access(handle_t *handle, struct ocfs2_caching_info *ci,
308 struct buffer_head *bh, int type);
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329void ocfs2_journal_dirty(handle_t *handle, struct buffer_head *bh);
330
331
332
333
334
335
336
337
338
339
340
341#define OCFS2_INODE_UPDATE_CREDITS 1
342
343
344#define OCFS2_XATTR_BLOCK_UPDATE_CREDITS 1
345
346
347#define OCFS2_QUOTA_BLOCK_UPDATE_CREDITS 1
348
349
350#define OCFS2_QINFO_WRITE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + \
351 OCFS2_QUOTA_BLOCK_UPDATE_CREDITS)
352
353#define OCFS2_LOCAL_QINFO_WRITE_CREDITS OCFS2_QUOTA_BLOCK_UPDATE_CREDITS
354
355
356
357
358
359
360#define OCFS2_QWRITE_CREDITS (OCFS2_QINFO_WRITE_CREDITS + \
361 OCFS2_QUOTA_BLOCK_UPDATE_CREDITS)
362
363
364
365#define OCFS2_QSYNC_CREDITS (OCFS2_QINFO_WRITE_CREDITS + \
366 2 * OCFS2_QUOTA_BLOCK_UPDATE_CREDITS)
367
368static inline int ocfs2_quota_trans_credits(struct super_block *sb)
369{
370 int credits = 0;
371
372 if (OCFS2_HAS_RO_COMPAT_FEATURE(sb, OCFS2_FEATURE_RO_COMPAT_USRQUOTA))
373 credits += OCFS2_QWRITE_CREDITS;
374 if (OCFS2_HAS_RO_COMPAT_FEATURE(sb, OCFS2_FEATURE_RO_COMPAT_GRPQUOTA))
375 credits += OCFS2_QWRITE_CREDITS;
376 return credits;
377}
378
379
380#define OCFS2_GROUP_EXTEND_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1)
381
382
383#define OCFS2_GROUP_ADD_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1)
384
385
386
387#define OCFS2_SUBALLOC_ALLOC (3)
388
389static inline int ocfs2_inline_to_extents_credits(struct super_block *sb)
390{
391 return OCFS2_SUBALLOC_ALLOC + OCFS2_INODE_UPDATE_CREDITS +
392 ocfs2_quota_trans_credits(sb);
393}
394
395
396#define OCFS2_SUBALLOC_FREE (2)
397
398#define OCFS2_TRUNCATE_LOG_UPDATE OCFS2_INODE_UPDATE_CREDITS
399#define OCFS2_TRUNCATE_LOG_FLUSH_ONE_REC (OCFS2_SUBALLOC_FREE \
400 + OCFS2_TRUNCATE_LOG_UPDATE)
401
402static inline int ocfs2_remove_extent_credits(struct super_block *sb)
403{
404 return OCFS2_TRUNCATE_LOG_UPDATE + OCFS2_INODE_UPDATE_CREDITS +
405 ocfs2_quota_trans_credits(sb);
406}
407
408
409
410#define OCFS2_DIR_LINK_ADDITIONAL_CREDITS (1 + OCFS2_SUBALLOC_ALLOC + 1)
411
412static inline int ocfs2_add_dir_index_credits(struct super_block *sb)
413{
414
415
416 return 1 + 2 * OCFS2_SUBALLOC_ALLOC +
417 ocfs2_clusters_to_blocks(sb, 1);
418}
419
420
421
422
423static inline int ocfs2_mknod_credits(struct super_block *sb, int is_dir,
424 int xattr_credits)
425{
426 int dir_credits = OCFS2_DIR_LINK_ADDITIONAL_CREDITS;
427
428 if (is_dir)
429 dir_credits += ocfs2_add_dir_index_credits(sb);
430
431 return 4 + OCFS2_SUBALLOC_ALLOC + dir_credits + xattr_credits +
432 ocfs2_quota_trans_credits(sb);
433}
434
435
436#define OCFS2_WINDOW_MOVE_CREDITS (OCFS2_INODE_UPDATE_CREDITS \
437 + OCFS2_SUBALLOC_ALLOC + OCFS2_SUBALLOC_FREE)
438
439
440
441#define OCFS2_SIMPLE_DIR_EXTEND_CREDITS (2)
442
443
444
445
446static inline int ocfs2_link_credits(struct super_block *sb)
447{
448 return 2*OCFS2_INODE_UPDATE_CREDITS + 4 +
449 ocfs2_quota_trans_credits(sb);
450}
451
452
453
454static inline int ocfs2_unlink_credits(struct super_block *sb)
455{
456
457 return 2 * OCFS2_INODE_UPDATE_CREDITS + 3 + ocfs2_link_credits(sb);
458}
459
460
461
462
463#define OCFS2_DELETE_INODE_CREDITS (3 * OCFS2_INODE_UPDATE_CREDITS + 4)
464
465
466
467
468static inline int ocfs2_rename_credits(struct super_block *sb)
469{
470 return 3 * OCFS2_INODE_UPDATE_CREDITS + 6 + ocfs2_unlink_credits(sb);
471}
472
473
474
475
476#define OCFS2_XATTR_BLOCK_CREATE_CREDITS (OCFS2_SUBALLOC_ALLOC * 2 + \
477 + OCFS2_INODE_UPDATE_CREDITS \
478 + OCFS2_XATTR_BLOCK_UPDATE_CREDITS)
479
480
481#define OCFS2_DX_ROOT_REMOVE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + \
482 OCFS2_SUBALLOC_FREE)
483
484static inline int ocfs2_calc_dxi_expand_credits(struct super_block *sb)
485{
486 int credits = 1 + OCFS2_SUBALLOC_ALLOC;
487
488 credits += ocfs2_clusters_to_blocks(sb, 1);
489 credits += ocfs2_quota_trans_credits(sb);
490
491 return credits;
492}
493
494
495#define OCFS2_REFCOUNT_TREE_CREATE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1 \
496 + OCFS2_SUBALLOC_ALLOC)
497
498
499#define OCFS2_REFCOUNT_TREE_SET_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1)
500
501
502
503
504
505
506#define OCFS2_REFCOUNT_TREE_REMOVE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1)
507
508
509#define OCFS2_EXPAND_REFCOUNT_TREE_CREDITS (OCFS2_SUBALLOC_ALLOC * 2 + 3)
510
511
512
513
514
515
516static inline int ocfs2_calc_extend_credits(struct super_block *sb,
517 struct ocfs2_extent_list *root_el,
518 u32 bits_wanted)
519{
520 int bitmap_blocks, sysfile_bitmap_blocks, extent_blocks;
521
522
523 bitmap_blocks = OCFS2_SUBALLOC_ALLOC;
524
525
526
527
528
529
530 sysfile_bitmap_blocks = 1 +
531 (OCFS2_SUBALLOC_ALLOC - 1) * ocfs2_extend_meta_needed(root_el);
532
533
534
535
536
537
538 extent_blocks = 1 + 1 + le16_to_cpu(root_el->l_tree_depth);
539
540 return bitmap_blocks + sysfile_bitmap_blocks + extent_blocks +
541 ocfs2_quota_trans_credits(sb);
542}
543
544static inline int ocfs2_calc_symlink_credits(struct super_block *sb)
545{
546 int blocks = ocfs2_mknod_credits(sb, 0, 0);
547
548
549
550 blocks += ocfs2_clusters_to_blocks(sb, 1);
551
552 return blocks + ocfs2_quota_trans_credits(sb);
553}
554
555static inline int ocfs2_calc_group_alloc_credits(struct super_block *sb,
556 unsigned int cpg)
557{
558 int blocks;
559 int bitmap_blocks = OCFS2_SUBALLOC_ALLOC + 1;
560
561
562 blocks = 1 + 1 + 1 + bitmap_blocks;
563 return blocks;
564}
565
566
567
568
569
570
571
572
573static inline int ocfs2_calc_bg_discontig_credits(struct super_block *sb)
574{
575 return ocfs2_extent_recs_per_gd(sb);
576}
577
578static inline int ocfs2_calc_tree_trunc_credits(struct super_block *sb,
579 unsigned int clusters_to_del,
580 struct ocfs2_dinode *fe,
581 struct ocfs2_extent_list *last_el)
582{
583
584 u16 next_free = le16_to_cpu(last_el->l_next_free_rec);
585 u16 tree_depth = le16_to_cpu(fe->id2.i_list.l_tree_depth);
586 int credits = 1 + tree_depth + 1;
587 int i;
588
589 i = next_free - 1;
590 BUG_ON(i < 0);
591
592
593
594 if (tree_depth && next_free == 1 &&
595 ocfs2_rec_clusters(last_el, &last_el->l_recs[i]) == clusters_to_del)
596 credits += 1 + tree_depth;
597
598
599 credits += OCFS2_TRUNCATE_LOG_UPDATE;
600
601 credits += ocfs2_quota_trans_credits(sb);
602
603 return credits;
604}
605
606static inline int ocfs2_jbd2_file_inode(handle_t *handle, struct inode *inode)
607{
608 return jbd2_journal_file_inode(handle, &OCFS2_I(inode)->ip_jinode);
609}
610
611static inline int ocfs2_begin_ordered_truncate(struct inode *inode,
612 loff_t new_size)
613{
614 return jbd2_journal_begin_ordered_truncate(
615 OCFS2_SB(inode->i_sb)->journal->j_journal,
616 &OCFS2_I(inode)->ip_jinode,
617 new_size);
618}
619
620#endif
621