diff options
-rw-r--r-- | fs/reiserfs/bitmap.c | 60 | ||||
-rw-r--r-- | fs/reiserfs/resize.c | 60 |
2 files changed, 71 insertions, 49 deletions
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index 1022347a211f..44d9410e9d6a 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c | |||
@@ -59,6 +59,7 @@ static inline void get_bit_address(struct super_block *s, | |||
59 | int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) | 59 | int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) |
60 | { | 60 | { |
61 | int bmap, offset; | 61 | int bmap, offset; |
62 | struct buffer_head *bh; | ||
62 | 63 | ||
63 | if (block == 0 || block >= SB_BLOCK_COUNT(s)) { | 64 | if (block == 0 || block >= SB_BLOCK_COUNT(s)) { |
64 | reiserfs_warning(s, | 65 | reiserfs_warning(s, |
@@ -96,20 +97,21 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) | |||
96 | return 0; | 97 | return 0; |
97 | } | 98 | } |
98 | 99 | ||
99 | if ((bit_value == 0 && | 100 | bh = SB_AP_BITMAP(s)[bmap].bh; |
100 | reiserfs_test_le_bit(offset, SB_AP_BITMAP(s)[bmap].bh->b_data)) || | 101 | get_bh(bh); |
101 | (bit_value == 1 && | 102 | |
102 | reiserfs_test_le_bit(offset, SB_AP_BITMAP(s)[bmap].bh->b_data) == 0)) { | 103 | if ((bit_value == 0 && reiserfs_test_le_bit(offset, bh->b_data)) || |
104 | (bit_value == 1 && reiserfs_test_le_bit(offset, bh->b_data) == 0)) { | ||
103 | reiserfs_warning(s, | 105 | reiserfs_warning(s, |
104 | "vs-4040: is_reusable: corresponding bit of block %lu does not " | 106 | "vs-4040: is_reusable: corresponding bit of block %lu does not " |
105 | "match required value (bmap==%d, offset==%d) test_bit==%d", | 107 | "match required value (bmap==%d, offset==%d) test_bit==%d", |
106 | block, bmap, offset, reiserfs_test_le_bit(offset, | 108 | block, bmap, offset, |
107 | SB_AP_BITMAP | 109 | reiserfs_test_le_bit(offset, bh->b_data)); |
108 | (s)[bmap].bh-> | ||
109 | b_data)); | ||
110 | 110 | ||
111 | brelse(bh); | ||
111 | return 0; | 112 | return 0; |
112 | } | 113 | } |
114 | brelse(bh); | ||
113 | 115 | ||
114 | if (bit_value == 0 && block == SB_ROOT_BLOCK(s)) { | 116 | if (bit_value == 0 && block == SB_ROOT_BLOCK(s)) { |
115 | reiserfs_warning(s, | 117 | reiserfs_warning(s, |
@@ -151,6 +153,7 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, | |||
151 | { | 153 | { |
152 | struct super_block *s = th->t_super; | 154 | struct super_block *s = th->t_super; |
153 | struct reiserfs_bitmap_info *bi = &SB_AP_BITMAP(s)[bmap_n]; | 155 | struct reiserfs_bitmap_info *bi = &SB_AP_BITMAP(s)[bmap_n]; |
156 | struct buffer_head *bh; | ||
154 | int end, next; | 157 | int end, next; |
155 | int org = *beg; | 158 | int org = *beg; |
156 | 159 | ||
@@ -169,22 +172,28 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, | |||
169 | bmap_n); | 172 | bmap_n); |
170 | return 0; | 173 | return 0; |
171 | } | 174 | } |
172 | if (buffer_locked(bi->bh)) { | 175 | bh = bi->bh; |
176 | get_bh(bh); | ||
177 | |||
178 | if (buffer_locked(bh)) { | ||
173 | PROC_INFO_INC(s, scan_bitmap.wait); | 179 | PROC_INFO_INC(s, scan_bitmap.wait); |
174 | __wait_on_buffer(bi->bh); | 180 | __wait_on_buffer(bh); |
175 | } | 181 | } |
176 | 182 | ||
177 | while (1) { | 183 | while (1) { |
178 | cont: | 184 | cont: |
179 | if (bi->free_count < min) | 185 | if (bi->free_count < min) { |
186 | brelse(bh); | ||
180 | return 0; // No free blocks in this bitmap | 187 | return 0; // No free blocks in this bitmap |
188 | } | ||
181 | 189 | ||
182 | /* search for a first zero bit -- beggining of a window */ | 190 | /* search for a first zero bit -- beggining of a window */ |
183 | *beg = reiserfs_find_next_zero_le_bit | 191 | *beg = reiserfs_find_next_zero_le_bit |
184 | ((unsigned long *)(bi->bh->b_data), boundary, *beg); | 192 | ((unsigned long *)(bh->b_data), boundary, *beg); |
185 | 193 | ||
186 | if (*beg + min > boundary) { /* search for a zero bit fails or the rest of bitmap block | 194 | if (*beg + min > boundary) { /* search for a zero bit fails or the rest of bitmap block |
187 | * cannot contain a zero window of minimum size */ | 195 | * cannot contain a zero window of minimum size */ |
196 | brelse(bh); | ||
188 | return 0; | 197 | return 0; |
189 | } | 198 | } |
190 | 199 | ||
@@ -193,7 +202,7 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, | |||
193 | /* first zero bit found; we check next bits */ | 202 | /* first zero bit found; we check next bits */ |
194 | for (end = *beg + 1;; end++) { | 203 | for (end = *beg + 1;; end++) { |
195 | if (end >= *beg + max || end >= boundary | 204 | if (end >= *beg + max || end >= boundary |
196 | || reiserfs_test_le_bit(end, bi->bh->b_data)) { | 205 | || reiserfs_test_le_bit(end, bh->b_data)) { |
197 | next = end; | 206 | next = end; |
198 | break; | 207 | break; |
199 | } | 208 | } |
@@ -207,12 +216,12 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, | |||
207 | * (end) points to one bit after the window end */ | 216 | * (end) points to one bit after the window end */ |
208 | if (end - *beg >= min) { /* it seems we have found window of proper size */ | 217 | if (end - *beg >= min) { /* it seems we have found window of proper size */ |
209 | int i; | 218 | int i; |
210 | reiserfs_prepare_for_journal(s, bi->bh, 1); | 219 | reiserfs_prepare_for_journal(s, bh, 1); |
211 | /* try to set all blocks used checking are they still free */ | 220 | /* try to set all blocks used checking are they still free */ |
212 | for (i = *beg; i < end; i++) { | 221 | for (i = *beg; i < end; i++) { |
213 | /* It seems that we should not check in journal again. */ | 222 | /* It seems that we should not check in journal again. */ |
214 | if (reiserfs_test_and_set_le_bit | 223 | if (reiserfs_test_and_set_le_bit |
215 | (i, bi->bh->b_data)) { | 224 | (i, bh->b_data)) { |
216 | /* bit was set by another process | 225 | /* bit was set by another process |
217 | * while we slept in prepare_for_journal() */ | 226 | * while we slept in prepare_for_journal() */ |
218 | PROC_INFO_INC(s, scan_bitmap.stolen); | 227 | PROC_INFO_INC(s, scan_bitmap.stolen); |
@@ -224,17 +233,16 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, | |||
224 | /* otherwise we clear all bit were set ... */ | 233 | /* otherwise we clear all bit were set ... */ |
225 | while (--i >= *beg) | 234 | while (--i >= *beg) |
226 | reiserfs_test_and_clear_le_bit | 235 | reiserfs_test_and_clear_le_bit |
227 | (i, bi->bh->b_data); | 236 | (i, bh->b_data); |
228 | reiserfs_restore_prepared_buffer(s, | 237 | reiserfs_restore_prepared_buffer(s, bh); |
229 | bi-> | ||
230 | bh); | ||
231 | *beg = org; | 238 | *beg = org; |
232 | /* ... and search again in current block from beginning */ | 239 | /* ... and search again in current block from beginning */ |
233 | goto cont; | 240 | goto cont; |
234 | } | 241 | } |
235 | } | 242 | } |
236 | bi->free_count -= (end - *beg); | 243 | bi->free_count -= (end - *beg); |
237 | journal_mark_dirty(th, s, bi->bh); | 244 | journal_mark_dirty(th, s, bh); |
245 | brelse(bh); | ||
238 | 246 | ||
239 | /* free block count calculation */ | 247 | /* free block count calculation */ |
240 | reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), | 248 | reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), |
@@ -383,7 +391,7 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th, | |||
383 | { | 391 | { |
384 | struct super_block *s = th->t_super; | 392 | struct super_block *s = th->t_super; |
385 | struct reiserfs_super_block *rs; | 393 | struct reiserfs_super_block *rs; |
386 | struct buffer_head *sbh; | 394 | struct buffer_head *sbh, *bmbh; |
387 | struct reiserfs_bitmap_info *apbi; | 395 | struct reiserfs_bitmap_info *apbi; |
388 | int nr, offset; | 396 | int nr, offset; |
389 | 397 | ||
@@ -404,16 +412,20 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th, | |||
404 | return; | 412 | return; |
405 | } | 413 | } |
406 | 414 | ||
407 | reiserfs_prepare_for_journal(s, apbi[nr].bh, 1); | 415 | bmbh = apbi[nr].bh; |
416 | get_bh(bmbh); | ||
417 | |||
418 | reiserfs_prepare_for_journal(s, bmbh, 1); | ||
408 | 419 | ||
409 | /* clear bit for the given block in bit map */ | 420 | /* clear bit for the given block in bit map */ |
410 | if (!reiserfs_test_and_clear_le_bit(offset, apbi[nr].bh->b_data)) { | 421 | if (!reiserfs_test_and_clear_le_bit(offset, bmbh->b_data)) { |
411 | reiserfs_warning(s, "vs-4080: reiserfs_free_block: " | 422 | reiserfs_warning(s, "vs-4080: reiserfs_free_block: " |
412 | "free_block (%s:%lu)[dev:blocknr]: bit already cleared", | 423 | "free_block (%s:%lu)[dev:blocknr]: bit already cleared", |
413 | reiserfs_bdevname(s), block); | 424 | reiserfs_bdevname(s), block); |
414 | } | 425 | } |
415 | apbi[nr].free_count++; | 426 | apbi[nr].free_count++; |
416 | journal_mark_dirty(th, s, apbi[nr].bh); | 427 | journal_mark_dirty(th, s, bmbh); |
428 | brelse(bmbh); | ||
417 | 429 | ||
418 | reiserfs_prepare_for_journal(s, sbh, 1); | 430 | reiserfs_prepare_for_journal(s, sbh, 1); |
419 | /* update super block */ | 431 | /* update super block */ |
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); |