diff options
author | Jan Kara <jack@suse.cz> | 2012-11-13 11:05:14 -0500 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2012-11-19 15:34:33 -0500 |
commit | 7af11686933726e99af22901d622f9e161404e6b (patch) | |
tree | a693298183889f319942b70ab1013a5e14a4673c /fs/reiserfs/super.c | |
parent | 361d94a338a3fd0cee6a4ea32bbc427ba228e628 (diff) |
reiserfs: Move quota calls out of write lock
Calls into highlevel quota code cannot happen under the write lock. These
calls take dqio_mutex which ranks above write lock. So drop write lock
before calling back into quota code.
CC: stable@vger.kernel.org # >= 3.0
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/reiserfs/super.c')
-rw-r--r-- | fs/reiserfs/super.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index c101704ece48..418bdc3a57da 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -298,7 +298,9 @@ static int finish_unfinished(struct super_block *s) | |||
298 | retval = remove_save_link_only(s, &save_link_key, 0); | 298 | retval = remove_save_link_only(s, &save_link_key, 0); |
299 | continue; | 299 | continue; |
300 | } | 300 | } |
301 | reiserfs_write_unlock(s); | ||
301 | dquot_initialize(inode); | 302 | dquot_initialize(inode); |
303 | reiserfs_write_lock(s); | ||
302 | 304 | ||
303 | if (truncate && S_ISDIR(inode->i_mode)) { | 305 | if (truncate && S_ISDIR(inode->i_mode)) { |
304 | /* We got a truncate request for a dir which is impossible. | 306 | /* We got a truncate request for a dir which is impossible. |
@@ -2108,13 +2110,15 @@ static int reiserfs_write_dquot(struct dquot *dquot) | |||
2108 | REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); | 2110 | REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); |
2109 | if (ret) | 2111 | if (ret) |
2110 | goto out; | 2112 | goto out; |
2113 | reiserfs_write_unlock(dquot->dq_sb); | ||
2111 | ret = dquot_commit(dquot); | 2114 | ret = dquot_commit(dquot); |
2115 | reiserfs_write_lock(dquot->dq_sb); | ||
2112 | err = | 2116 | err = |
2113 | journal_end(&th, dquot->dq_sb, | 2117 | journal_end(&th, dquot->dq_sb, |
2114 | REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); | 2118 | REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); |
2115 | if (!ret && err) | 2119 | if (!ret && err) |
2116 | ret = err; | 2120 | ret = err; |
2117 | out: | 2121 | out: |
2118 | reiserfs_write_unlock(dquot->dq_sb); | 2122 | reiserfs_write_unlock(dquot->dq_sb); |
2119 | return ret; | 2123 | return ret; |
2120 | } | 2124 | } |
@@ -2130,13 +2134,15 @@ static int reiserfs_acquire_dquot(struct dquot *dquot) | |||
2130 | REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); | 2134 | REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); |
2131 | if (ret) | 2135 | if (ret) |
2132 | goto out; | 2136 | goto out; |
2137 | reiserfs_write_unlock(dquot->dq_sb); | ||
2133 | ret = dquot_acquire(dquot); | 2138 | ret = dquot_acquire(dquot); |
2139 | reiserfs_write_lock(dquot->dq_sb); | ||
2134 | err = | 2140 | err = |
2135 | journal_end(&th, dquot->dq_sb, | 2141 | journal_end(&th, dquot->dq_sb, |
2136 | REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); | 2142 | REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); |
2137 | if (!ret && err) | 2143 | if (!ret && err) |
2138 | ret = err; | 2144 | ret = err; |
2139 | out: | 2145 | out: |
2140 | reiserfs_write_unlock(dquot->dq_sb); | 2146 | reiserfs_write_unlock(dquot->dq_sb); |
2141 | return ret; | 2147 | return ret; |
2142 | } | 2148 | } |
@@ -2150,19 +2156,21 @@ static int reiserfs_release_dquot(struct dquot *dquot) | |||
2150 | ret = | 2156 | ret = |
2151 | journal_begin(&th, dquot->dq_sb, | 2157 | journal_begin(&th, dquot->dq_sb, |
2152 | REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb)); | 2158 | REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb)); |
2159 | reiserfs_write_unlock(dquot->dq_sb); | ||
2153 | if (ret) { | 2160 | if (ret) { |
2154 | /* Release dquot anyway to avoid endless cycle in dqput() */ | 2161 | /* Release dquot anyway to avoid endless cycle in dqput() */ |
2155 | dquot_release(dquot); | 2162 | dquot_release(dquot); |
2156 | goto out; | 2163 | goto out; |
2157 | } | 2164 | } |
2158 | ret = dquot_release(dquot); | 2165 | ret = dquot_release(dquot); |
2166 | reiserfs_write_lock(dquot->dq_sb); | ||
2159 | err = | 2167 | err = |
2160 | journal_end(&th, dquot->dq_sb, | 2168 | journal_end(&th, dquot->dq_sb, |
2161 | REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb)); | 2169 | REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb)); |
2162 | if (!ret && err) | 2170 | if (!ret && err) |
2163 | ret = err; | 2171 | ret = err; |
2164 | out: | ||
2165 | reiserfs_write_unlock(dquot->dq_sb); | 2172 | reiserfs_write_unlock(dquot->dq_sb); |
2173 | out: | ||
2166 | return ret; | 2174 | return ret; |
2167 | } | 2175 | } |
2168 | 2176 | ||
@@ -2187,11 +2195,13 @@ static int reiserfs_write_info(struct super_block *sb, int type) | |||
2187 | ret = journal_begin(&th, sb, 2); | 2195 | ret = journal_begin(&th, sb, 2); |
2188 | if (ret) | 2196 | if (ret) |
2189 | goto out; | 2197 | goto out; |
2198 | reiserfs_write_unlock(sb); | ||
2190 | ret = dquot_commit_info(sb, type); | 2199 | ret = dquot_commit_info(sb, type); |
2200 | reiserfs_write_lock(sb); | ||
2191 | err = journal_end(&th, sb, 2); | 2201 | err = journal_end(&th, sb, 2); |
2192 | if (!ret && err) | 2202 | if (!ret && err) |
2193 | ret = err; | 2203 | ret = err; |
2194 | out: | 2204 | out: |
2195 | reiserfs_write_unlock(sb); | 2205 | reiserfs_write_unlock(sb); |
2196 | return ret; | 2206 | return ret; |
2197 | } | 2207 | } |