~ubuntu-branches/ubuntu/quantal/linux-linaro-mx51/quantal

« back to all changes in this revision

Viewing changes to fs/ext4/balloc.c

  • Committer: Package Import Robot
  • Author(s): John Rigby, John Rigby
  • Date: 2011-09-26 10:44:23 UTC
  • Revision ID: package-import@ubuntu.com-20110926104423-3o58a3c1bj7x00rs
Tags: 3.0.0-1007.9
[ John Rigby ]

Enable crypto modules and remove crypto-modules from
exclude-module files
LP: #826021

Show diffs side-by-side

added added

removed removed

Lines of Context:
362
362
}
363
363
 
364
364
/**
365
 
 * ext4_add_groupblocks() -- Add given blocks to an existing group
366
 
 * @handle:                     handle to this transaction
367
 
 * @sb:                         super block
368
 
 * @block:                      start physcial block to add to the block group
369
 
 * @count:                      number of blocks to free
370
 
 *
371
 
 * This marks the blocks as free in the bitmap. We ask the
372
 
 * mballoc to reload the buddy after this by setting group
373
 
 * EXT4_GROUP_INFO_NEED_INIT_BIT flag
374
 
 */
375
 
void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
376
 
                         ext4_fsblk_t block, unsigned long count)
377
 
{
378
 
        struct buffer_head *bitmap_bh = NULL;
379
 
        struct buffer_head *gd_bh;
380
 
        ext4_group_t block_group;
381
 
        ext4_grpblk_t bit;
382
 
        unsigned int i;
383
 
        struct ext4_group_desc *desc;
384
 
        struct ext4_sb_info *sbi = EXT4_SB(sb);
385
 
        int err = 0, ret, blk_free_count;
386
 
        ext4_grpblk_t blocks_freed;
387
 
        struct ext4_group_info *grp;
388
 
 
389
 
        ext4_debug("Adding block(s) %llu-%llu\n", block, block + count - 1);
390
 
 
391
 
        ext4_get_group_no_and_offset(sb, block, &block_group, &bit);
392
 
        grp = ext4_get_group_info(sb, block_group);
393
 
        /*
394
 
         * Check to see if we are freeing blocks across a group
395
 
         * boundary.
396
 
         */
397
 
        if (bit + count > EXT4_BLOCKS_PER_GROUP(sb)) {
398
 
                goto error_return;
399
 
        }
400
 
        bitmap_bh = ext4_read_block_bitmap(sb, block_group);
401
 
        if (!bitmap_bh)
402
 
                goto error_return;
403
 
        desc = ext4_get_group_desc(sb, block_group, &gd_bh);
404
 
        if (!desc)
405
 
                goto error_return;
406
 
 
407
 
        if (in_range(ext4_block_bitmap(sb, desc), block, count) ||
408
 
            in_range(ext4_inode_bitmap(sb, desc), block, count) ||
409
 
            in_range(block, ext4_inode_table(sb, desc), sbi->s_itb_per_group) ||
410
 
            in_range(block + count - 1, ext4_inode_table(sb, desc),
411
 
                     sbi->s_itb_per_group)) {
412
 
                ext4_error(sb, "Adding blocks in system zones - "
413
 
                           "Block = %llu, count = %lu",
414
 
                           block, count);
415
 
                goto error_return;
416
 
        }
417
 
 
418
 
        /*
419
 
         * We are about to add blocks to the bitmap,
420
 
         * so we need undo access.
421
 
         */
422
 
        BUFFER_TRACE(bitmap_bh, "getting undo access");
423
 
        err = ext4_journal_get_undo_access(handle, bitmap_bh);
424
 
        if (err)
425
 
                goto error_return;
426
 
 
427
 
        /*
428
 
         * We are about to modify some metadata.  Call the journal APIs
429
 
         * to unshare ->b_data if a currently-committing transaction is
430
 
         * using it
431
 
         */
432
 
        BUFFER_TRACE(gd_bh, "get_write_access");
433
 
        err = ext4_journal_get_write_access(handle, gd_bh);
434
 
        if (err)
435
 
                goto error_return;
436
 
        /*
437
 
         * make sure we don't allow a parallel init on other groups in the
438
 
         * same buddy cache
439
 
         */
440
 
        down_write(&grp->alloc_sem);
441
 
        for (i = 0, blocks_freed = 0; i < count; i++) {
442
 
                BUFFER_TRACE(bitmap_bh, "clear bit");
443
 
                if (!ext4_clear_bit_atomic(ext4_group_lock_ptr(sb, block_group),
444
 
                                                bit + i, bitmap_bh->b_data)) {
445
 
                        ext4_error(sb, "bit already cleared for block %llu",
446
 
                                   (ext4_fsblk_t)(block + i));
447
 
                        BUFFER_TRACE(bitmap_bh, "bit already cleared");
448
 
                } else {
449
 
                        blocks_freed++;
450
 
                }
451
 
        }
452
 
        ext4_lock_group(sb, block_group);
453
 
        blk_free_count = blocks_freed + ext4_free_blks_count(sb, desc);
454
 
        ext4_free_blks_set(sb, desc, blk_free_count);
455
 
        desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc);
456
 
        ext4_unlock_group(sb, block_group);
457
 
        percpu_counter_add(&sbi->s_freeblocks_counter, blocks_freed);
458
 
 
459
 
        if (sbi->s_log_groups_per_flex) {
460
 
                ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
461
 
                atomic_add(blocks_freed,
462
 
                           &sbi->s_flex_groups[flex_group].free_blocks);
463
 
        }
464
 
        /*
465
 
         * request to reload the buddy with the
466
 
         * new bitmap information
467
 
         */
468
 
        set_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &(grp->bb_state));
469
 
        grp->bb_free += blocks_freed;
470
 
        up_write(&grp->alloc_sem);
471
 
 
472
 
        /* We dirtied the bitmap block */
473
 
        BUFFER_TRACE(bitmap_bh, "dirtied bitmap block");
474
 
        err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
475
 
 
476
 
        /* And the group descriptor block */
477
 
        BUFFER_TRACE(gd_bh, "dirtied group descriptor block");
478
 
        ret = ext4_handle_dirty_metadata(handle, NULL, gd_bh);
479
 
        if (!err)
480
 
                err = ret;
481
 
 
482
 
error_return:
483
 
        brelse(bitmap_bh);
484
 
        ext4_std_error(sb, err);
485
 
        return;
486
 
}
487
 
 
488
 
/**
489
365
 * ext4_has_free_blocks()
490
366
 * @sbi:        in-core super block structure.
491
367
 * @nblocks:    number of needed blocks
493
369
 * Check if filesystem has nblocks free & available for allocation.
494
370
 * On success return 1, return 0 on failure.
495
371
 */
496
 
static int ext4_has_free_blocks(struct ext4_sb_info *sbi, s64 nblocks)
 
372
static int ext4_has_free_blocks(struct ext4_sb_info *sbi,
 
373
                                s64 nblocks, unsigned int flags)
497
374
{
498
375
        s64 free_blocks, dirty_blocks, root_blocks;
499
376
        struct percpu_counter *fbc = &sbi->s_freeblocks_counter;
507
384
                                                EXT4_FREEBLOCKS_WATERMARK) {
508
385
                free_blocks  = percpu_counter_sum_positive(fbc);
509
386
                dirty_blocks = percpu_counter_sum_positive(dbc);
510
 
                if (dirty_blocks < 0) {
511
 
                        printk(KERN_CRIT "Dirty block accounting "
512
 
                                        "went wrong %lld\n",
513
 
                                        (long long)dirty_blocks);
514
 
                }
515
387
        }
516
388
        /* Check whether we have space after
517
389
         * accounting for current dirty blocks & root reserved blocks.
522
394
        /* Hm, nope.  Are (enough) root reserved blocks available? */
523
395
        if (sbi->s_resuid == current_fsuid() ||
524
396
            ((sbi->s_resgid != 0) && in_group_p(sbi->s_resgid)) ||
525
 
            capable(CAP_SYS_RESOURCE)) {
 
397
            capable(CAP_SYS_RESOURCE) ||
 
398
                (flags & EXT4_MB_USE_ROOT_BLOCKS)) {
 
399
 
526
400
                if (free_blocks >= (nblocks + dirty_blocks))
527
401
                        return 1;
528
402
        }
531
405
}
532
406
 
533
407
int ext4_claim_free_blocks(struct ext4_sb_info *sbi,
534
 
                                                s64 nblocks)
 
408
                           s64 nblocks, unsigned int flags)
535
409
{
536
 
        if (ext4_has_free_blocks(sbi, nblocks)) {
 
410
        if (ext4_has_free_blocks(sbi, nblocks, flags)) {
537
411
                percpu_counter_add(&sbi->s_dirtyblocks_counter, nblocks);
538
412
                return 0;
539
413
        } else
554
428
 */
555
429
int ext4_should_retry_alloc(struct super_block *sb, int *retries)
556
430
{
557
 
        if (!ext4_has_free_blocks(EXT4_SB(sb), 1) ||
 
431
        if (!ext4_has_free_blocks(EXT4_SB(sb), 1, 0) ||
558
432
            (*retries)++ > 3 ||
559
433
            !EXT4_SB(sb)->s_journal)
560
434
                return 0;
577
451
 * error stores in errp pointer
578
452
 */
579
453
ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode,
580
 
                ext4_fsblk_t goal, unsigned long *count, int *errp)
 
454
                                  ext4_fsblk_t goal, unsigned int flags,
 
455
                                  unsigned long *count, int *errp)
581
456
{
582
457
        struct ext4_allocation_request ar;
583
458
        ext4_fsblk_t ret;
587
462
        ar.inode = inode;
588
463
        ar.goal = goal;
589
464
        ar.len = count ? *count : 1;
 
465
        ar.flags = flags;
590
466
 
591
467
        ret = ext4_mb_new_blocks(handle, &ar, errp);
592
468
        if (count)