diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-21 10:33:37 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-21 10:33:37 -0500 |
commit | 4843456c5c341eb57f80f9224362a22665d14107 (patch) | |
tree | 5656b405a8b1d2596e8eb748b953ee677a261e3c /fs/ext3 | |
parent | 2b1caf6ed7b888c95a1909d343799672731651a5 (diff) | |
parent | f00c9e44ad1a9660fe8cd3ca15b6cd9497172eab (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6:
quota: Fix deadlock during path resolution
Diffstat (limited to 'fs/ext3')
-rw-r--r-- | fs/ext3/super.c | 25 |
1 files changed, 7 insertions, 18 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 7aa767d4f06f..85c8cc8f2473 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -754,7 +754,7 @@ static int ext3_release_dquot(struct dquot *dquot); | |||
754 | static int ext3_mark_dquot_dirty(struct dquot *dquot); | 754 | static int ext3_mark_dquot_dirty(struct dquot *dquot); |
755 | static int ext3_write_info(struct super_block *sb, int type); | 755 | static int ext3_write_info(struct super_block *sb, int type); |
756 | static int ext3_quota_on(struct super_block *sb, int type, int format_id, | 756 | static int ext3_quota_on(struct super_block *sb, int type, int format_id, |
757 | char *path); | 757 | struct path *path); |
758 | static int ext3_quota_on_mount(struct super_block *sb, int type); | 758 | static int ext3_quota_on_mount(struct super_block *sb, int type); |
759 | static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data, | 759 | static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data, |
760 | size_t len, loff_t off); | 760 | size_t len, loff_t off); |
@@ -2877,27 +2877,20 @@ static int ext3_quota_on_mount(struct super_block *sb, int type) | |||
2877 | * Standard function to be called on quota_on | 2877 | * Standard function to be called on quota_on |
2878 | */ | 2878 | */ |
2879 | static int ext3_quota_on(struct super_block *sb, int type, int format_id, | 2879 | static int ext3_quota_on(struct super_block *sb, int type, int format_id, |
2880 | char *name) | 2880 | struct path *path) |
2881 | { | 2881 | { |
2882 | int err; | 2882 | int err; |
2883 | struct path path; | ||
2884 | 2883 | ||
2885 | if (!test_opt(sb, QUOTA)) | 2884 | if (!test_opt(sb, QUOTA)) |
2886 | return -EINVAL; | 2885 | return -EINVAL; |
2887 | 2886 | ||
2888 | err = kern_path(name, LOOKUP_FOLLOW, &path); | ||
2889 | if (err) | ||
2890 | return err; | ||
2891 | |||
2892 | /* Quotafile not on the same filesystem? */ | 2887 | /* Quotafile not on the same filesystem? */ |
2893 | if (path.mnt->mnt_sb != sb) { | 2888 | if (path->mnt->mnt_sb != sb) |
2894 | path_put(&path); | ||
2895 | return -EXDEV; | 2889 | return -EXDEV; |
2896 | } | ||
2897 | /* Journaling quota? */ | 2890 | /* Journaling quota? */ |
2898 | if (EXT3_SB(sb)->s_qf_names[type]) { | 2891 | if (EXT3_SB(sb)->s_qf_names[type]) { |
2899 | /* Quotafile not of fs root? */ | 2892 | /* Quotafile not of fs root? */ |
2900 | if (path.dentry->d_parent != sb->s_root) | 2893 | if (path->dentry->d_parent != sb->s_root) |
2901 | ext3_msg(sb, KERN_WARNING, | 2894 | ext3_msg(sb, KERN_WARNING, |
2902 | "warning: Quota file not on filesystem root. " | 2895 | "warning: Quota file not on filesystem root. " |
2903 | "Journaled quota will not work."); | 2896 | "Journaled quota will not work."); |
@@ -2907,7 +2900,7 @@ static int ext3_quota_on(struct super_block *sb, int type, int format_id, | |||
2907 | * When we journal data on quota file, we have to flush journal to see | 2900 | * When we journal data on quota file, we have to flush journal to see |
2908 | * all updates to the file when we bypass pagecache... | 2901 | * all updates to the file when we bypass pagecache... |
2909 | */ | 2902 | */ |
2910 | if (ext3_should_journal_data(path.dentry->d_inode)) { | 2903 | if (ext3_should_journal_data(path->dentry->d_inode)) { |
2911 | /* | 2904 | /* |
2912 | * We don't need to lock updates but journal_flush() could | 2905 | * We don't need to lock updates but journal_flush() could |
2913 | * otherwise be livelocked... | 2906 | * otherwise be livelocked... |
@@ -2915,15 +2908,11 @@ static int ext3_quota_on(struct super_block *sb, int type, int format_id, | |||
2915 | journal_lock_updates(EXT3_SB(sb)->s_journal); | 2908 | journal_lock_updates(EXT3_SB(sb)->s_journal); |
2916 | err = journal_flush(EXT3_SB(sb)->s_journal); | 2909 | err = journal_flush(EXT3_SB(sb)->s_journal); |
2917 | journal_unlock_updates(EXT3_SB(sb)->s_journal); | 2910 | journal_unlock_updates(EXT3_SB(sb)->s_journal); |
2918 | if (err) { | 2911 | if (err) |
2919 | path_put(&path); | ||
2920 | return err; | 2912 | return err; |
2921 | } | ||
2922 | } | 2913 | } |
2923 | 2914 | ||
2924 | err = dquot_quota_on_path(sb, type, format_id, &path); | 2915 | return dquot_quota_on(sb, type, format_id, path); |
2925 | path_put(&path); | ||
2926 | return err; | ||
2927 | } | 2916 | } |
2928 | 2917 | ||
2929 | /* Read data from quotafile - avoid pagecache and such because we cannot afford | 2918 | /* Read data from quotafile - avoid pagecache and such because we cannot afford |