aboutsummaryrefslogtreecommitdiffstats
path: root/fs/logfs
diff options
context:
space:
mode:
authorJoern Engel <joern@logfs.org>2010-03-04 15:36:19 -0500
committerJoern Engel <joern@logfs.org>2010-03-04 15:36:19 -0500
commitc6d3830140f1d56b07d8ab56a6e14ca3c492a39a (patch)
tree8dd9923b4217f6f7dc2735356d112fdcfa277852 /fs/logfs
parent9421502b4fc894cc477be8fc49776830e37ca157 (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.c6
-rw-r--r--fs/logfs/journal.c11
-rw-r--r--fs/logfs/logfs.h4
-rw-r--r--fs/logfs/readwrite.c2
-rw-r--r--fs/logfs/segment.c7
-rw-r--r--fs/logfs/super.c2
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 */
727void logfs_write_anchor(struct inode *inode) 727void 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);
526void logfs_clear_inode(struct inode *inode); 526void logfs_clear_inode(struct inode *inode);
527 527
528/* journal.c */ 528/* journal.c */
529void logfs_write_anchor(struct inode *inode); 529void logfs_write_anchor(struct super_block *sb);
530int logfs_init_journal(struct super_block *sb); 530int logfs_init_journal(struct super_block *sb);
531void logfs_cleanup_journal(struct super_block *sb); 531void logfs_cleanup_journal(struct super_block *sb);
532int write_alias_journal(struct super_block *sb, u64 ino, u64 bix, 532int 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,
653int logfs_segment_delete(struct inode *inode, struct logfs_shadow *shadow) 654int 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