/* Verify that we are loading a valid orphan from disk */ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino) { unsigned long max_ino = le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count); unsigned long block_group; int bit; struct buffer_head *bitmap_bh = NULL; struct inode *inode = NULL; /* Error cases - e2fsck has already cleaned up for us */ if (ino > max_ino) { ext4_warning(sb, __FUNCTION__, "bad orphan ino %lu! e2fsck was run?", ino); goto out; } block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb); bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb); bitmap_bh = read_inode_bitmap(sb, block_group); if (!bitmap_bh) { ext4_warning(sb, __FUNCTION__, "inode bitmap error for orphan %lu", ino); goto out; } /* Having the inode bit set should be a 100% indicator that this * is a valid orphan (no e2fsck run on fs). Orphans also include * inodes that were being truncated, so we can't check i_nlink==0. */ if (!ext4_test_bit(bit, bitmap_bh->b_data) || !(inode = iget(sb, ino)) || is_bad_inode(inode) || NEXT_ORPHAN(inode) > max_ino) { ext4_warning(sb, __FUNCTION__, "bad orphan inode %lu! e2fsck was run?", ino); printk(KERN_NOTICE "ext4_test_bit(bit=%d, block=%llu) = %d\n", bit, (unsigned long long)bitmap_bh->b_blocknr, ext4_test_bit(bit, bitmap_bh->b_data)); printk(KERN_NOTICE "inode=%p\n", inode); if (inode) { printk(KERN_NOTICE "is_bad_inode(inode)=%d\n", is_bad_inode(inode)); printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n", NEXT_ORPHAN(inode)); printk(KERN_NOTICE "max_ino=%lu\n", max_ino); } /* Avoid freeing blocks if we got a bad deleted inode */ if (inode && inode->i_nlink == 0) inode->i_blocks = 0; iput(inode); inode = NULL; } out: brelse(bitmap_bh); return inode; }
static int ext4_valid_block_bitmap(struct super_block *sb, struct ext4_group_desc *desc, unsigned int block_group, struct buffer_head *bh) { ext4_grpblk_t offset; ext4_grpblk_t next_zero_bit; ext4_fsblk_t bitmap_blk; ext4_fsblk_t group_first_block; if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) { /* with FLEX_BG, the inode/block bitmaps and itable * blocks may not be in the group at all * so the bitmap validation will be skipped for those groups * or it has to also read the block group where the bitmaps * are located to verify they are set. */ return 1; } group_first_block = ext4_group_first_block_no(sb, block_group); /* check whether block bitmap block number is set */ bitmap_blk = ext4_block_bitmap(sb, desc); offset = bitmap_blk - group_first_block; if (!ext4_test_bit(offset, bh->b_data)) /* bad block bitmap */ goto err_out; /* check whether the inode bitmap block number is set */ bitmap_blk = ext4_inode_bitmap(sb, desc); offset = bitmap_blk - group_first_block; if (!ext4_test_bit(offset, bh->b_data)) /* bad block bitmap */ goto err_out; /* check whether the inode table block number is set */ bitmap_blk = ext4_inode_table(sb, desc); offset = bitmap_blk - group_first_block; next_zero_bit = ext4_find_next_zero_bit(bh->b_data, offset + EXT4_SB(sb)->s_itb_per_group, offset); if (next_zero_bit >= offset + EXT4_SB(sb)->s_itb_per_group) /* good bitmap for inode tables */ return 1; err_out: ext4_error(sb, __func__, "Invalid block bitmap - " "block_group = %d, block = %llu", block_group, bitmap_blk); return 0; }