diff options
author | Jan Kara <jack@suse.cz> | 2008-07-25 04:46:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-25 13:53:31 -0400 |
commit | 9cfe7b9010aa66da5f3b2bc33d9e30a4d53bd274 (patch) | |
tree | 7cbafe89d4101f3bb0ca2132154e414dec4aecf7 /fs/ext3/super.c | |
parent | 50c33a84db4aa5082e3af8d873b22344ae2ebea8 (diff) |
ext3: fix synchronization of quota files in journal=data mode
In journal=data mode, it is not enough to do write_inode_now as done in
vfs_quota_on() to write all data to their final location (which is needed for
quota_read to work correctly). Calling journal_flush() does its job.
Reported-by: Nick <gentuu@gmail.com>
Cc: <linux-ext4@vger.kernel.org>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ext3/super.c')
-rw-r--r-- | fs/ext3/super.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 2845425077e8..50796e90d070 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -2759,23 +2759,42 @@ static int ext3_quota_on(struct super_block *sb, int type, int format_id, | |||
2759 | 2759 | ||
2760 | if (!test_opt(sb, QUOTA)) | 2760 | if (!test_opt(sb, QUOTA)) |
2761 | return -EINVAL; | 2761 | return -EINVAL; |
2762 | /* Not journalling quota or remount? */ | 2762 | /* When remounting, no checks are needed and in fact, path is NULL */ |
2763 | if ((!EXT3_SB(sb)->s_qf_names[USRQUOTA] && | 2763 | if (remount) |
2764 | !EXT3_SB(sb)->s_qf_names[GRPQUOTA]) || remount) | ||
2765 | return vfs_quota_on(sb, type, format_id, path, remount); | 2764 | return vfs_quota_on(sb, type, format_id, path, remount); |
2765 | |||
2766 | err = path_lookup(path, LOOKUP_FOLLOW, &nd); | 2766 | err = path_lookup(path, LOOKUP_FOLLOW, &nd); |
2767 | if (err) | 2767 | if (err) |
2768 | return err; | 2768 | return err; |
2769 | |||
2769 | /* Quotafile not on the same filesystem? */ | 2770 | /* Quotafile not on the same filesystem? */ |
2770 | if (nd.path.mnt->mnt_sb != sb) { | 2771 | if (nd.path.mnt->mnt_sb != sb) { |
2771 | path_put(&nd.path); | 2772 | path_put(&nd.path); |
2772 | return -EXDEV; | 2773 | return -EXDEV; |
2773 | } | 2774 | } |
2774 | /* Quotafile not in fs root? */ | 2775 | /* Journaling quota? */ |
2775 | if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) | 2776 | if (EXT3_SB(sb)->s_qf_names[type]) { |
2776 | printk(KERN_WARNING | 2777 | /* Quotafile not of fs root? */ |
2777 | "EXT3-fs: Quota file not on filesystem root. " | 2778 | if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) |
2778 | "Journalled quota will not work.\n"); | 2779 | printk(KERN_WARNING |
2780 | "EXT3-fs: Quota file not on filesystem root. " | ||
2781 | "Journaled quota will not work.\n"); | ||
2782 | } | ||
2783 | |||
2784 | /* | ||
2785 | * When we journal data on quota file, we have to flush journal to see | ||
2786 | * all updates to the file when we bypass pagecache... | ||
2787 | */ | ||
2788 | if (ext3_should_journal_data(nd.path.dentry->d_inode)) { | ||
2789 | /* | ||
2790 | * We don't need to lock updates but journal_flush() could | ||
2791 | * otherwise be livelocked... | ||
2792 | */ | ||
2793 | journal_lock_updates(EXT3_SB(sb)->s_journal); | ||
2794 | journal_flush(EXT3_SB(sb)->s_journal); | ||
2795 | journal_unlock_updates(EXT3_SB(sb)->s_journal); | ||
2796 | } | ||
2797 | |||
2779 | path_put(&nd.path); | 2798 | path_put(&nd.path); |
2780 | return vfs_quota_on(sb, type, format_id, path, remount); | 2799 | return vfs_quota_on(sb, type, format_id, path, remount); |
2781 | } | 2800 | } |