diff options
Diffstat (limited to 'fs/reiserfs/super.c')
-rw-r--r-- | fs/reiserfs/super.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 393cc22c1717..ed424d708e69 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -304,7 +304,7 @@ static int finish_unfinished(struct super_block *s) | |||
304 | /* Turn quotas off */ | 304 | /* Turn quotas off */ |
305 | for (i = 0; i < MAXQUOTAS; i++) { | 305 | for (i = 0; i < MAXQUOTAS; i++) { |
306 | if (sb_dqopt(s)->files[i]) | 306 | if (sb_dqopt(s)->files[i]) |
307 | vfs_quota_off_mount(s, i); | 307 | vfs_quota_off(s, i, 0); |
308 | } | 308 | } |
309 | if (ms_active_set) | 309 | if (ms_active_set) |
310 | /* Restore the flag back */ | 310 | /* Restore the flag back */ |
@@ -634,7 +634,7 @@ static int reiserfs_acquire_dquot(struct dquot *); | |||
634 | static int reiserfs_release_dquot(struct dquot *); | 634 | static int reiserfs_release_dquot(struct dquot *); |
635 | static int reiserfs_mark_dquot_dirty(struct dquot *); | 635 | static int reiserfs_mark_dquot_dirty(struct dquot *); |
636 | static int reiserfs_write_info(struct super_block *, int); | 636 | static int reiserfs_write_info(struct super_block *, int); |
637 | static int reiserfs_quota_on(struct super_block *, int, int, char *); | 637 | static int reiserfs_quota_on(struct super_block *, int, int, char *, int); |
638 | 638 | ||
639 | static struct dquot_operations reiserfs_quota_operations = { | 639 | static struct dquot_operations reiserfs_quota_operations = { |
640 | .initialize = reiserfs_dquot_initialize, | 640 | .initialize = reiserfs_dquot_initialize, |
@@ -1890,8 +1890,14 @@ static int reiserfs_dquot_drop(struct inode *inode) | |||
1890 | ret = | 1890 | ret = |
1891 | journal_begin(&th, inode->i_sb, | 1891 | journal_begin(&th, inode->i_sb, |
1892 | 2 * REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)); | 1892 | 2 * REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)); |
1893 | if (ret) | 1893 | if (ret) { |
1894 | /* | ||
1895 | * We call dquot_drop() anyway to at least release references | ||
1896 | * to quota structures so that umount does not hang. | ||
1897 | */ | ||
1898 | dquot_drop(inode); | ||
1894 | goto out; | 1899 | goto out; |
1900 | } | ||
1895 | ret = dquot_drop(inode); | 1901 | ret = dquot_drop(inode); |
1896 | err = | 1902 | err = |
1897 | journal_end(&th, inode->i_sb, | 1903 | journal_end(&th, inode->i_sb, |
@@ -2015,13 +2021,17 @@ static int reiserfs_quota_on_mount(struct super_block *sb, int type) | |||
2015 | * Standard function to be called on quota_on | 2021 | * Standard function to be called on quota_on |
2016 | */ | 2022 | */ |
2017 | static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, | 2023 | static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, |
2018 | char *path) | 2024 | char *path, int remount) |
2019 | { | 2025 | { |
2020 | int err; | 2026 | int err; |
2021 | struct nameidata nd; | 2027 | struct nameidata nd; |
2028 | struct inode *inode; | ||
2022 | 2029 | ||
2023 | if (!(REISERFS_SB(sb)->s_mount_opt & (1 << REISERFS_QUOTA))) | 2030 | if (!(REISERFS_SB(sb)->s_mount_opt & (1 << REISERFS_QUOTA))) |
2024 | return -EINVAL; | 2031 | return -EINVAL; |
2032 | /* No more checks needed? Path and format_id are bogus anyway... */ | ||
2033 | if (remount) | ||
2034 | return vfs_quota_on(sb, type, format_id, path, 1); | ||
2025 | err = path_lookup(path, LOOKUP_FOLLOW, &nd); | 2035 | err = path_lookup(path, LOOKUP_FOLLOW, &nd); |
2026 | if (err) | 2036 | if (err) |
2027 | return err; | 2037 | return err; |
@@ -2030,18 +2040,24 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, | |||
2030 | path_put(&nd.path); | 2040 | path_put(&nd.path); |
2031 | return -EXDEV; | 2041 | return -EXDEV; |
2032 | } | 2042 | } |
2043 | inode = nd.path.dentry->d_inode; | ||
2033 | /* We must not pack tails for quota files on reiserfs for quota IO to work */ | 2044 | /* We must not pack tails for quota files on reiserfs for quota IO to work */ |
2034 | if (!(REISERFS_I(nd.path.dentry->d_inode)->i_flags & i_nopack_mask)) { | 2045 | if (!(REISERFS_I(inode)->i_flags & i_nopack_mask)) { |
2035 | reiserfs_warning(sb, | 2046 | err = reiserfs_unpack(inode, NULL); |
2036 | "reiserfs: Quota file must have tail packing disabled."); | 2047 | if (err) { |
2037 | path_put(&nd.path); | 2048 | reiserfs_warning(sb, |
2038 | return -EINVAL; | 2049 | "reiserfs: Unpacking tail of quota file failed" |
2050 | " (%d). Cannot turn on quotas.", err); | ||
2051 | path_put(&nd.path); | ||
2052 | return -EINVAL; | ||
2053 | } | ||
2054 | mark_inode_dirty(inode); | ||
2039 | } | 2055 | } |
2040 | /* Not journalling quota? No more tests needed... */ | 2056 | /* Not journalling quota? No more tests needed... */ |
2041 | if (!REISERFS_SB(sb)->s_qf_names[USRQUOTA] && | 2057 | if (!REISERFS_SB(sb)->s_qf_names[USRQUOTA] && |
2042 | !REISERFS_SB(sb)->s_qf_names[GRPQUOTA]) { | 2058 | !REISERFS_SB(sb)->s_qf_names[GRPQUOTA]) { |
2043 | path_put(&nd.path); | 2059 | path_put(&nd.path); |
2044 | return vfs_quota_on(sb, type, format_id, path); | 2060 | return vfs_quota_on(sb, type, format_id, path, 0); |
2045 | } | 2061 | } |
2046 | /* Quotafile not of fs root? */ | 2062 | /* Quotafile not of fs root? */ |
2047 | if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) | 2063 | if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) |
@@ -2049,7 +2065,7 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, | |||
2049 | "reiserfs: Quota file not on filesystem root. " | 2065 | "reiserfs: Quota file not on filesystem root. " |
2050 | "Journalled quota will not work."); | 2066 | "Journalled quota will not work."); |
2051 | path_put(&nd.path); | 2067 | path_put(&nd.path); |
2052 | return vfs_quota_on(sb, type, format_id, path); | 2068 | return vfs_quota_on(sb, type, format_id, path, 0); |
2053 | } | 2069 | } |
2054 | 2070 | ||
2055 | /* Read data from quotafile - avoid pagecache and such because we cannot afford | 2071 | /* Read data from quotafile - avoid pagecache and such because we cannot afford |