diff options
-rw-r--r-- | fs/ext3/balloc.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index bba4aeb4a708..7a2c7198b059 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c | |||
@@ -1206,7 +1206,7 @@ int ext3_new_blocks(handle_t *handle, struct inode *inode, | |||
1206 | /* | 1206 | /* |
1207 | * Check quota for allocation of this block. | 1207 | * Check quota for allocation of this block. |
1208 | */ | 1208 | */ |
1209 | if (DQUOT_ALLOC_BLOCK(inode, 1)) { | 1209 | if (DQUOT_ALLOC_BLOCK(inode, num)) { |
1210 | *errp = -EDQUOT; | 1210 | *errp = -EDQUOT; |
1211 | return 0; | 1211 | return 0; |
1212 | } | 1212 | } |
@@ -1333,13 +1333,15 @@ allocated: | |||
1333 | target_block = ret_block + group_no * EXT3_BLOCKS_PER_GROUP(sb) | 1333 | target_block = ret_block + group_no * EXT3_BLOCKS_PER_GROUP(sb) |
1334 | + le32_to_cpu(es->s_first_data_block); | 1334 | + le32_to_cpu(es->s_first_data_block); |
1335 | 1335 | ||
1336 | if (target_block == le32_to_cpu(gdp->bg_block_bitmap) || | 1336 | if (in_range(le32_to_cpu(gdp->bg_block_bitmap), target_block, num) || |
1337 | target_block == le32_to_cpu(gdp->bg_inode_bitmap) || | 1337 | in_range(le32_to_cpu(gdp->bg_inode_bitmap), target_block, num) || |
1338 | in_range(target_block, le32_to_cpu(gdp->bg_inode_table), | 1338 | in_range(target_block, le32_to_cpu(gdp->bg_inode_table), |
1339 | EXT3_SB(sb)->s_itb_per_group) || | ||
1340 | in_range(target_block + num - 1, le32_to_cpu(gdp->bg_inode_table), | ||
1339 | EXT3_SB(sb)->s_itb_per_group)) | 1341 | EXT3_SB(sb)->s_itb_per_group)) |
1340 | ext3_error(sb, "ext3_new_block", | 1342 | ext3_error(sb, "ext3_new_block", |
1341 | "Allocating block in system zone - " | 1343 | "Allocating block in system zone - " |
1342 | "block = %u", target_block); | 1344 | "blocks from %u, length %lu", target_block, num); |
1343 | 1345 | ||
1344 | performed_allocation = 1; | 1346 | performed_allocation = 1; |
1345 | 1347 | ||
@@ -1358,10 +1360,14 @@ allocated: | |||
1358 | jbd_lock_bh_state(bitmap_bh); | 1360 | jbd_lock_bh_state(bitmap_bh); |
1359 | spin_lock(sb_bgl_lock(sbi, group_no)); | 1361 | spin_lock(sb_bgl_lock(sbi, group_no)); |
1360 | if (buffer_jbd(bitmap_bh) && bh2jh(bitmap_bh)->b_committed_data) { | 1362 | if (buffer_jbd(bitmap_bh) && bh2jh(bitmap_bh)->b_committed_data) { |
1361 | if (ext3_test_bit(ret_block, | 1363 | int i; |
1362 | bh2jh(bitmap_bh)->b_committed_data)) { | 1364 | |
1363 | printk("%s: block was unexpectedly set in " | 1365 | for (i = 0; i < num; i++) { |
1364 | "b_committed_data\n", __FUNCTION__); | 1366 | if (ext3_test_bit(ret_block, |
1367 | bh2jh(bitmap_bh)->b_committed_data)) { | ||
1368 | printk("%s: block was unexpectedly set in " | ||
1369 | "b_committed_data\n", __FUNCTION__); | ||
1370 | } | ||
1365 | } | 1371 | } |
1366 | } | 1372 | } |
1367 | ext3_debug("found bit %d\n", ret_block); | 1373 | ext3_debug("found bit %d\n", ret_block); |
@@ -1372,7 +1378,7 @@ allocated: | |||
1372 | /* ret_block was blockgroup-relative. Now it becomes fs-relative */ | 1378 | /* ret_block was blockgroup-relative. Now it becomes fs-relative */ |
1373 | ret_block = target_block; | 1379 | ret_block = target_block; |
1374 | 1380 | ||
1375 | if (ret_block >= le32_to_cpu(es->s_blocks_count)) { | 1381 | if (ret_block + num - 1 >= le32_to_cpu(es->s_blocks_count)) { |
1376 | ext3_error(sb, "ext3_new_block", | 1382 | ext3_error(sb, "ext3_new_block", |
1377 | "block(%d) >= blocks count(%d) - " | 1383 | "block(%d) >= blocks count(%d) - " |
1378 | "block_group = %d, es == %p ", ret_block, | 1384 | "block_group = %d, es == %p ", ret_block, |
@@ -1390,9 +1396,9 @@ allocated: | |||
1390 | 1396 | ||
1391 | spin_lock(sb_bgl_lock(sbi, group_no)); | 1397 | spin_lock(sb_bgl_lock(sbi, group_no)); |
1392 | gdp->bg_free_blocks_count = | 1398 | gdp->bg_free_blocks_count = |
1393 | cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) - 1); | 1399 | cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) - num); |
1394 | spin_unlock(sb_bgl_lock(sbi, group_no)); | 1400 | spin_unlock(sb_bgl_lock(sbi, group_no)); |
1395 | percpu_counter_mod(&sbi->s_freeblocks_counter, -1); | 1401 | percpu_counter_mod(&sbi->s_freeblocks_counter, -num); |
1396 | 1402 | ||
1397 | BUFFER_TRACE(gdp_bh, "journal_dirty_metadata for group descriptor"); | 1403 | BUFFER_TRACE(gdp_bh, "journal_dirty_metadata for group descriptor"); |
1398 | err = ext3_journal_dirty_metadata(handle, gdp_bh); | 1404 | err = ext3_journal_dirty_metadata(handle, gdp_bh); |
@@ -1405,6 +1411,7 @@ allocated: | |||
1405 | 1411 | ||
1406 | *errp = 0; | 1412 | *errp = 0; |
1407 | brelse(bitmap_bh); | 1413 | brelse(bitmap_bh); |
1414 | DQUOT_FREE_BLOCK(inode, *count-num); | ||
1408 | *count = num; | 1415 | *count = num; |
1409 | return ret_block; | 1416 | return ret_block; |
1410 | 1417 | ||
@@ -1419,7 +1426,7 @@ out: | |||
1419 | * Undo the block allocation | 1426 | * Undo the block allocation |
1420 | */ | 1427 | */ |
1421 | if (!performed_allocation) | 1428 | if (!performed_allocation) |
1422 | DQUOT_FREE_BLOCK(inode, 1); | 1429 | DQUOT_FREE_BLOCK(inode, *count); |
1423 | brelse(bitmap_bh); | 1430 | brelse(bitmap_bh); |
1424 | return 0; | 1431 | return 0; |
1425 | } | 1432 | } |