diff options
Diffstat (limited to 'fs/ext4/ialloc.c')
| -rw-r--r-- | fs/ext4/ialloc.c | 58 |
1 files changed, 34 insertions, 24 deletions
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index a92eb305344f..655e760212b8 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
| @@ -97,34 +97,44 @@ unsigned ext4_init_inode_bitmap(struct super_block *sb, struct buffer_head *bh, | |||
| 97 | * Return buffer_head of bitmap on success or NULL. | 97 | * Return buffer_head of bitmap on success or NULL. |
| 98 | */ | 98 | */ |
| 99 | static struct buffer_head * | 99 | static struct buffer_head * |
| 100 | read_inode_bitmap(struct super_block *sb, ext4_group_t block_group) | 100 | ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group) |
| 101 | { | 101 | { |
| 102 | struct ext4_group_desc *desc; | 102 | struct ext4_group_desc *desc; |
| 103 | struct buffer_head *bh = NULL; | 103 | struct buffer_head *bh = NULL; |
| 104 | ext4_fsblk_t bitmap_blk; | ||
| 104 | 105 | ||
| 105 | desc = ext4_get_group_desc(sb, block_group, NULL); | 106 | desc = ext4_get_group_desc(sb, block_group, NULL); |
| 106 | if (!desc) | 107 | if (!desc) |
| 107 | goto error_out; | 108 | return NULL; |
| 108 | if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { | 109 | bitmap_blk = ext4_inode_bitmap(sb, desc); |
| 109 | bh = sb_getblk(sb, ext4_inode_bitmap(sb, desc)); | 110 | bh = sb_getblk(sb, bitmap_blk); |
| 110 | if (!buffer_uptodate(bh)) { | 111 | if (unlikely(!bh)) { |
| 111 | lock_buffer(bh); | 112 | ext4_error(sb, __func__, |
| 112 | if (!buffer_uptodate(bh)) { | 113 | "Cannot read inode bitmap - " |
| 113 | ext4_init_inode_bitmap(sb, bh, block_group, | 114 | "block_group = %lu, inode_bitmap = %llu", |
| 114 | desc); | 115 | block_group, bitmap_blk); |
| 115 | set_buffer_uptodate(bh); | 116 | return NULL; |
| 116 | } | ||
| 117 | unlock_buffer(bh); | ||
| 118 | } | ||
| 119 | } else { | ||
| 120 | bh = sb_bread(sb, ext4_inode_bitmap(sb, desc)); | ||
| 121 | } | 117 | } |
| 122 | if (!bh) | 118 | if (bh_uptodate_or_lock(bh)) |
| 123 | ext4_error(sb, "read_inode_bitmap", | 119 | return bh; |
| 120 | |||
| 121 | spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group)); | ||
| 122 | if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { | ||
| 123 | ext4_init_inode_bitmap(sb, bh, block_group, desc); | ||
| 124 | set_buffer_uptodate(bh); | ||
| 125 | unlock_buffer(bh); | ||
| 126 | spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); | ||
| 127 | return bh; | ||
| 128 | } | ||
| 129 | spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); | ||
| 130 | if (bh_submit_read(bh) < 0) { | ||
| 131 | put_bh(bh); | ||
| 132 | ext4_error(sb, __func__, | ||
| 124 | "Cannot read inode bitmap - " | 133 | "Cannot read inode bitmap - " |
| 125 | "block_group = %lu, inode_bitmap = %llu", | 134 | "block_group = %lu, inode_bitmap = %llu", |
| 126 | block_group, ext4_inode_bitmap(sb, desc)); | 135 | block_group, bitmap_blk); |
| 127 | error_out: | 136 | return NULL; |
| 137 | } | ||
| 128 | return bh; | 138 | return bh; |
| 129 | } | 139 | } |
| 130 | 140 | ||
| @@ -200,7 +210,7 @@ void ext4_free_inode (handle_t *handle, struct inode * inode) | |||
| 200 | } | 210 | } |
| 201 | block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb); | 211 | block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb); |
| 202 | bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb); | 212 | bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb); |
| 203 | bitmap_bh = read_inode_bitmap(sb, block_group); | 213 | bitmap_bh = ext4_read_inode_bitmap(sb, block_group); |
| 204 | if (!bitmap_bh) | 214 | if (!bitmap_bh) |
| 205 | goto error_return; | 215 | goto error_return; |
| 206 | 216 | ||
| @@ -623,7 +633,7 @@ got_group: | |||
| 623 | goto fail; | 633 | goto fail; |
| 624 | 634 | ||
| 625 | brelse(bitmap_bh); | 635 | brelse(bitmap_bh); |
| 626 | bitmap_bh = read_inode_bitmap(sb, group); | 636 | bitmap_bh = ext4_read_inode_bitmap(sb, group); |
| 627 | if (!bitmap_bh) | 637 | if (!bitmap_bh) |
| 628 | goto fail; | 638 | goto fail; |
| 629 | 639 | ||
| @@ -728,7 +738,7 @@ got: | |||
| 728 | 738 | ||
| 729 | /* When marking the block group with | 739 | /* When marking the block group with |
| 730 | * ~EXT4_BG_INODE_UNINIT we don't want to depend | 740 | * ~EXT4_BG_INODE_UNINIT we don't want to depend |
| 731 | * on the value of bg_itable_unsed even though | 741 | * on the value of bg_itable_unused even though |
| 732 | * mke2fs could have initialized the same for us. | 742 | * mke2fs could have initialized the same for us. |
| 733 | * Instead we calculated the value below | 743 | * Instead we calculated the value below |
| 734 | */ | 744 | */ |
| @@ -891,7 +901,7 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino) | |||
| 891 | 901 | ||
| 892 | block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb); | 902 | block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb); |
| 893 | bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb); | 903 | bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb); |
| 894 | bitmap_bh = read_inode_bitmap(sb, block_group); | 904 | bitmap_bh = ext4_read_inode_bitmap(sb, block_group); |
| 895 | if (!bitmap_bh) { | 905 | if (!bitmap_bh) { |
| 896 | ext4_warning(sb, __func__, | 906 | ext4_warning(sb, __func__, |
| 897 | "inode bitmap error for orphan %lu", ino); | 907 | "inode bitmap error for orphan %lu", ino); |
| @@ -969,7 +979,7 @@ unsigned long ext4_count_free_inodes (struct super_block * sb) | |||
| 969 | continue; | 979 | continue; |
| 970 | desc_count += le16_to_cpu(gdp->bg_free_inodes_count); | 980 | desc_count += le16_to_cpu(gdp->bg_free_inodes_count); |
| 971 | brelse(bitmap_bh); | 981 | brelse(bitmap_bh); |
| 972 | bitmap_bh = read_inode_bitmap(sb, i); | 982 | bitmap_bh = ext4_read_inode_bitmap(sb, i); |
| 973 | if (!bitmap_bh) | 983 | if (!bitmap_bh) |
| 974 | continue; | 984 | continue; |
| 975 | 985 | ||
