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 unsigned long j_trans_id;
71 struct rw_semaphore j_trans_barrier;
72 wait_queue_head_t j_checkpointed;
73
74 spinlock_t j_lock;
75 struct list_head j_la_cleanups;
76 struct work_struct j_recovery_work;
77};
78
79extern spinlock_t trans_inc_lock;
80
81
82static inline unsigned long ocfs2_inc_trans_id(struct ocfs2_journal *j)
83{
84 unsigned long old_id;
85 spin_lock(&trans_inc_lock);
86 old_id = j->j_trans_id++;
87 if (unlikely(!j->j_trans_id))
88 j->j_trans_id = 1;
89 spin_unlock(&trans_inc_lock);
90 return old_id;
91}
92
93static inline void ocfs2_set_ci_lock_trans(struct ocfs2_journal *journal,
94 struct ocfs2_caching_info *ci)
95{
96 spin_lock(&trans_inc_lock);
97 ci->ci_last_trans = journal->j_trans_id;
98 spin_unlock(&trans_inc_lock);
99}
100
101
102
103
104
105
106static inline int ocfs2_ci_fully_checkpointed(struct ocfs2_caching_info *ci)
107{
108 int ret;
109 struct ocfs2_journal *journal =
110 OCFS2_SB(ocfs2_metadata_cache_get_super(ci))->journal;
111
112 spin_lock(&trans_inc_lock);
113 ret = time_after(journal->j_trans_id, ci->ci_last_trans);
114 spin_unlock(&trans_inc_lock);
115 return ret;
116}
117
118
119
120
121
122static inline int ocfs2_ci_is_new(struct ocfs2_caching_info *ci)
123{
124 int ret;
125 struct ocfs2_journal *journal =
126 OCFS2_SB(ocfs2_metadata_cache_get_super(ci))->journal;
127
128 spin_lock(&trans_inc_lock);
129 ret = !(time_after(journal->j_trans_id, ci->ci_created_trans));
130 if (!ret)
131 ci->ci_created_trans = 0;
132 spin_unlock(&trans_inc_lock);
133 return ret;
134}
135
136
137static inline int ocfs2_inode_is_new(struct inode *inode)
138{
139
140
141
142 if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SYSTEM_FILE)
143 return 0;
144
145 return ocfs2_ci_is_new(INODE_CACHE(inode));
146}
147
148static inline void ocfs2_ci_set_new(struct ocfs2_super *osb,
149 struct ocfs2_caching_info *ci)
150{
151 spin_lock(&trans_inc_lock);
152 ci->ci_created_trans = osb->journal->j_trans_id;
153 spin_unlock(&trans_inc_lock);
154}
155
156
157void ocfs2_orphan_scan_init(struct ocfs2_super *osb);
158void ocfs2_orphan_scan_start(struct ocfs2_super *osb);
159void ocfs2_orphan_scan_stop(struct ocfs2_super *osb);
160void ocfs2_orphan_scan_exit(struct ocfs2_super *osb);
161
162void ocfs2_complete_recovery(struct work_struct *work);
163void ocfs2_wait_for_recovery(struct ocfs2_super *osb);
164
165int ocfs2_recovery_init(struct ocfs2_super *osb);
166void ocfs2_recovery_exit(struct ocfs2_super *osb);
167
168int ocfs2_compute_replay_slots(struct ocfs2_super *osb);
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185void ocfs2_set_journal_params(struct ocfs2_super *osb);
186int ocfs2_journal_init(struct ocfs2_journal *journal,
187 int *dirty);
188void ocfs2_journal_shutdown(struct ocfs2_super *osb);
189int ocfs2_journal_wipe(struct ocfs2_journal *journal,
190 int full);
191int ocfs2_journal_load(struct ocfs2_journal *journal, int local,
192 int replayed);
193int ocfs2_check_journals_nolocks(struct ocfs2_super *osb);
194void ocfs2_recovery_thread(struct ocfs2_super *osb,
195 int node_num);
196int ocfs2_mark_dead_nodes(struct ocfs2_super *osb);
197void ocfs2_complete_mount_recovery(struct ocfs2_super *osb);
198void ocfs2_complete_quota_recovery(struct ocfs2_super *osb);
199
200static inline void ocfs2_start_checkpoint(struct ocfs2_super *osb)
201{
202 atomic_set(&osb->needs_checkpoint, 1);
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);
261
262
263
264
265
266
267
268
269
270
271
272
273#define OCFS2_JOURNAL_ACCESS_CREATE 0
274#define OCFS2_JOURNAL_ACCESS_WRITE 1
275#define OCFS2_JOURNAL_ACCESS_UNDO 2
276
277
278
279int ocfs2_journal_access_di(handle_t *handle, struct ocfs2_caching_info *ci,
280 struct buffer_head *bh, int type);
281
282int ocfs2_journal_access_eb(handle_t *handle, struct ocfs2_caching_info *ci,
283 struct buffer_head *bh, int type);
284
285int ocfs2_journal_access_rb(handle_t *handle, struct ocfs2_caching_info *ci,
286 struct buffer_head *bh, int type);
287
288int ocfs2_journal_access_gd(handle_t *handle, struct ocfs2_caching_info *ci,
289 struct buffer_head *bh, int type);
290
291int ocfs2_journal_access_xb(handle_t *handle, struct ocfs2_caching_info *ci,
292 struct buffer_head *bh, int type);
293
294int ocfs2_journal_access_dq(handle_t *handle, struct ocfs2_caching_info *ci,
295 struct buffer_head *bh, int type);
296
297int ocfs2_journal_access_db(handle_t *handle, struct ocfs2_caching_info *ci,
298 struct buffer_head *bh, int type);
299
300int ocfs2_journal_access_dr(handle_t *handle, struct ocfs2_caching_info *ci,
301 struct buffer_head *bh, int type);
302
303int ocfs2_journal_access_dl(handle_t *handle, struct ocfs2_caching_info *ci,
304 struct buffer_head *bh, int type);
305
306int ocfs2_journal_access(handle_t *handle, struct ocfs2_caching_info *ci,
307 struct buffer_head *bh, int type);
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328int ocfs2_journal_dirty(handle_t *handle,
329 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 + 2 + 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
445static inline int ocfs2_link_credits(struct super_block *sb)
446{
447 return 2*OCFS2_INODE_UPDATE_CREDITS + 3 +
448 ocfs2_quota_trans_credits(sb);
449}
450
451
452
453static inline int ocfs2_unlink_credits(struct super_block *sb)
454{
455
456 return 2 * OCFS2_INODE_UPDATE_CREDITS + 3 + ocfs2_link_credits(sb);
457}
458
459
460
461
462#define OCFS2_DELETE_INODE_CREDITS (3 * OCFS2_INODE_UPDATE_CREDITS + 4)
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 u32 bits_wanted)
518{
519 int bitmap_blocks, sysfile_bitmap_blocks, extent_blocks;
520
521
522 bitmap_blocks = OCFS2_SUBALLOC_ALLOC;
523
524
525
526
527
528
529 sysfile_bitmap_blocks = 1 +
530 (OCFS2_SUBALLOC_ALLOC - 1) * ocfs2_extend_meta_needed(root_el);
531
532
533
534
535
536
537 extent_blocks = 1 + 1 + le16_to_cpu(root_el->l_tree_depth);
538
539 return bitmap_blocks + sysfile_bitmap_blocks + extent_blocks +
540 ocfs2_quota_trans_credits(sb);
541}
542
543static inline int ocfs2_calc_symlink_credits(struct super_block *sb)
544{
545 int blocks = ocfs2_mknod_credits(sb, 0, 0);
546
547
548
549 blocks += ocfs2_clusters_to_blocks(sb, 1);
550
551 return blocks + ocfs2_quota_trans_credits(sb);
552}
553
554static inline int ocfs2_calc_group_alloc_credits(struct super_block *sb,
555 unsigned int cpg)
556{
557 int blocks;
558 int bitmap_blocks = OCFS2_SUBALLOC_ALLOC + 1;
559
560
561 blocks = 1 + 1 + 1 + bitmap_blocks;
562 return blocks;
563}
564
565static inline int ocfs2_calc_tree_trunc_credits(struct super_block *sb,
566 unsigned int clusters_to_del,
567 struct ocfs2_dinode *fe,
568 struct ocfs2_extent_list *last_el)
569{
570
571 u16 next_free = le16_to_cpu(last_el->l_next_free_rec);
572 u16 tree_depth = le16_to_cpu(fe->id2.i_list.l_tree_depth);
573 int credits = 1 + tree_depth + 1;
574 int i;
575
576 i = next_free - 1;
577 BUG_ON(i < 0);
578
579
580
581 if (tree_depth && next_free == 1 &&
582 ocfs2_rec_clusters(last_el, &last_el->l_recs[i]) == clusters_to_del)
583 credits += 1 + tree_depth;
584
585
586 credits += OCFS2_TRUNCATE_LOG_UPDATE;
587
588 credits += ocfs2_quota_trans_credits(sb);
589
590 return credits;
591}
592
593static inline int ocfs2_jbd2_file_inode(handle_t *handle, struct inode *inode)
594{
595 return jbd2_journal_file_inode(handle, &OCFS2_I(inode)->ip_jinode);
596}
597
598static inline int ocfs2_begin_ordered_truncate(struct inode *inode,
599 loff_t new_size)
600{
601 return jbd2_journal_begin_ordered_truncate(
602 OCFS2_SB(inode->i_sb)->journal->j_journal,
603 &OCFS2_I(inode)->ip_jinode,
604 new_size);
605}
606
607#endif
608