aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext3')
-rw-r--r--fs/ext3/resize.c51
1 files changed, 49 insertions, 2 deletions
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index a4693c0428be..771f7ada15d9 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -154,6 +154,34 @@ static void mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
154} 154}
155 155
156/* 156/*
157 * If we have fewer than thresh credits, extend by EXT3_MAX_TRANS_DATA.
158 * If that fails, restart the transaction & regain write access for the
159 * buffer head which is used for block_bitmap modifications.
160 */
161static int extend_or_restart_transaction(handle_t *handle, int thresh,
162 struct buffer_head *bh)
163{
164 int err;
165
166 if (handle->h_buffer_credits >= thresh)
167 return 0;
168
169 err = ext3_journal_extend(handle, EXT3_MAX_TRANS_DATA);
170 if (err < 0)
171 return err;
172 if (err) {
173 err = ext3_journal_restart(handle, EXT3_MAX_TRANS_DATA);
174 if (err)
175 return err;
176 err = ext3_journal_get_write_access(handle, bh);
177 if (err)
178 return err;
179 }
180
181 return 0;
182}
183
184/*
157 * Set up the block and inode bitmaps, and the inode table for the new group. 185 * Set up the block and inode bitmaps, and the inode table for the new group.
158 * This doesn't need to be part of the main transaction, since we are only 186 * This doesn't need to be part of the main transaction, since we are only
159 * changing blocks outside the actual filesystem. We still do journaling to 187 * changing blocks outside the actual filesystem. We still do journaling to
@@ -175,8 +203,9 @@ static int setup_new_group_blocks(struct super_block *sb,
175 int i; 203 int i;
176 int err = 0, err2; 204 int err = 0, err2;
177 205
178 handle = ext3_journal_start_sb(sb, reserved_gdb + gdblocks + 206 /* This transaction may be extended/restarted along the way */
179 2 + sbi->s_itb_per_group); 207 handle = ext3_journal_start_sb(sb, EXT3_MAX_TRANS_DATA);
208
180 if (IS_ERR(handle)) 209 if (IS_ERR(handle))
181 return PTR_ERR(handle); 210 return PTR_ERR(handle);
182 211
@@ -203,6 +232,10 @@ static int setup_new_group_blocks(struct super_block *sb,
203 232
204 ext3_debug("update backup group %#04lx (+%d)\n", block, bit); 233 ext3_debug("update backup group %#04lx (+%d)\n", block, bit);
205 234
235 err = extend_or_restart_transaction(handle, 1, bh);
236 if (err)
237 goto exit_bh;
238
206 gdb = sb_getblk(sb, block); 239 gdb = sb_getblk(sb, block);
207 if (!gdb) { 240 if (!gdb) {
208 err = -EIO; 241 err = -EIO;
@@ -228,6 +261,10 @@ static int setup_new_group_blocks(struct super_block *sb,
228 261
229 ext3_debug("clear reserved block %#04lx (+%d)\n", block, bit); 262 ext3_debug("clear reserved block %#04lx (+%d)\n", block, bit);
230 263
264 err = extend_or_restart_transaction(handle, 1, bh);
265 if (err)
266 goto exit_bh;
267
231 if (IS_ERR(gdb = bclean(handle, sb, block))) { 268 if (IS_ERR(gdb = bclean(handle, sb, block))) {
232 err = PTR_ERR(bh); 269 err = PTR_ERR(bh);
233 goto exit_bh; 270 goto exit_bh;
@@ -249,6 +286,11 @@ static int setup_new_group_blocks(struct super_block *sb,
249 struct buffer_head *it; 286 struct buffer_head *it;
250 287
251 ext3_debug("clear inode block %#04lx (+%d)\n", block, bit); 288 ext3_debug("clear inode block %#04lx (+%d)\n", block, bit);
289
290 err = extend_or_restart_transaction(handle, 1, bh);
291 if (err)
292 goto exit_bh;
293
252 if (IS_ERR(it = bclean(handle, sb, block))) { 294 if (IS_ERR(it = bclean(handle, sb, block))) {
253 err = PTR_ERR(it); 295 err = PTR_ERR(it);
254 goto exit_bh; 296 goto exit_bh;
@@ -257,6 +299,11 @@ static int setup_new_group_blocks(struct super_block *sb,
257 brelse(it); 299 brelse(it);
258 ext3_set_bit(bit, bh->b_data); 300 ext3_set_bit(bit, bh->b_data);
259 } 301 }
302
303 err = extend_or_restart_transaction(handle, 2, bh);
304 if (err)
305 goto exit_bh;
306
260 mark_bitmap_end(input->blocks_count, EXT3_BLOCKS_PER_GROUP(sb), 307 mark_bitmap_end(input->blocks_count, EXT3_BLOCKS_PER_GROUP(sb),
261 bh->b_data); 308 bh->b_data);
262 ext3_journal_dirty_metadata(handle, bh); 309 ext3_journal_dirty_metadata(handle, bh);