diff options
-rw-r--r-- | fs/reiserfs/journal.c | 6 | ||||
-rw-r--r-- | fs/reiserfs/reiserfs.h | 6 | ||||
-rw-r--r-- | fs/reiserfs/super.c | 54 |
3 files changed, 55 insertions, 11 deletions
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index e5e06dd8562f..afcadcc03e8a 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c | |||
@@ -1923,6 +1923,8 @@ static int do_journal_release(struct reiserfs_transaction_handle *th, | |||
1923 | * the workqueue job (flush_async_commit) needs this lock | 1923 | * the workqueue job (flush_async_commit) needs this lock |
1924 | */ | 1924 | */ |
1925 | reiserfs_write_unlock(sb); | 1925 | reiserfs_write_unlock(sb); |
1926 | |||
1927 | cancel_delayed_work_sync(&REISERFS_SB(sb)->old_work); | ||
1926 | flush_workqueue(commit_wq); | 1928 | flush_workqueue(commit_wq); |
1927 | 1929 | ||
1928 | if (!reiserfs_mounted_fs_count) { | 1930 | if (!reiserfs_mounted_fs_count) { |
@@ -3314,7 +3316,7 @@ int journal_mark_dirty(struct reiserfs_transaction_handle *th, | |||
3314 | journal->j_first = cn; | 3316 | journal->j_first = cn; |
3315 | journal->j_last = cn; | 3317 | journal->j_last = cn; |
3316 | } | 3318 | } |
3317 | sb->s_dirt = 1; | 3319 | reiserfs_schedule_old_flush(sb); |
3318 | return 0; | 3320 | return 0; |
3319 | } | 3321 | } |
3320 | 3322 | ||
@@ -3952,7 +3954,7 @@ static int do_journal_end(struct reiserfs_transaction_handle *th, | |||
3952 | ** it tells us if we should continue with the journal_end, or just return | 3954 | ** it tells us if we should continue with the journal_end, or just return |
3953 | */ | 3955 | */ |
3954 | if (!check_journal_end(th, sb, nblocks, flags)) { | 3956 | if (!check_journal_end(th, sb, nblocks, flags)) { |
3955 | sb->s_dirt = 1; | 3957 | reiserfs_schedule_old_flush(sb); |
3956 | wake_queued_writers(sb); | 3958 | wake_queued_writers(sb); |
3957 | reiserfs_async_progress_wait(sb); | 3959 | reiserfs_async_progress_wait(sb); |
3958 | goto out; | 3960 | goto out; |
diff --git a/fs/reiserfs/reiserfs.h b/fs/reiserfs/reiserfs.h index 5c700550bb07..33215f57ea06 100644 --- a/fs/reiserfs/reiserfs.h +++ b/fs/reiserfs/reiserfs.h | |||
@@ -480,6 +480,11 @@ struct reiserfs_sb_info { | |||
480 | struct dentry *priv_root; /* root of /.reiserfs_priv */ | 480 | struct dentry *priv_root; /* root of /.reiserfs_priv */ |
481 | struct dentry *xattr_root; /* root of /.reiserfs_priv/xattrs */ | 481 | struct dentry *xattr_root; /* root of /.reiserfs_priv/xattrs */ |
482 | int j_errno; | 482 | int j_errno; |
483 | |||
484 | int work_queued; /* non-zero delayed work is queued */ | ||
485 | struct delayed_work old_work; /* old transactions flush delayed work */ | ||
486 | spinlock_t old_work_lock; /* protects old_work and work_queued */ | ||
487 | |||
483 | #ifdef CONFIG_QUOTA | 488 | #ifdef CONFIG_QUOTA |
484 | char *s_qf_names[MAXQUOTAS]; | 489 | char *s_qf_names[MAXQUOTAS]; |
485 | int s_jquota_fmt; | 490 | int s_jquota_fmt; |
@@ -2487,6 +2492,7 @@ void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...); | |||
2487 | int reiserfs_allocate_list_bitmaps(struct super_block *s, | 2492 | int reiserfs_allocate_list_bitmaps(struct super_block *s, |
2488 | struct reiserfs_list_bitmap *, unsigned int); | 2493 | struct reiserfs_list_bitmap *, unsigned int); |
2489 | 2494 | ||
2495 | void reiserfs_schedule_old_flush(struct super_block *s); | ||
2490 | void add_save_link(struct reiserfs_transaction_handle *th, | 2496 | void add_save_link(struct reiserfs_transaction_handle *th, |
2491 | struct inode *inode, int truncate); | 2497 | struct inode *inode, int truncate); |
2492 | int remove_save_link(struct inode *inode, int truncate); | 2498 | int remove_save_link(struct inode *inode, int truncate); |
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)); |