diff options
author | Artem Bityutskiy <artem.bityutskiy@linux.intel.com> | 2012-06-01 10:18:08 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-06-01 10:37:36 -0400 |
commit | 033369d1af1264abc23bea2e174aa47cdd212f6f (patch) | |
tree | b00e709d1e9270b1708488da7a596a8dff72541d /fs/reiserfs/super.c | |
parent | 5c5fd81962271d4ee2984837fef4ec37e689aa41 (diff) |
reiserfs: get rid of resierfs_sync_super
This patch stops reiserfs using the VFS 'write_super()' method along with the
s_dirt flag, because they are on their way out.
The whole "superblock write-out" VFS infrastructure is served by the
'sync_supers()' kernel thread, which wakes up every 5 (by default) seconds and
writes out all dirty superblock using the '->write_super()' call-back. But the
problem with this thread is that it wastes power by waking up the system every
5 seconds, even if there are no diry superblocks, or there are no client
file-systems which would need this (e.g., btrfs does not use
'->write_super()'). So we want to kill it completely and thus, we need to make
file-systems to stop using the '->write_super()' VFS service, and then remove
it together with the kernel thread.
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/reiserfs/super.c')
-rw-r--r-- | fs/reiserfs/super.c | 54 |
1 files changed, 45 insertions, 9 deletions
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 60cddb7e6389..651ce767b55d 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -72,20 +72,58 @@ static int reiserfs_sync_fs(struct super_block *s, int wait) | |||
72 | if (!journal_begin(&th, s, 1)) | 72 | if (!journal_begin(&th, s, 1)) |
73 | if (!journal_end_sync(&th, s, 1)) | 73 | if (!journal_end_sync(&th, s, 1)) |
74 | reiserfs_flush_old_commits(s); | 74 | reiserfs_flush_old_commits(s); |
75 | s->s_dirt = 0; /* Even if it's not true. | ||
76 | * We'll loop forever in sync_supers otherwise */ | ||
77 | reiserfs_write_unlock(s); | 75 | reiserfs_write_unlock(s); |
78 | return 0; | 76 | return 0; |
79 | } | 77 | } |
80 | 78 | ||
81 | static void reiserfs_write_super(struct super_block *s) | 79 | static void flush_old_commits(struct work_struct *work) |
82 | { | 80 | { |
81 | struct reiserfs_sb_info *sbi; | ||
82 | struct super_block *s; | ||
83 | |||
84 | sbi = container_of(work, struct reiserfs_sb_info, old_work.work); | ||
85 | s = sbi->s_journal->j_work_sb; | ||
86 | |||
87 | spin_lock(&sbi->old_work_lock); | ||
88 | sbi->work_queued = 0; | ||
89 | spin_unlock(&sbi->old_work_lock); | ||
90 | |||
83 | reiserfs_sync_fs(s, 1); | 91 | reiserfs_sync_fs(s, 1); |
84 | } | 92 | } |
85 | 93 | ||
94 | void reiserfs_schedule_old_flush(struct super_block *s) | ||
95 | { | ||
96 | struct reiserfs_sb_info *sbi = REISERFS_SB(s); | ||
97 | unsigned long delay; | ||
98 | |||
99 | if (s->s_flags & MS_RDONLY) | ||
100 | return; | ||
101 | |||
102 | spin_lock(&sbi->old_work_lock); | ||
103 | if (!sbi->work_queued) { | ||
104 | delay = msecs_to_jiffies(dirty_writeback_interval * 10); | ||
105 | queue_delayed_work(system_long_wq, &sbi->old_work, delay); | ||
106 | sbi->work_queued = 1; | ||
107 | } | ||
108 | spin_unlock(&sbi->old_work_lock); | ||
109 | } | ||
110 | |||
111 | static void cancel_old_flush(struct super_block *s) | ||
112 | { | ||
113 | struct reiserfs_sb_info *sbi = REISERFS_SB(s); | ||
114 | |||
115 | cancel_delayed_work_sync(&REISERFS_SB(s)->old_work); | ||
116 | spin_lock(&sbi->old_work_lock); | ||
117 | sbi->work_queued = 0; | ||
118 | spin_unlock(&sbi->old_work_lock); | ||
119 | } | ||
120 | |||
86 | static int reiserfs_freeze(struct super_block *s) | 121 | static int reiserfs_freeze(struct super_block *s) |
87 | { | 122 | { |
88 | struct reiserfs_transaction_handle th; | 123 | struct reiserfs_transaction_handle th; |
124 | |||
125 | cancel_old_flush(s); | ||
126 | |||
89 | reiserfs_write_lock(s); | 127 | reiserfs_write_lock(s); |
90 | if (!(s->s_flags & MS_RDONLY)) { | 128 | if (!(s->s_flags & MS_RDONLY)) { |
91 | int err = journal_begin(&th, s, 1); | 129 | int err = journal_begin(&th, s, 1); |
@@ -99,7 +137,6 @@ static int reiserfs_freeze(struct super_block *s) | |||
99 | journal_end_sync(&th, s, 1); | 137 | journal_end_sync(&th, s, 1); |
100 | } | 138 | } |
101 | } | 139 | } |
102 | s->s_dirt = 0; | ||
103 | reiserfs_write_unlock(s); | 140 | reiserfs_write_unlock(s); |
104 | return 0; | 141 | return 0; |
105 | } | 142 | } |
@@ -483,9 +520,6 @@ static void reiserfs_put_super(struct super_block *s) | |||
483 | 520 | ||
484 | reiserfs_write_lock(s); | 521 | reiserfs_write_lock(s); |
485 | 522 | ||
486 | if (s->s_dirt) | ||
487 | reiserfs_write_super(s); | ||
488 | |||
489 | /* change file system state to current state if it was mounted with read-write permissions */ | 523 | /* change file system state to current state if it was mounted with read-write permissions */ |
490 | if (!(s->s_flags & MS_RDONLY)) { | 524 | if (!(s->s_flags & MS_RDONLY)) { |
491 | if (!journal_begin(&th, s, 10)) { | 525 | if (!journal_begin(&th, s, 10)) { |
@@ -692,7 +726,6 @@ static const struct super_operations reiserfs_sops = { | |||
692 | .dirty_inode = reiserfs_dirty_inode, | 726 | .dirty_inode = reiserfs_dirty_inode, |
693 | .evict_inode = reiserfs_evict_inode, | 727 | .evict_inode = reiserfs_evict_inode, |
694 | .put_super = reiserfs_put_super, | 728 | .put_super = reiserfs_put_super, |
695 | .write_super = reiserfs_write_super, | ||
696 | .sync_fs = reiserfs_sync_fs, | 729 | .sync_fs = reiserfs_sync_fs, |
697 | .freeze_fs = reiserfs_freeze, | 730 | .freeze_fs = reiserfs_freeze, |
698 | .unfreeze_fs = reiserfs_unfreeze, | 731 | .unfreeze_fs = reiserfs_unfreeze, |
@@ -1400,7 +1433,6 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1400 | err = journal_end(&th, s, 10); | 1433 | err = journal_end(&th, s, 10); |
1401 | if (err) | 1434 | if (err) |
1402 | goto out_err; | 1435 | goto out_err; |
1403 | s->s_dirt = 0; | ||
1404 | 1436 | ||
1405 | if (!(*mount_flags & MS_RDONLY)) { | 1437 | if (!(*mount_flags & MS_RDONLY)) { |
1406 | dquot_resume(s, -1); | 1438 | dquot_resume(s, -1); |
@@ -1741,6 +1773,8 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) | |||
1741 | /* setup default block allocator options */ | 1773 | /* setup default block allocator options */ |
1742 | reiserfs_init_alloc_options(s); | 1774 | reiserfs_init_alloc_options(s); |
1743 | 1775 | ||
1776 | spin_lock_init(&sbi->old_work_lock); | ||
1777 | INIT_DELAYED_WORK(&sbi->old_work, flush_old_commits); | ||
1744 | mutex_init(&sbi->lock); | 1778 | mutex_init(&sbi->lock); |
1745 | sbi->lock_depth = -1; | 1779 | sbi->lock_depth = -1; |
1746 | 1780 | ||
@@ -2003,6 +2037,8 @@ error_unlocked: | |||
2003 | reiserfs_write_unlock(s); | 2037 | reiserfs_write_unlock(s); |
2004 | } | 2038 | } |
2005 | 2039 | ||
2040 | cancel_delayed_work_sync(&REISERFS_SB(s)->old_work); | ||
2041 | |||
2006 | reiserfs_free_bitmap_cache(s); | 2042 | reiserfs_free_bitmap_cache(s); |
2007 | if (SB_BUFFER_WITH_SB(s)) | 2043 | if (SB_BUFFER_WITH_SB(s)) |
2008 | brelse(SB_BUFFER_WITH_SB(s)); | 2044 | brelse(SB_BUFFER_WITH_SB(s)); |