diff options
author | Joern Engel <joern@logfs.org> | 2010-03-04 15:36:19 -0500 |
---|---|---|
committer | Joern Engel <joern@logfs.org> | 2010-03-04 15:36:19 -0500 |
commit | c6d3830140f1d56b07d8ab56a6e14ca3c492a39a (patch) | |
tree | 8dd9923b4217f6f7dc2735356d112fdcfa277852 /fs/logfs | |
parent | 9421502b4fc894cc477be8fc49776830e37ca157 (diff) |
[LogFS] Only write journal if dirty
This prevents unnecessary journal writes. More importantly it prevents
an oops due to a journal write on failed mount.
Diffstat (limited to 'fs/logfs')
-rw-r--r-- | fs/logfs/gc.c | 6 | ||||
-rw-r--r-- | fs/logfs/journal.c | 11 | ||||
-rw-r--r-- | fs/logfs/logfs.h | 4 | ||||
-rw-r--r-- | fs/logfs/readwrite.c | 2 | ||||
-rw-r--r-- | fs/logfs/segment.c | 7 | ||||
-rw-r--r-- | fs/logfs/super.c | 2 |
6 files changed, 19 insertions, 13 deletions
diff --git a/fs/logfs/gc.c b/fs/logfs/gc.c index b3656c44190e..92949f95a901 100644 --- a/fs/logfs/gc.c +++ b/fs/logfs/gc.c | |||
@@ -469,7 +469,7 @@ static void __logfs_gc_pass(struct super_block *sb, int target) | |||
469 | 469 | ||
470 | /* Sync in-memory state with on-medium state in case they | 470 | /* Sync in-memory state with on-medium state in case they |
471 | * diverged */ | 471 | * diverged */ |
472 | logfs_write_anchor(super->s_master_inode); | 472 | logfs_write_anchor(sb); |
473 | round += logfs_scan_some(sb); | 473 | round += logfs_scan_some(sb); |
474 | if (no_free_segments(sb) >= target) | 474 | if (no_free_segments(sb) >= target) |
475 | goto write_alias; | 475 | goto write_alias; |
@@ -613,8 +613,8 @@ void logfs_gc_pass(struct super_block *sb) | |||
613 | */ | 613 | */ |
614 | if (super->s_dirty_used_bytes + super->s_dirty_free_bytes | 614 | if (super->s_dirty_used_bytes + super->s_dirty_free_bytes |
615 | + LOGFS_MAX_OBJECTSIZE >= super->s_free_bytes) | 615 | + LOGFS_MAX_OBJECTSIZE >= super->s_free_bytes) |
616 | logfs_write_anchor(super->s_master_inode); | 616 | logfs_write_anchor(sb); |
617 | __logfs_gc_pass(sb, logfs_super(sb)->s_total_levels); | 617 | __logfs_gc_pass(sb, super->s_total_levels); |
618 | logfs_wl_pass(sb); | 618 | logfs_wl_pass(sb); |
619 | logfs_journal_wl_pass(sb); | 619 | logfs_journal_wl_pass(sb); |
620 | } | 620 | } |
diff --git a/fs/logfs/journal.c b/fs/logfs/journal.c index c0e7d63221d4..57eb4fb444a9 100644 --- a/fs/logfs/journal.c +++ b/fs/logfs/journal.c | |||
@@ -724,14 +724,17 @@ static int logfs_write_obj_aliases(struct super_block *sb) | |||
724 | * bit wasteful, but robustness is more important. With this we can *always* | 724 | * bit wasteful, but robustness is more important. With this we can *always* |
725 | * erase all journal segments except the one containing the most recent commit. | 725 | * erase all journal segments except the one containing the most recent commit. |
726 | */ | 726 | */ |
727 | void logfs_write_anchor(struct inode *inode) | 727 | void logfs_write_anchor(struct super_block *sb) |
728 | { | 728 | { |
729 | struct super_block *sb = inode->i_sb; | ||
730 | struct logfs_super *super = logfs_super(sb); | 729 | struct logfs_super *super = logfs_super(sb); |
731 | struct logfs_area *area = super->s_journal_area; | 730 | struct logfs_area *area = super->s_journal_area; |
732 | int i, err; | 731 | int i, err; |
733 | 732 | ||
734 | BUG_ON(logfs_super(sb)->s_flags & LOGFS_SB_FLAG_SHUTDOWN); | 733 | if (!(super->s_flags & LOGFS_SB_FLAG_DIRTY)) |
734 | return; | ||
735 | super->s_flags &= ~LOGFS_SB_FLAG_DIRTY; | ||
736 | |||
737 | BUG_ON(super->s_flags & LOGFS_SB_FLAG_SHUTDOWN); | ||
735 | mutex_lock(&super->s_journal_mutex); | 738 | mutex_lock(&super->s_journal_mutex); |
736 | 739 | ||
737 | /* Do this first or suffer corruption */ | 740 | /* Do this first or suffer corruption */ |
@@ -821,7 +824,7 @@ void do_logfs_journal_wl_pass(struct super_block *sb) | |||
821 | area->a_is_open = 0; | 824 | area->a_is_open = 0; |
822 | area->a_used_bytes = 0; | 825 | area->a_used_bytes = 0; |
823 | /* Write journal */ | 826 | /* Write journal */ |
824 | logfs_write_anchor(super->s_master_inode); | 827 | logfs_write_anchor(sb); |
825 | /* Write superblocks */ | 828 | /* Write superblocks */ |
826 | err = logfs_write_sb(sb); | 829 | err = logfs_write_sb(sb); |
827 | BUG_ON(err); | 830 | BUG_ON(err); |
diff --git a/fs/logfs/logfs.h b/fs/logfs/logfs.h index 72592114a28f..129779431373 100644 --- a/fs/logfs/logfs.h +++ b/fs/logfs/logfs.h | |||
@@ -82,7 +82,7 @@ | |||
82 | 82 | ||
83 | /* Read-only filesystem */ | 83 | /* Read-only filesystem */ |
84 | #define LOGFS_SB_FLAG_RO 0x0001 | 84 | #define LOGFS_SB_FLAG_RO 0x0001 |
85 | #define LOGFS_SB_FLAG_SEG_ALIAS 0x0002 | 85 | #define LOGFS_SB_FLAG_DIRTY 0x0002 |
86 | #define LOGFS_SB_FLAG_OBJ_ALIAS 0x0004 | 86 | #define LOGFS_SB_FLAG_OBJ_ALIAS 0x0004 |
87 | #define LOGFS_SB_FLAG_SHUTDOWN 0x0008 | 87 | #define LOGFS_SB_FLAG_SHUTDOWN 0x0008 |
88 | 88 | ||
@@ -526,7 +526,7 @@ void logfs_delete_inode(struct inode *inode); | |||
526 | void logfs_clear_inode(struct inode *inode); | 526 | void logfs_clear_inode(struct inode *inode); |
527 | 527 | ||
528 | /* journal.c */ | 528 | /* journal.c */ |
529 | void logfs_write_anchor(struct inode *inode); | 529 | void logfs_write_anchor(struct super_block *sb); |
530 | int logfs_init_journal(struct super_block *sb); | 530 | int logfs_init_journal(struct super_block *sb); |
531 | void logfs_cleanup_journal(struct super_block *sb); | 531 | void logfs_cleanup_journal(struct super_block *sb); |
532 | int write_alias_journal(struct super_block *sb, u64 ino, u64 bix, | 532 | int write_alias_journal(struct super_block *sb, u64 ino, u64 bix, |
diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c index 1dbe6e8cccec..7a23b3e7c0a7 100644 --- a/fs/logfs/readwrite.c +++ b/fs/logfs/readwrite.c | |||
@@ -421,7 +421,7 @@ static void inode_write_block(struct logfs_block *block) | |||
421 | 421 | ||
422 | inode = block->inode; | 422 | inode = block->inode; |
423 | if (inode->i_ino == LOGFS_INO_MASTER) | 423 | if (inode->i_ino == LOGFS_INO_MASTER) |
424 | logfs_write_anchor(inode); | 424 | logfs_write_anchor(inode->i_sb); |
425 | else { | 425 | else { |
426 | ret = __logfs_write_inode(inode, 0); | 426 | ret = __logfs_write_inode(inode, 0); |
427 | /* see indirect_write_block comment */ | 427 | /* see indirect_write_block comment */ |
diff --git a/fs/logfs/segment.c b/fs/logfs/segment.c index 664cd0dd3576..1a14f9910d55 100644 --- a/fs/logfs/segment.c +++ b/fs/logfs/segment.c | |||
@@ -352,7 +352,8 @@ int logfs_segment_write(struct inode *inode, struct page *page, | |||
352 | int ret; | 352 | int ret; |
353 | void *buf; | 353 | void *buf; |
354 | 354 | ||
355 | BUG_ON(logfs_super(sb)->s_flags & LOGFS_SB_FLAG_SHUTDOWN); | 355 | super->s_flags |= LOGFS_SB_FLAG_DIRTY; |
356 | BUG_ON(super->s_flags & LOGFS_SB_FLAG_SHUTDOWN); | ||
356 | do_compress = logfs_inode(inode)->li_flags & LOGFS_IF_COMPRESSED; | 357 | do_compress = logfs_inode(inode)->li_flags & LOGFS_IF_COMPRESSED; |
357 | if (shadow->gc_level != 0) { | 358 | if (shadow->gc_level != 0) { |
358 | /* temporarily disable compression for indirect blocks */ | 359 | /* temporarily disable compression for indirect blocks */ |
@@ -653,11 +654,13 @@ int logfs_segment_read(struct inode *inode, struct page *page, | |||
653 | int logfs_segment_delete(struct inode *inode, struct logfs_shadow *shadow) | 654 | int logfs_segment_delete(struct inode *inode, struct logfs_shadow *shadow) |
654 | { | 655 | { |
655 | struct super_block *sb = inode->i_sb; | 656 | struct super_block *sb = inode->i_sb; |
657 | struct logfs_super *super = logfs_super(sb); | ||
656 | struct logfs_object_header h; | 658 | struct logfs_object_header h; |
657 | u16 len; | 659 | u16 len; |
658 | int err; | 660 | int err; |
659 | 661 | ||
660 | BUG_ON(logfs_super(sb)->s_flags & LOGFS_SB_FLAG_SHUTDOWN); | 662 | super->s_flags |= LOGFS_SB_FLAG_DIRTY; |
663 | BUG_ON(super->s_flags & LOGFS_SB_FLAG_SHUTDOWN); | ||
661 | BUG_ON(shadow->old_ofs & LOGFS_FULLY_POPULATED); | 664 | BUG_ON(shadow->old_ofs & LOGFS_FULLY_POPULATED); |
662 | if (!shadow->old_ofs) | 665 | if (!shadow->old_ofs) |
663 | return 0; | 666 | return 0; |
diff --git a/fs/logfs/super.c b/fs/logfs/super.c index 94d80f7ee7c2..1d081b7ede5a 100644 --- a/fs/logfs/super.c +++ b/fs/logfs/super.c | |||
@@ -490,7 +490,7 @@ static void logfs_kill_sb(struct super_block *sb) | |||
490 | log_super("LogFS: Start unmounting\n"); | 490 | log_super("LogFS: Start unmounting\n"); |
491 | /* Alias entries slow down mount, so evict as many as possible */ | 491 | /* Alias entries slow down mount, so evict as many as possible */ |
492 | sync_filesystem(sb); | 492 | sync_filesystem(sb); |
493 | logfs_write_anchor(super->s_master_inode); | 493 | logfs_write_anchor(sb); |
494 | 494 | ||
495 | /* | 495 | /* |
496 | * From this point on alias entries are simply dropped - and any | 496 | * From this point on alias entries are simply dropped - and any |