diff options
Diffstat (limited to 'fs/reiserfs/resize.c')
-rw-r--r-- | fs/reiserfs/resize.c | 60 |
1 files changed, 35 insertions, 25 deletions
diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c index 39cc7f47f5dc..958b75978994 100644 --- a/fs/reiserfs/resize.c +++ b/fs/reiserfs/resize.c | |||
@@ -22,6 +22,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) | |||
22 | int err = 0; | 22 | int err = 0; |
23 | struct reiserfs_super_block *sb; | 23 | struct reiserfs_super_block *sb; |
24 | struct reiserfs_bitmap_info *bitmap; | 24 | struct reiserfs_bitmap_info *bitmap; |
25 | struct reiserfs_bitmap_info *info; | ||
25 | struct reiserfs_bitmap_info *old_bitmap = SB_AP_BITMAP(s); | 26 | struct reiserfs_bitmap_info *old_bitmap = SB_AP_BITMAP(s); |
26 | struct buffer_head *bh; | 27 | struct buffer_head *bh; |
27 | struct reiserfs_transaction_handle th; | 28 | struct reiserfs_transaction_handle th; |
@@ -127,16 +128,19 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) | |||
127 | * transaction begins, and the new bitmaps don't matter if the | 128 | * transaction begins, and the new bitmaps don't matter if the |
128 | * transaction fails. */ | 129 | * transaction fails. */ |
129 | for (i = bmap_nr; i < bmap_nr_new; i++) { | 130 | for (i = bmap_nr; i < bmap_nr_new; i++) { |
130 | bitmap[i].bh = sb_getblk(s, i * s->s_blocksize * 8); | 131 | bh = sb_getblk(s, i * s->s_blocksize * 8); |
131 | memset(bitmap[i].bh->b_data, 0, sb_blocksize(sb)); | 132 | get_bh(bh); |
132 | reiserfs_test_and_set_le_bit(0, bitmap[i].bh->b_data); | 133 | memset(bh->b_data, 0, sb_blocksize(sb)); |
133 | 134 | reiserfs_test_and_set_le_bit(0, bh->b_data); | |
134 | set_buffer_uptodate(bitmap[i].bh); | 135 | |
135 | mark_buffer_dirty(bitmap[i].bh); | 136 | set_buffer_uptodate(bh); |
136 | sync_dirty_buffer(bitmap[i].bh); | 137 | mark_buffer_dirty(bh); |
138 | sync_dirty_buffer(bh); | ||
137 | // update bitmap_info stuff | 139 | // update bitmap_info stuff |
138 | bitmap[i].first_zero_hint = 1; | 140 | bitmap[i].first_zero_hint = 1; |
139 | bitmap[i].free_count = sb_blocksize(sb) * 8 - 1; | 141 | bitmap[i].free_count = sb_blocksize(sb) * 8 - 1; |
142 | bitmap[i].bh = bh; | ||
143 | brelse(bh); | ||
140 | } | 144 | } |
141 | /* free old bitmap blocks array */ | 145 | /* free old bitmap blocks array */ |
142 | SB_AP_BITMAP(s) = bitmap; | 146 | SB_AP_BITMAP(s) = bitmap; |
@@ -150,30 +154,36 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) | |||
150 | if (err) | 154 | if (err) |
151 | return err; | 155 | return err; |
152 | 156 | ||
153 | /* correct last bitmap blocks in old and new disk layout */ | 157 | /* Extend old last bitmap block - new blocks have been made available */ |
154 | reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr - 1].bh, 1); | 158 | info = SB_AP_BITMAP(s) + bmap_nr - 1; |
159 | bh = info->bh; | ||
160 | get_bh(bh); | ||
161 | |||
162 | reiserfs_prepare_for_journal(s, bh, 1); | ||
155 | for (i = block_r; i < s->s_blocksize * 8; i++) | 163 | for (i = block_r; i < s->s_blocksize * 8; i++) |
156 | reiserfs_test_and_clear_le_bit(i, | 164 | reiserfs_test_and_clear_le_bit(i, bh->b_data); |
157 | SB_AP_BITMAP(s)[bmap_nr - | 165 | info->free_count += s->s_blocksize * 8 - block_r; |
158 | 1].bh->b_data); | 166 | if (!info->first_zero_hint) |
159 | SB_AP_BITMAP(s)[bmap_nr - 1].free_count += s->s_blocksize * 8 - block_r; | 167 | info->first_zero_hint = block_r; |
160 | if (!SB_AP_BITMAP(s)[bmap_nr - 1].first_zero_hint) | 168 | |
161 | SB_AP_BITMAP(s)[bmap_nr - 1].first_zero_hint = block_r; | 169 | journal_mark_dirty(&th, s, bh); |
170 | brelse(bh); | ||
162 | 171 | ||
163 | journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr - 1].bh); | 172 | /* Correct new last bitmap block - It may not be full */ |
173 | info = SB_AP_BITMAP(s) + bmap_nr_new - 1; | ||
174 | bh = info->bh; | ||
175 | get_bh(bh); | ||
164 | 176 | ||
165 | reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr_new - 1].bh, 1); | 177 | reiserfs_prepare_for_journal(s, bh, 1); |
166 | for (i = block_r_new; i < s->s_blocksize * 8; i++) | 178 | for (i = block_r_new; i < s->s_blocksize * 8; i++) |
167 | reiserfs_test_and_set_le_bit(i, | 179 | reiserfs_test_and_set_le_bit(i, bh->b_data); |
168 | SB_AP_BITMAP(s)[bmap_nr_new - | 180 | journal_mark_dirty(&th, s, bh); |
169 | 1].bh->b_data); | 181 | brelse(bh); |
170 | journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr_new - 1].bh); | ||
171 | 182 | ||
172 | SB_AP_BITMAP(s)[bmap_nr_new - 1].free_count -= | 183 | info->free_count -= s->s_blocksize * 8 - block_r_new; |
173 | s->s_blocksize * 8 - block_r_new; | ||
174 | /* Extreme case where last bitmap is the only valid block in itself. */ | 184 | /* Extreme case where last bitmap is the only valid block in itself. */ |
175 | if (!SB_AP_BITMAP(s)[bmap_nr_new - 1].free_count) | 185 | if (!info->free_count) |
176 | SB_AP_BITMAP(s)[bmap_nr_new - 1].first_zero_hint = 0; | 186 | info->first_zero_hint = 0; |
177 | /* update super */ | 187 | /* update super */ |
178 | reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); | 188 | reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); |
179 | free_blocks = SB_FREE_BLOCKS(s); | 189 | free_blocks = SB_FREE_BLOCKS(s); |