diff options
Diffstat (limited to 'fs/ext3/ialloc.c')
-rw-r--r-- | fs/ext3/ialloc.c | 70 |
1 files changed, 39 insertions, 31 deletions
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 1bc8cd89c51d..4f4020c54683 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c | |||
@@ -164,11 +164,9 @@ void ext3_free_inode (handle_t *handle, struct inode * inode) | |||
164 | 164 | ||
165 | if (gdp) { | 165 | if (gdp) { |
166 | spin_lock(sb_bgl_lock(sbi, block_group)); | 166 | spin_lock(sb_bgl_lock(sbi, block_group)); |
167 | gdp->bg_free_inodes_count = cpu_to_le16( | 167 | le16_add_cpu(&gdp->bg_free_inodes_count, 1); |
168 | le16_to_cpu(gdp->bg_free_inodes_count) + 1); | ||
169 | if (is_directory) | 168 | if (is_directory) |
170 | gdp->bg_used_dirs_count = cpu_to_le16( | 169 | le16_add_cpu(&gdp->bg_used_dirs_count, -1); |
171 | le16_to_cpu(gdp->bg_used_dirs_count) - 1); | ||
172 | spin_unlock(sb_bgl_lock(sbi, block_group)); | 170 | spin_unlock(sb_bgl_lock(sbi, block_group)); |
173 | percpu_counter_inc(&sbi->s_freeinodes_counter); | 171 | percpu_counter_inc(&sbi->s_freeinodes_counter); |
174 | if (is_directory) | 172 | if (is_directory) |
@@ -527,11 +525,9 @@ got: | |||
527 | err = ext3_journal_get_write_access(handle, bh2); | 525 | err = ext3_journal_get_write_access(handle, bh2); |
528 | if (err) goto fail; | 526 | if (err) goto fail; |
529 | spin_lock(sb_bgl_lock(sbi, group)); | 527 | spin_lock(sb_bgl_lock(sbi, group)); |
530 | gdp->bg_free_inodes_count = | 528 | le16_add_cpu(&gdp->bg_free_inodes_count, -1); |
531 | cpu_to_le16(le16_to_cpu(gdp->bg_free_inodes_count) - 1); | ||
532 | if (S_ISDIR(mode)) { | 529 | if (S_ISDIR(mode)) { |
533 | gdp->bg_used_dirs_count = | 530 | le16_add_cpu(&gdp->bg_used_dirs_count, 1); |
534 | cpu_to_le16(le16_to_cpu(gdp->bg_used_dirs_count) + 1); | ||
535 | } | 531 | } |
536 | spin_unlock(sb_bgl_lock(sbi, group)); | 532 | spin_unlock(sb_bgl_lock(sbi, group)); |
537 | BUFFER_TRACE(bh2, "call ext3_journal_dirty_metadata"); | 533 | BUFFER_TRACE(bh2, "call ext3_journal_dirty_metadata"); |
@@ -642,14 +638,15 @@ struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino) | |||
642 | unsigned long max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count); | 638 | unsigned long max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count); |
643 | unsigned long block_group; | 639 | unsigned long block_group; |
644 | int bit; | 640 | int bit; |
645 | struct buffer_head *bitmap_bh = NULL; | 641 | struct buffer_head *bitmap_bh; |
646 | struct inode *inode = NULL; | 642 | struct inode *inode = NULL; |
643 | long err = -EIO; | ||
647 | 644 | ||
648 | /* Error cases - e2fsck has already cleaned up for us */ | 645 | /* Error cases - e2fsck has already cleaned up for us */ |
649 | if (ino > max_ino) { | 646 | if (ino > max_ino) { |
650 | ext3_warning(sb, __FUNCTION__, | 647 | ext3_warning(sb, __FUNCTION__, |
651 | "bad orphan ino %lu! e2fsck was run?", ino); | 648 | "bad orphan ino %lu! e2fsck was run?", ino); |
652 | goto out; | 649 | goto error; |
653 | } | 650 | } |
654 | 651 | ||
655 | block_group = (ino - 1) / EXT3_INODES_PER_GROUP(sb); | 652 | block_group = (ino - 1) / EXT3_INODES_PER_GROUP(sb); |
@@ -658,38 +655,49 @@ struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino) | |||
658 | if (!bitmap_bh) { | 655 | if (!bitmap_bh) { |
659 | ext3_warning(sb, __FUNCTION__, | 656 | ext3_warning(sb, __FUNCTION__, |
660 | "inode bitmap error for orphan %lu", ino); | 657 | "inode bitmap error for orphan %lu", ino); |
661 | goto out; | 658 | goto error; |
662 | } | 659 | } |
663 | 660 | ||
664 | /* Having the inode bit set should be a 100% indicator that this | 661 | /* Having the inode bit set should be a 100% indicator that this |
665 | * is a valid orphan (no e2fsck run on fs). Orphans also include | 662 | * is a valid orphan (no e2fsck run on fs). Orphans also include |
666 | * inodes that were being truncated, so we can't check i_nlink==0. | 663 | * inodes that were being truncated, so we can't check i_nlink==0. |
667 | */ | 664 | */ |
668 | if (!ext3_test_bit(bit, bitmap_bh->b_data) || | 665 | if (!ext3_test_bit(bit, bitmap_bh->b_data)) |
669 | !(inode = iget(sb, ino)) || is_bad_inode(inode) || | 666 | goto bad_orphan; |
670 | NEXT_ORPHAN(inode) > max_ino) { | 667 | |
671 | ext3_warning(sb, __FUNCTION__, | 668 | inode = ext3_iget(sb, ino); |
672 | "bad orphan inode %lu! e2fsck was run?", ino); | 669 | if (IS_ERR(inode)) |
673 | printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%llu) = %d\n", | 670 | goto iget_failed; |
674 | bit, (unsigned long long)bitmap_bh->b_blocknr, | 671 | |
675 | ext3_test_bit(bit, bitmap_bh->b_data)); | 672 | if (NEXT_ORPHAN(inode) > max_ino) |
676 | printk(KERN_NOTICE "inode=%p\n", inode); | 673 | goto bad_orphan; |
677 | if (inode) { | 674 | brelse(bitmap_bh); |
678 | printk(KERN_NOTICE "is_bad_inode(inode)=%d\n", | 675 | return inode; |
679 | is_bad_inode(inode)); | 676 | |
680 | printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n", | 677 | iget_failed: |
681 | NEXT_ORPHAN(inode)); | 678 | err = PTR_ERR(inode); |
682 | printk(KERN_NOTICE "max_ino=%lu\n", max_ino); | 679 | inode = NULL; |
683 | } | 680 | bad_orphan: |
681 | ext3_warning(sb, __FUNCTION__, | ||
682 | "bad orphan inode %lu! e2fsck was run?", ino); | ||
683 | printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%llu) = %d\n", | ||
684 | bit, (unsigned long long)bitmap_bh->b_blocknr, | ||
685 | ext3_test_bit(bit, bitmap_bh->b_data)); | ||
686 | printk(KERN_NOTICE "inode=%p\n", inode); | ||
687 | if (inode) { | ||
688 | printk(KERN_NOTICE "is_bad_inode(inode)=%d\n", | ||
689 | is_bad_inode(inode)); | ||
690 | printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n", | ||
691 | NEXT_ORPHAN(inode)); | ||
692 | printk(KERN_NOTICE "max_ino=%lu\n", max_ino); | ||
684 | /* Avoid freeing blocks if we got a bad deleted inode */ | 693 | /* Avoid freeing blocks if we got a bad deleted inode */ |
685 | if (inode && inode->i_nlink == 0) | 694 | if (inode->i_nlink == 0) |
686 | inode->i_blocks = 0; | 695 | inode->i_blocks = 0; |
687 | iput(inode); | 696 | iput(inode); |
688 | inode = NULL; | ||
689 | } | 697 | } |
690 | out: | ||
691 | brelse(bitmap_bh); | 698 | brelse(bitmap_bh); |
692 | return inode; | 699 | error: |
700 | return ERR_PTR(err); | ||
693 | } | 701 | } |
694 | 702 | ||
695 | unsigned long ext3_count_free_inodes (struct super_block * sb) | 703 | unsigned long ext3_count_free_inodes (struct super_block * sb) |