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 | ||