diff options
Diffstat (limited to 'fs/ext4/balloc.c')
-rw-r--r-- | fs/ext4/balloc.c | 293 |
1 files changed, 94 insertions, 199 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 38b3acf5683b..6bba06b09dd1 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include "ext4.h" | 20 | #include "ext4.h" |
21 | #include "ext4_jbd2.h" | 21 | #include "ext4_jbd2.h" |
22 | #include "group.h" | 22 | #include "group.h" |
23 | #include "mballoc.h" | ||
23 | 24 | ||
24 | /* | 25 | /* |
25 | * balloc.c contains the blocks allocation and deallocation routines | 26 | * balloc.c contains the blocks allocation and deallocation routines |
@@ -100,10 +101,10 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, | |||
100 | * essentially implementing a per-group read-only flag. */ | 101 | * essentially implementing a per-group read-only flag. */ |
101 | if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) { | 102 | if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) { |
102 | ext4_error(sb, __func__, | 103 | ext4_error(sb, __func__, |
103 | "Checksum bad for group %lu\n", block_group); | 104 | "Checksum bad for group %u", block_group); |
104 | gdp->bg_free_blocks_count = 0; | 105 | ext4_free_blks_set(sb, gdp, 0); |
105 | gdp->bg_free_inodes_count = 0; | 106 | ext4_free_inodes_set(sb, gdp, 0); |
106 | gdp->bg_itable_unused = 0; | 107 | ext4_itable_unused_set(sb, gdp, 0); |
107 | memset(bh->b_data, 0xff, sb->s_blocksize); | 108 | memset(bh->b_data, 0xff, sb->s_blocksize); |
108 | return 0; | 109 | return 0; |
109 | } | 110 | } |
@@ -205,15 +206,15 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb, | |||
205 | ext4_group_t block_group, | 206 | ext4_group_t block_group, |
206 | struct buffer_head **bh) | 207 | struct buffer_head **bh) |
207 | { | 208 | { |
208 | unsigned long group_desc; | 209 | unsigned int group_desc; |
209 | unsigned long offset; | 210 | unsigned int offset; |
210 | struct ext4_group_desc *desc; | 211 | struct ext4_group_desc *desc; |
211 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 212 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
212 | 213 | ||
213 | if (block_group >= sbi->s_groups_count) { | 214 | if (block_group >= sbi->s_groups_count) { |
214 | ext4_error(sb, "ext4_get_group_desc", | 215 | ext4_error(sb, "ext4_get_group_desc", |
215 | "block_group >= groups_count - " | 216 | "block_group >= groups_count - " |
216 | "block_group = %lu, groups_count = %lu", | 217 | "block_group = %u, groups_count = %u", |
217 | block_group, sbi->s_groups_count); | 218 | block_group, sbi->s_groups_count); |
218 | 219 | ||
219 | return NULL; | 220 | return NULL; |
@@ -225,7 +226,7 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb, | |||
225 | if (!sbi->s_group_desc[group_desc]) { | 226 | if (!sbi->s_group_desc[group_desc]) { |
226 | ext4_error(sb, "ext4_get_group_desc", | 227 | ext4_error(sb, "ext4_get_group_desc", |
227 | "Group descriptor not loaded - " | 228 | "Group descriptor not loaded - " |
228 | "block_group = %lu, group_desc = %lu, desc = %lu", | 229 | "block_group = %u, group_desc = %u, desc = %u", |
229 | block_group, group_desc, offset); | 230 | block_group, group_desc, offset); |
230 | return NULL; | 231 | return NULL; |
231 | } | 232 | } |
@@ -315,29 +316,50 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group) | |||
315 | if (unlikely(!bh)) { | 316 | if (unlikely(!bh)) { |
316 | ext4_error(sb, __func__, | 317 | ext4_error(sb, __func__, |
317 | "Cannot read block bitmap - " | 318 | "Cannot read block bitmap - " |
318 | "block_group = %lu, block_bitmap = %llu", | 319 | "block_group = %u, block_bitmap = %llu", |
319 | block_group, bitmap_blk); | 320 | block_group, bitmap_blk); |
320 | return NULL; | 321 | return NULL; |
321 | } | 322 | } |
322 | if (buffer_uptodate(bh) && | 323 | |
323 | !(desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) | 324 | if (bitmap_uptodate(bh)) |
324 | return bh; | 325 | return bh; |
325 | 326 | ||
326 | lock_buffer(bh); | 327 | lock_buffer(bh); |
328 | if (bitmap_uptodate(bh)) { | ||
329 | unlock_buffer(bh); | ||
330 | return bh; | ||
331 | } | ||
327 | spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group)); | 332 | spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group)); |
328 | if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { | 333 | if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { |
329 | ext4_init_block_bitmap(sb, bh, block_group, desc); | 334 | ext4_init_block_bitmap(sb, bh, block_group, desc); |
335 | set_bitmap_uptodate(bh); | ||
330 | set_buffer_uptodate(bh); | 336 | set_buffer_uptodate(bh); |
331 | unlock_buffer(bh); | ||
332 | spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); | 337 | spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); |
338 | unlock_buffer(bh); | ||
333 | return bh; | 339 | return bh; |
334 | } | 340 | } |
335 | spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); | 341 | spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); |
342 | if (buffer_uptodate(bh)) { | ||
343 | /* | ||
344 | * if not uninit if bh is uptodate, | ||
345 | * bitmap is also uptodate | ||
346 | */ | ||
347 | set_bitmap_uptodate(bh); | ||
348 | unlock_buffer(bh); | ||
349 | return bh; | ||
350 | } | ||
351 | /* | ||
352 | * submit the buffer_head for read. We can | ||
353 | * safely mark the bitmap as uptodate now. | ||
354 | * We do it here so the bitmap uptodate bit | ||
355 | * get set with buffer lock held. | ||
356 | */ | ||
357 | set_bitmap_uptodate(bh); | ||
336 | if (bh_submit_read(bh) < 0) { | 358 | if (bh_submit_read(bh) < 0) { |
337 | put_bh(bh); | 359 | put_bh(bh); |
338 | ext4_error(sb, __func__, | 360 | ext4_error(sb, __func__, |
339 | "Cannot read block bitmap - " | 361 | "Cannot read block bitmap - " |
340 | "block_group = %lu, block_bitmap = %llu", | 362 | "block_group = %u, block_bitmap = %llu", |
341 | block_group, bitmap_blk); | 363 | block_group, bitmap_blk); |
342 | return NULL; | 364 | return NULL; |
343 | } | 365 | } |
@@ -350,62 +372,44 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group) | |||
350 | } | 372 | } |
351 | 373 | ||
352 | /** | 374 | /** |
353 | * ext4_free_blocks_sb() -- Free given blocks and update quota | 375 | * ext4_add_groupblocks() -- Add given blocks to an existing group |
354 | * @handle: handle to this transaction | 376 | * @handle: handle to this transaction |
355 | * @sb: super block | 377 | * @sb: super block |
356 | * @block: start physcial block to free | 378 | * @block: start physcial block to add to the block group |
357 | * @count: number of blocks to free | 379 | * @count: number of blocks to free |
358 | * @pdquot_freed_blocks: pointer to quota | ||
359 | * | 380 | * |
360 | * XXX This function is only used by the on-line resizing code, which | 381 | * This marks the blocks as free in the bitmap. We ask the |
361 | * should probably be fixed up to call the mballoc variant. There | 382 | * mballoc to reload the buddy after this by setting group |
362 | * this needs to be cleaned up later; in fact, I'm not convinced this | 383 | * EXT4_GROUP_INFO_NEED_INIT_BIT flag |
363 | * is 100% correct in the face of the mballoc code. The online resizing | ||
364 | * code needs to be fixed up to more tightly (and correctly) interlock | ||
365 | * with the mballoc code. | ||
366 | */ | 384 | */ |
367 | void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb, | 385 | void ext4_add_groupblocks(handle_t *handle, struct super_block *sb, |
368 | ext4_fsblk_t block, unsigned long count, | 386 | ext4_fsblk_t block, unsigned long count) |
369 | unsigned long *pdquot_freed_blocks) | ||
370 | { | 387 | { |
371 | struct buffer_head *bitmap_bh = NULL; | 388 | struct buffer_head *bitmap_bh = NULL; |
372 | struct buffer_head *gd_bh; | 389 | struct buffer_head *gd_bh; |
373 | ext4_group_t block_group; | 390 | ext4_group_t block_group; |
374 | ext4_grpblk_t bit; | 391 | ext4_grpblk_t bit; |
375 | unsigned long i; | 392 | unsigned int i; |
376 | unsigned long overflow; | ||
377 | struct ext4_group_desc *desc; | 393 | struct ext4_group_desc *desc; |
378 | struct ext4_super_block *es; | 394 | struct ext4_super_block *es; |
379 | struct ext4_sb_info *sbi; | 395 | struct ext4_sb_info *sbi; |
380 | int err = 0, ret; | 396 | int err = 0, ret, blk_free_count; |
381 | ext4_grpblk_t group_freed; | 397 | ext4_grpblk_t blocks_freed; |
398 | struct ext4_group_info *grp; | ||
382 | 399 | ||
383 | *pdquot_freed_blocks = 0; | ||
384 | sbi = EXT4_SB(sb); | 400 | sbi = EXT4_SB(sb); |
385 | es = sbi->s_es; | 401 | es = sbi->s_es; |
386 | if (block < le32_to_cpu(es->s_first_data_block) || | 402 | ext4_debug("Adding block(s) %llu-%llu\n", block, block + count - 1); |
387 | block + count < block || | ||
388 | block + count > ext4_blocks_count(es)) { | ||
389 | ext4_error(sb, "ext4_free_blocks", | ||
390 | "Freeing blocks not in datazone - " | ||
391 | "block = %llu, count = %lu", block, count); | ||
392 | goto error_return; | ||
393 | } | ||
394 | |||
395 | ext4_debug("freeing block(s) %llu-%llu\n", block, block + count - 1); | ||
396 | 403 | ||
397 | do_more: | ||
398 | overflow = 0; | ||
399 | ext4_get_group_no_and_offset(sb, block, &block_group, &bit); | 404 | ext4_get_group_no_and_offset(sb, block, &block_group, &bit); |
405 | grp = ext4_get_group_info(sb, block_group); | ||
400 | /* | 406 | /* |
401 | * Check to see if we are freeing blocks across a group | 407 | * Check to see if we are freeing blocks across a group |
402 | * boundary. | 408 | * boundary. |
403 | */ | 409 | */ |
404 | if (bit + count > EXT4_BLOCKS_PER_GROUP(sb)) { | 410 | if (bit + count > EXT4_BLOCKS_PER_GROUP(sb)) { |
405 | overflow = bit + count - EXT4_BLOCKS_PER_GROUP(sb); | 411 | goto error_return; |
406 | count -= overflow; | ||
407 | } | 412 | } |
408 | brelse(bitmap_bh); | ||
409 | bitmap_bh = ext4_read_block_bitmap(sb, block_group); | 413 | bitmap_bh = ext4_read_block_bitmap(sb, block_group); |
410 | if (!bitmap_bh) | 414 | if (!bitmap_bh) |
411 | goto error_return; | 415 | goto error_return; |
@@ -418,18 +422,17 @@ do_more: | |||
418 | in_range(block, ext4_inode_table(sb, desc), sbi->s_itb_per_group) || | 422 | in_range(block, ext4_inode_table(sb, desc), sbi->s_itb_per_group) || |
419 | in_range(block + count - 1, ext4_inode_table(sb, desc), | 423 | in_range(block + count - 1, ext4_inode_table(sb, desc), |
420 | sbi->s_itb_per_group)) { | 424 | sbi->s_itb_per_group)) { |
421 | ext4_error(sb, "ext4_free_blocks", | 425 | ext4_error(sb, __func__, |
422 | "Freeing blocks in system zones - " | 426 | "Adding blocks in system zones - " |
423 | "Block = %llu, count = %lu", | 427 | "Block = %llu, count = %lu", |
424 | block, count); | 428 | block, count); |
425 | goto error_return; | 429 | goto error_return; |
426 | } | 430 | } |
427 | 431 | ||
428 | /* | 432 | /* |
429 | * We are about to start releasing blocks in the bitmap, | 433 | * We are about to add blocks to the bitmap, |
430 | * so we need undo access. | 434 | * so we need undo access. |
431 | */ | 435 | */ |
432 | /* @@@ check errors */ | ||
433 | BUFFER_TRACE(bitmap_bh, "getting undo access"); | 436 | BUFFER_TRACE(bitmap_bh, "getting undo access"); |
434 | err = ext4_journal_get_undo_access(handle, bitmap_bh); | 437 | err = ext4_journal_get_undo_access(handle, bitmap_bh); |
435 | if (err) | 438 | if (err) |
@@ -444,107 +447,55 @@ do_more: | |||
444 | err = ext4_journal_get_write_access(handle, gd_bh); | 447 | err = ext4_journal_get_write_access(handle, gd_bh); |
445 | if (err) | 448 | if (err) |
446 | goto error_return; | 449 | goto error_return; |
447 | 450 | /* | |
448 | jbd_lock_bh_state(bitmap_bh); | 451 | * make sure we don't allow a parallel init on other groups in the |
449 | 452 | * same buddy cache | |
450 | for (i = 0, group_freed = 0; i < count; i++) { | 453 | */ |
451 | /* | 454 | down_write(&grp->alloc_sem); |
452 | * An HJ special. This is expensive... | 455 | for (i = 0, blocks_freed = 0; i < count; i++) { |
453 | */ | ||
454 | #ifdef CONFIG_JBD2_DEBUG | ||
455 | jbd_unlock_bh_state(bitmap_bh); | ||
456 | { | ||
457 | struct buffer_head *debug_bh; | ||
458 | debug_bh = sb_find_get_block(sb, block + i); | ||
459 | if (debug_bh) { | ||
460 | BUFFER_TRACE(debug_bh, "Deleted!"); | ||
461 | if (!bh2jh(bitmap_bh)->b_committed_data) | ||
462 | BUFFER_TRACE(debug_bh, | ||
463 | "No commited data in bitmap"); | ||
464 | BUFFER_TRACE2(debug_bh, bitmap_bh, "bitmap"); | ||
465 | __brelse(debug_bh); | ||
466 | } | ||
467 | } | ||
468 | jbd_lock_bh_state(bitmap_bh); | ||
469 | #endif | ||
470 | if (need_resched()) { | ||
471 | jbd_unlock_bh_state(bitmap_bh); | ||
472 | cond_resched(); | ||
473 | jbd_lock_bh_state(bitmap_bh); | ||
474 | } | ||
475 | /* @@@ This prevents newly-allocated data from being | ||
476 | * freed and then reallocated within the same | ||
477 | * transaction. | ||
478 | * | ||
479 | * Ideally we would want to allow that to happen, but to | ||
480 | * do so requires making jbd2_journal_forget() capable of | ||
481 | * revoking the queued write of a data block, which | ||
482 | * implies blocking on the journal lock. *forget() | ||
483 | * cannot block due to truncate races. | ||
484 | * | ||
485 | * Eventually we can fix this by making jbd2_journal_forget() | ||
486 | * return a status indicating whether or not it was able | ||
487 | * to revoke the buffer. On successful revoke, it is | ||
488 | * safe not to set the allocation bit in the committed | ||
489 | * bitmap, because we know that there is no outstanding | ||
490 | * activity on the buffer any more and so it is safe to | ||
491 | * reallocate it. | ||
492 | */ | ||
493 | BUFFER_TRACE(bitmap_bh, "set in b_committed_data"); | ||
494 | J_ASSERT_BH(bitmap_bh, | ||
495 | bh2jh(bitmap_bh)->b_committed_data != NULL); | ||
496 | ext4_set_bit_atomic(sb_bgl_lock(sbi, block_group), bit + i, | ||
497 | bh2jh(bitmap_bh)->b_committed_data); | ||
498 | |||
499 | /* | ||
500 | * We clear the bit in the bitmap after setting the committed | ||
501 | * data bit, because this is the reverse order to that which | ||
502 | * the allocator uses. | ||
503 | */ | ||
504 | BUFFER_TRACE(bitmap_bh, "clear bit"); | 456 | BUFFER_TRACE(bitmap_bh, "clear bit"); |
505 | if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group), | 457 | if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group), |
506 | bit + i, bitmap_bh->b_data)) { | 458 | bit + i, bitmap_bh->b_data)) { |
507 | jbd_unlock_bh_state(bitmap_bh); | ||
508 | ext4_error(sb, __func__, | 459 | ext4_error(sb, __func__, |
509 | "bit already cleared for block %llu", | 460 | "bit already cleared for block %llu", |
510 | (ext4_fsblk_t)(block + i)); | 461 | (ext4_fsblk_t)(block + i)); |
511 | jbd_lock_bh_state(bitmap_bh); | ||
512 | BUFFER_TRACE(bitmap_bh, "bit already cleared"); | 462 | BUFFER_TRACE(bitmap_bh, "bit already cleared"); |
513 | } else { | 463 | } else { |
514 | group_freed++; | 464 | blocks_freed++; |
515 | } | 465 | } |
516 | } | 466 | } |
517 | jbd_unlock_bh_state(bitmap_bh); | ||
518 | |||
519 | spin_lock(sb_bgl_lock(sbi, block_group)); | 467 | spin_lock(sb_bgl_lock(sbi, block_group)); |
520 | le16_add_cpu(&desc->bg_free_blocks_count, group_freed); | 468 | blk_free_count = blocks_freed + ext4_free_blks_count(sb, desc); |
469 | ext4_free_blks_set(sb, desc, blk_free_count); | ||
521 | desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc); | 470 | desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc); |
522 | spin_unlock(sb_bgl_lock(sbi, block_group)); | 471 | spin_unlock(sb_bgl_lock(sbi, block_group)); |
523 | percpu_counter_add(&sbi->s_freeblocks_counter, count); | 472 | percpu_counter_add(&sbi->s_freeblocks_counter, blocks_freed); |
524 | 473 | ||
525 | if (sbi->s_log_groups_per_flex) { | 474 | if (sbi->s_log_groups_per_flex) { |
526 | ext4_group_t flex_group = ext4_flex_group(sbi, block_group); | 475 | ext4_group_t flex_group = ext4_flex_group(sbi, block_group); |
527 | spin_lock(sb_bgl_lock(sbi, flex_group)); | 476 | spin_lock(sb_bgl_lock(sbi, flex_group)); |
528 | sbi->s_flex_groups[flex_group].free_blocks += count; | 477 | sbi->s_flex_groups[flex_group].free_blocks += blocks_freed; |
529 | spin_unlock(sb_bgl_lock(sbi, flex_group)); | 478 | spin_unlock(sb_bgl_lock(sbi, flex_group)); |
530 | } | 479 | } |
480 | /* | ||
481 | * request to reload the buddy with the | ||
482 | * new bitmap information | ||
483 | */ | ||
484 | set_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &(grp->bb_state)); | ||
485 | ext4_mb_update_group_info(grp, blocks_freed); | ||
486 | up_write(&grp->alloc_sem); | ||
531 | 487 | ||
532 | /* We dirtied the bitmap block */ | 488 | /* We dirtied the bitmap block */ |
533 | BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); | 489 | BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); |
534 | err = ext4_journal_dirty_metadata(handle, bitmap_bh); | 490 | err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh); |
535 | 491 | ||
536 | /* And the group descriptor block */ | 492 | /* And the group descriptor block */ |
537 | BUFFER_TRACE(gd_bh, "dirtied group descriptor block"); | 493 | BUFFER_TRACE(gd_bh, "dirtied group descriptor block"); |
538 | ret = ext4_journal_dirty_metadata(handle, gd_bh); | 494 | ret = ext4_handle_dirty_metadata(handle, NULL, gd_bh); |
539 | if (!err) err = ret; | 495 | if (!err) |
540 | *pdquot_freed_blocks += group_freed; | 496 | err = ret; |
541 | |||
542 | if (overflow && !err) { | ||
543 | block += count; | ||
544 | count = overflow; | ||
545 | goto do_more; | ||
546 | } | ||
547 | sb->s_dirt = 1; | 497 | sb->s_dirt = 1; |
498 | |||
548 | error_return: | 499 | error_return: |
549 | brelse(bitmap_bh); | 500 | brelse(bitmap_bh); |
550 | ext4_std_error(sb, err); | 501 | ext4_std_error(sb, err); |
@@ -614,7 +565,7 @@ int ext4_has_free_blocks(struct ext4_sb_info *sbi, s64 nblocks) | |||
614 | if (dirty_blocks < 0) { | 565 | if (dirty_blocks < 0) { |
615 | printk(KERN_CRIT "Dirty block accounting " | 566 | printk(KERN_CRIT "Dirty block accounting " |
616 | "went wrong %lld\n", | 567 | "went wrong %lld\n", |
617 | dirty_blocks); | 568 | (long long)dirty_blocks); |
618 | } | 569 | } |
619 | } | 570 | } |
620 | /* Check whether we have space after | 571 | /* Check whether we have space after |
@@ -666,101 +617,45 @@ int ext4_should_retry_alloc(struct super_block *sb, int *retries) | |||
666 | return jbd2_journal_force_commit_nested(EXT4_SB(sb)->s_journal); | 617 | return jbd2_journal_force_commit_nested(EXT4_SB(sb)->s_journal); |
667 | } | 618 | } |
668 | 619 | ||
669 | #define EXT4_META_BLOCK 0x1 | ||
670 | |||
671 | static ext4_fsblk_t do_blk_alloc(handle_t *handle, struct inode *inode, | ||
672 | ext4_lblk_t iblock, ext4_fsblk_t goal, | ||
673 | unsigned long *count, int *errp, int flags) | ||
674 | { | ||
675 | struct ext4_allocation_request ar; | ||
676 | ext4_fsblk_t ret; | ||
677 | |||
678 | memset(&ar, 0, sizeof(ar)); | ||
679 | /* Fill with neighbour allocated blocks */ | ||
680 | |||
681 | ar.inode = inode; | ||
682 | ar.goal = goal; | ||
683 | ar.len = *count; | ||
684 | ar.logical = iblock; | ||
685 | |||
686 | if (S_ISREG(inode->i_mode) && !(flags & EXT4_META_BLOCK)) | ||
687 | /* enable in-core preallocation for data block allocation */ | ||
688 | ar.flags = EXT4_MB_HINT_DATA; | ||
689 | else | ||
690 | /* disable in-core preallocation for non-regular files */ | ||
691 | ar.flags = 0; | ||
692 | |||
693 | ret = ext4_mb_new_blocks(handle, &ar, errp); | ||
694 | *count = ar.len; | ||
695 | return ret; | ||
696 | } | ||
697 | |||
698 | /* | 620 | /* |
699 | * ext4_new_meta_blocks() -- allocate block for meta data (indexing) blocks | 621 | * ext4_new_meta_blocks() -- allocate block for meta data (indexing) blocks |
700 | * | 622 | * |
701 | * @handle: handle to this transaction | 623 | * @handle: handle to this transaction |
702 | * @inode: file inode | 624 | * @inode: file inode |
703 | * @goal: given target block(filesystem wide) | 625 | * @goal: given target block(filesystem wide) |
704 | * @count: total number of blocks need | 626 | * @count: pointer to total number of blocks needed |
705 | * @errp: error code | 627 | * @errp: error code |
706 | * | 628 | * |
707 | * Return 1st allocated block numberon success, *count stores total account | 629 | * Return 1st allocated block number on success, *count stores total account |
708 | * error stores in errp pointer | 630 | * error stores in errp pointer |
709 | */ | 631 | */ |
710 | ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, | 632 | ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, |
711 | ext4_fsblk_t goal, unsigned long *count, int *errp) | 633 | ext4_fsblk_t goal, unsigned long *count, int *errp) |
712 | { | 634 | { |
635 | struct ext4_allocation_request ar; | ||
713 | ext4_fsblk_t ret; | 636 | ext4_fsblk_t ret; |
714 | ret = do_blk_alloc(handle, inode, 0, goal, | 637 | |
715 | count, errp, EXT4_META_BLOCK); | 638 | memset(&ar, 0, sizeof(ar)); |
639 | /* Fill with neighbour allocated blocks */ | ||
640 | ar.inode = inode; | ||
641 | ar.goal = goal; | ||
642 | ar.len = count ? *count : 1; | ||
643 | |||
644 | ret = ext4_mb_new_blocks(handle, &ar, errp); | ||
645 | if (count) | ||
646 | *count = ar.len; | ||
647 | |||
716 | /* | 648 | /* |
717 | * Account for the allocated meta blocks | 649 | * Account for the allocated meta blocks |
718 | */ | 650 | */ |
719 | if (!(*errp) && EXT4_I(inode)->i_delalloc_reserved_flag) { | 651 | if (!(*errp) && EXT4_I(inode)->i_delalloc_reserved_flag) { |
720 | spin_lock(&EXT4_I(inode)->i_block_reservation_lock); | 652 | spin_lock(&EXT4_I(inode)->i_block_reservation_lock); |
721 | EXT4_I(inode)->i_allocated_meta_blocks += *count; | 653 | EXT4_I(inode)->i_allocated_meta_blocks += ar.len; |
722 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); | 654 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); |
723 | } | 655 | } |
724 | return ret; | 656 | return ret; |
725 | } | 657 | } |
726 | 658 | ||
727 | /* | ||
728 | * ext4_new_meta_block() -- allocate block for meta data (indexing) blocks | ||
729 | * | ||
730 | * @handle: handle to this transaction | ||
731 | * @inode: file inode | ||
732 | * @goal: given target block(filesystem wide) | ||
733 | * @errp: error code | ||
734 | * | ||
735 | * Return allocated block number on success | ||
736 | */ | ||
737 | ext4_fsblk_t ext4_new_meta_block(handle_t *handle, struct inode *inode, | ||
738 | ext4_fsblk_t goal, int *errp) | ||
739 | { | ||
740 | unsigned long count = 1; | ||
741 | return ext4_new_meta_blocks(handle, inode, goal, &count, errp); | ||
742 | } | ||
743 | |||
744 | /* | ||
745 | * ext4_new_blocks() -- allocate data blocks | ||
746 | * | ||
747 | * @handle: handle to this transaction | ||
748 | * @inode: file inode | ||
749 | * @goal: given target block(filesystem wide) | ||
750 | * @count: total number of blocks need | ||
751 | * @errp: error code | ||
752 | * | ||
753 | * Return 1st allocated block numberon success, *count stores total account | ||
754 | * error stores in errp pointer | ||
755 | */ | ||
756 | |||
757 | ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, | ||
758 | ext4_lblk_t iblock, ext4_fsblk_t goal, | ||
759 | unsigned long *count, int *errp) | ||
760 | { | ||
761 | return do_blk_alloc(handle, inode, iblock, goal, count, errp, 0); | ||
762 | } | ||
763 | |||
764 | /** | 659 | /** |
765 | * ext4_count_free_blocks() -- count filesystem free blocks | 660 | * ext4_count_free_blocks() -- count filesystem free blocks |
766 | * @sb: superblock | 661 | * @sb: superblock |
@@ -776,7 +671,7 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb) | |||
776 | #ifdef EXT4FS_DEBUG | 671 | #ifdef EXT4FS_DEBUG |
777 | struct ext4_super_block *es; | 672 | struct ext4_super_block *es; |
778 | ext4_fsblk_t bitmap_count; | 673 | ext4_fsblk_t bitmap_count; |
779 | unsigned long x; | 674 | unsigned int x; |
780 | struct buffer_head *bitmap_bh = NULL; | 675 | struct buffer_head *bitmap_bh = NULL; |
781 | 676 | ||
782 | es = EXT4_SB(sb)->s_es; | 677 | es = EXT4_SB(sb)->s_es; |
@@ -796,7 +691,7 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb) | |||
796 | continue; | 691 | continue; |
797 | 692 | ||
798 | x = ext4_count_free(bitmap_bh, sb->s_blocksize); | 693 | x = ext4_count_free(bitmap_bh, sb->s_blocksize); |
799 | printk(KERN_DEBUG "group %lu: stored = %d, counted = %lu\n", | 694 | printk(KERN_DEBUG "group %lu: stored = %d, counted = %u\n", |
800 | i, le16_to_cpu(gdp->bg_free_blocks_count), x); | 695 | i, le16_to_cpu(gdp->bg_free_blocks_count), x); |
801 | bitmap_count += x; | 696 | bitmap_count += x; |
802 | } | 697 | } |
@@ -812,7 +707,7 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb) | |||
812 | gdp = ext4_get_group_desc(sb, i, NULL); | 707 | gdp = ext4_get_group_desc(sb, i, NULL); |
813 | if (!gdp) | 708 | if (!gdp) |
814 | continue; | 709 | continue; |
815 | desc_count += le16_to_cpu(gdp->bg_free_blocks_count); | 710 | desc_count += ext4_free_blks_count(sb, gdp); |
816 | } | 711 | } |
817 | 712 | ||
818 | return desc_count; | 713 | return desc_count; |