aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2008-09-11 18:53:07 -0400
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:40:31 -0500
commit50655ae9e91d272d48997bada59efe166aa5e343 (patch)
treeca821943897781fe4852c6ac447ccb4760ec8c65 /fs
parentd6b32bbb3eae3fb787f1c33bf9f767ca1ddeb208 (diff)
ocfs2: Add journal_access functions with jbd2 triggers.
We create wrappers for ocfs2_journal_access() that are specific to the type of metadata block. This allows us to associate jbd2 commit triggers with the block. The triggers will compute metadata ecc in a future commit. Signed-off-by: Joel Becker <joel.becker@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ocfs2/journal.c159
-rw-r--r--fs/ocfs2/journal.h31
2 files changed, 181 insertions, 9 deletions
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index 302f1144a70..2daa5848faf 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -35,6 +35,7 @@
35#include "ocfs2.h" 35#include "ocfs2.h"
36 36
37#include "alloc.h" 37#include "alloc.h"
38#include "blockcheck.h"
38#include "dir.h" 39#include "dir.h"
39#include "dlmglue.h" 40#include "dlmglue.h"
40#include "extent_map.h" 41#include "extent_map.h"
@@ -369,10 +370,110 @@ bail:
369 return status; 370 return status;
370} 371}
371 372
372int ocfs2_journal_access(handle_t *handle, 373struct ocfs2_triggers {
373 struct inode *inode, 374 struct jbd2_buffer_trigger_type ot_triggers;
374 struct buffer_head *bh, 375 int ot_offset;
375 int type) 376};
377
378static inline struct ocfs2_triggers *to_ocfs2_trigger(struct jbd2_buffer_trigger_type *triggers)
379{
380 return container_of(triggers, struct ocfs2_triggers, ot_triggers);
381}
382
383static void ocfs2_commit_trigger(struct jbd2_buffer_trigger_type *triggers,
384 struct buffer_head *bh,
385 void *data, size_t size)
386{
387 struct ocfs2_triggers *ot = to_ocfs2_trigger(triggers);
388
389 /*
390 * We aren't guaranteed to have the superblock here, so we
391 * must unconditionally compute the ecc data.
392 * __ocfs2_journal_access() will only set the triggers if
393 * metaecc is enabled.
394 */
395 ocfs2_block_check_compute(data, size, data + ot->ot_offset);
396}
397
398/*
399 * Quota blocks have their own trigger because the struct ocfs2_block_check
400 * offset depends on the blocksize.
401 */
402static void ocfs2_dq_commit_trigger(struct jbd2_buffer_trigger_type *triggers,
403 struct buffer_head *bh,
404 void *data, size_t size)
405{
406 struct ocfs2_disk_dqtrailer *dqt =
407 ocfs2_block_dqtrailer(size, data);
408
409 /*
410 * We aren't guaranteed to have the superblock here, so we
411 * must unconditionally compute the ecc data.
412 * __ocfs2_journal_access() will only set the triggers if
413 * metaecc is enabled.
414 */
415 ocfs2_block_check_compute(data, size, &dqt->dq_check);
416}
417
418static void ocfs2_abort_trigger(struct jbd2_buffer_trigger_type *triggers,
419 struct buffer_head *bh)
420{
421 mlog(ML_ERROR,
422 "ocfs2_abort_trigger called by JBD2. bh = 0x%lx, "
423 "bh->b_blocknr = %llu\n",
424 (unsigned long)bh,
425 (unsigned long long)bh->b_blocknr);
426
427 /* We aren't guaranteed to have the superblock here - but if we
428 * don't, it'll just crash. */
429 ocfs2_error(bh->b_assoc_map->host->i_sb,
430 "JBD2 has aborted our journal, ocfs2 cannot continue\n");
431}
432
433static struct ocfs2_triggers di_triggers = {
434 .ot_triggers = {
435 .t_commit = ocfs2_commit_trigger,
436 .t_abort = ocfs2_abort_trigger,
437 },
438 .ot_offset = offsetof(struct ocfs2_dinode, i_check),
439};
440
441static struct ocfs2_triggers eb_triggers = {
442 .ot_triggers = {
443 .t_commit = ocfs2_commit_trigger,
444 .t_abort = ocfs2_abort_trigger,
445 },
446 .ot_offset = offsetof(struct ocfs2_extent_block, h_check),
447};
448
449static struct ocfs2_triggers gd_triggers = {
450 .ot_triggers = {
451 .t_commit = ocfs2_commit_trigger,
452 .t_abort = ocfs2_abort_trigger,
453 },
454 .ot_offset = offsetof(struct ocfs2_group_desc, bg_check),
455};
456
457static struct ocfs2_triggers xb_triggers = {
458 .ot_triggers = {
459 .t_commit = ocfs2_commit_trigger,
460 .t_abort = ocfs2_abort_trigger,
461 },
462 .ot_offset = offsetof(struct ocfs2_xattr_block, xb_check),
463};
464
465static struct ocfs2_triggers dq_triggers = {
466 .ot_triggers = {
467 .t_commit = ocfs2_dq_commit_trigger,
468 .t_abort = ocfs2_abort_trigger,
469 },
470};
471
472static int __ocfs2_journal_access(handle_t *handle,
473 struct inode *inode,
474 struct buffer_head *bh,
475 struct ocfs2_triggers *triggers,
476 int type)
376{ 477{
377 int status; 478 int status;
378 479
@@ -418,6 +519,8 @@ int ocfs2_journal_access(handle_t *handle,
418 status = -EINVAL; 519 status = -EINVAL;
419 mlog(ML_ERROR, "Uknown access type!\n"); 520 mlog(ML_ERROR, "Uknown access type!\n");
420 } 521 }
522 if (!status && ocfs2_meta_ecc(OCFS2_SB(inode->i_sb)) && triggers)
523 jbd2_journal_set_triggers(bh, &triggers->ot_triggers);
421 mutex_unlock(&OCFS2_I(inode)->ip_io_mutex); 524 mutex_unlock(&OCFS2_I(inode)->ip_io_mutex);
422 525
423 if (status < 0) 526 if (status < 0)
@@ -428,6 +531,54 @@ int ocfs2_journal_access(handle_t *handle,
428 return status; 531 return status;
429} 532}
430 533
534int ocfs2_journal_access_di(handle_t *handle, struct inode *inode,
535 struct buffer_head *bh, int type)
536{
537 return __ocfs2_journal_access(handle, inode, bh, &di_triggers,
538 type);
539}
540
541int ocfs2_journal_access_eb(handle_t *handle, struct inode *inode,
542 struct buffer_head *bh, int type)
543{
544 return __ocfs2_journal_access(handle, inode, bh, &eb_triggers,
545 type);
546}
547
548int ocfs2_journal_access_gd(handle_t *handle, struct inode *inode,
549 struct buffer_head *bh, int type)
550{
551 return __ocfs2_journal_access(handle, inode, bh, &gd_triggers,
552 type);
553}
554
555int ocfs2_journal_access_db(handle_t *handle, struct inode *inode,
556 struct buffer_head *bh, int type)
557{
558 /* Right now, nothing for dirblocks */
559 return __ocfs2_journal_access(handle, inode, bh, NULL, type);
560}
561
562int ocfs2_journal_access_xb(handle_t *handle, struct inode *inode,
563 struct buffer_head *bh, int type)
564{
565 return __ocfs2_journal_access(handle, inode, bh, &xb_triggers,
566 type);
567}
568
569int ocfs2_journal_access_dq(handle_t *handle, struct inode *inode,
570 struct buffer_head *bh, int type)
571{
572 return __ocfs2_journal_access(handle, inode, bh, &dq_triggers,
573 type);
574}
575
576int ocfs2_journal_access(handle_t *handle, struct inode *inode,
577 struct buffer_head *bh, int type)
578{
579 return __ocfs2_journal_access(handle, inode, bh, NULL, type);
580}
581
431int ocfs2_journal_dirty(handle_t *handle, 582int ocfs2_journal_dirty(handle_t *handle,
432 struct buffer_head *bh) 583 struct buffer_head *bh)
433{ 584{
diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h
index 37013bf9ce2..bca370dab02 100644
--- a/fs/ocfs2/journal.h
+++ b/fs/ocfs2/journal.h
@@ -212,9 +212,12 @@ static inline void ocfs2_checkpoint_inode(struct inode *inode)
212 * ocfs2_extend_trans - Extend a handle by nblocks credits. This may 212 * ocfs2_extend_trans - Extend a handle by nblocks credits. This may
213 * commit the handle to disk in the process, but will 213 * commit the handle to disk in the process, but will
214 * not release any locks taken during the transaction. 214 * not release any locks taken during the transaction.
215 * ocfs2_journal_access - Notify the handle that we want to journal this 215 * ocfs2_journal_access* - Notify the handle that we want to journal this
216 * buffer. Will have to call ocfs2_journal_dirty once 216 * buffer. Will have to call ocfs2_journal_dirty once
217 * we've actually dirtied it. Type is one of . or . 217 * we've actually dirtied it. Type is one of . or .
218 * Always call the specific flavor of
219 * ocfs2_journal_access_*() unless you intend to
220 * manage the checksum by hand.
218 * ocfs2_journal_dirty - Mark a journalled buffer as having dirty data. 221 * ocfs2_journal_dirty - Mark a journalled buffer as having dirty data.
219 * ocfs2_jbd2_file_inode - Mark an inode so that its data goes out before 222 * ocfs2_jbd2_file_inode - Mark an inode so that its data goes out before
220 * the current handle commits. 223 * the current handle commits.
@@ -244,10 +247,28 @@ int ocfs2_extend_trans(handle_t *handle, int nblocks);
244#define OCFS2_JOURNAL_ACCESS_WRITE 1 247#define OCFS2_JOURNAL_ACCESS_WRITE 1
245#define OCFS2_JOURNAL_ACCESS_UNDO 2 248#define OCFS2_JOURNAL_ACCESS_UNDO 2
246 249
247int ocfs2_journal_access(handle_t *handle, 250/* ocfs2_inode */
248 struct inode *inode, 251int ocfs2_journal_access_di(handle_t *handle, struct inode *inode,
249 struct buffer_head *bh, 252 struct buffer_head *bh, int type);
250 int type); 253/* ocfs2_extent_block */
254int ocfs2_journal_access_eb(handle_t *handle, struct inode *inode,
255 struct buffer_head *bh, int type);
256/* ocfs2_group_desc */
257int ocfs2_journal_access_gd(handle_t *handle, struct inode *inode,
258 struct buffer_head *bh, int type);
259/* ocfs2_xattr_block */
260int ocfs2_journal_access_xb(handle_t *handle, struct inode *inode,
261 struct buffer_head *bh, int type);
262/* quota blocks */
263int ocfs2_journal_access_dq(handle_t *handle, struct inode *inode,
264 struct buffer_head *bh, int type);
265/* dirblock */
266int ocfs2_journal_access_db(handle_t *handle, struct inode *inode,
267 struct buffer_head *bh, int type);
268/* Anything that has no ecc */
269int ocfs2_journal_access(handle_t *handle, struct inode *inode,
270 struct buffer_head *bh, int type);
271
251/* 272/*
252 * A word about the journal_access/journal_dirty "dance". It is 273 * A word about the journal_access/journal_dirty "dance". It is
253 * entirely legal to journal_access a buffer more than once (as long 274 * entirely legal to journal_access a buffer more than once (as long