diff options
-rw-r--r-- | fs/reiserfs/bitmap.c | 97 | ||||
-rw-r--r-- | fs/reiserfs/resize.c | 24 | ||||
-rw-r--r-- | fs/reiserfs/super.c | 39 | ||||
-rw-r--r-- | include/linux/reiserfs_fs_sb.h | 1 |
4 files changed, 70 insertions, 91 deletions
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index abdd6d9c4558..cca1dbf5458f 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c | |||
@@ -60,7 +60,6 @@ static inline void get_bit_address(struct super_block *s, | |||
60 | int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) | 60 | int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) |
61 | { | 61 | { |
62 | int bmap, offset; | 62 | int bmap, offset; |
63 | struct buffer_head *bh; | ||
64 | 63 | ||
65 | if (block == 0 || block >= SB_BLOCK_COUNT(s)) { | 64 | if (block == 0 || block >= SB_BLOCK_COUNT(s)) { |
66 | reiserfs_warning(s, | 65 | reiserfs_warning(s, |
@@ -98,22 +97,6 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) | |||
98 | return 0; | 97 | return 0; |
99 | } | 98 | } |
100 | 99 | ||
101 | bh = SB_AP_BITMAP(s)[bmap].bh; | ||
102 | get_bh(bh); | ||
103 | |||
104 | if ((bit_value == 0 && reiserfs_test_le_bit(offset, bh->b_data)) || | ||
105 | (bit_value == 1 && reiserfs_test_le_bit(offset, bh->b_data) == 0)) { | ||
106 | reiserfs_warning(s, | ||
107 | "vs-4040: is_reusable: corresponding bit of block %lu does not " | ||
108 | "match required value (bmap==%d, offset==%d) test_bit==%d", | ||
109 | block, bmap, offset, | ||
110 | reiserfs_test_le_bit(offset, bh->b_data)); | ||
111 | |||
112 | brelse(bh); | ||
113 | return 0; | ||
114 | } | ||
115 | brelse(bh); | ||
116 | |||
117 | if (bit_value == 0 && block == SB_ROOT_BLOCK(s)) { | 100 | if (bit_value == 0 && block == SB_ROOT_BLOCK(s)) { |
118 | reiserfs_warning(s, | 101 | reiserfs_warning(s, |
119 | "vs-4050: is_reusable: this is root block (%u), " | 102 | "vs-4050: is_reusable: this is root block (%u), " |
@@ -173,13 +156,10 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, | |||
173 | bmap_n); | 156 | bmap_n); |
174 | return 0; | 157 | return 0; |
175 | } | 158 | } |
176 | bh = bi->bh; | ||
177 | get_bh(bh); | ||
178 | 159 | ||
179 | if (buffer_locked(bh)) { | 160 | bh = reiserfs_read_bitmap_block(s, bmap_n); |
180 | PROC_INFO_INC(s, scan_bitmap.wait); | 161 | if (bh == NULL) |
181 | __wait_on_buffer(bh); | 162 | return 0; |
182 | } | ||
183 | 163 | ||
184 | while (1) { | 164 | while (1) { |
185 | cont: | 165 | cont: |
@@ -285,9 +265,20 @@ static int bmap_hash_id(struct super_block *s, u32 id) | |||
285 | */ | 265 | */ |
286 | static inline int block_group_used(struct super_block *s, u32 id) | 266 | static inline int block_group_used(struct super_block *s, u32 id) |
287 | { | 267 | { |
288 | int bm; | 268 | int bm = bmap_hash_id(s, id); |
289 | bm = bmap_hash_id(s, id); | 269 | struct reiserfs_bitmap_info *info = &SB_AP_BITMAP(s)[bm]; |
290 | if (SB_AP_BITMAP(s)[bm].free_count > ((s->s_blocksize << 3) * 60 / 100)) { | 270 | |
271 | /* If we don't have cached information on this bitmap block, we're | ||
272 | * going to have to load it later anyway. Loading it here allows us | ||
273 | * to make a better decision. This favors long-term performace gain | ||
274 | * with a better on-disk layout vs. a short term gain of skipping the | ||
275 | * read and potentially having a bad placement. */ | ||
276 | if (info->first_zero_hint == 0) { | ||
277 | struct buffer_head *bh = reiserfs_read_bitmap_block(s, bm); | ||
278 | brelse(bh); | ||
279 | } | ||
280 | |||
281 | if (info->free_count > ((s->s_blocksize << 3) * 60 / 100)) { | ||
291 | return 0; | 282 | return 0; |
292 | } | 283 | } |
293 | return 1; | 284 | return 1; |
@@ -413,8 +404,9 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th, | |||
413 | return; | 404 | return; |
414 | } | 405 | } |
415 | 406 | ||
416 | bmbh = apbi[nr].bh; | 407 | bmbh = reiserfs_read_bitmap_block(s, nr); |
417 | get_bh(bmbh); | 408 | if (!bmbh) |
409 | return; | ||
418 | 410 | ||
419 | reiserfs_prepare_for_journal(s, bmbh, 1); | 411 | reiserfs_prepare_for_journal(s, bmbh, 1); |
420 | 412 | ||
@@ -1320,6 +1312,7 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, | |||
1320 | unsigned int bitmap) | 1312 | unsigned int bitmap) |
1321 | { | 1313 | { |
1322 | b_blocknr_t block = (sb->s_blocksize << 3) * bitmap; | 1314 | b_blocknr_t block = (sb->s_blocksize << 3) * bitmap; |
1315 | struct reiserfs_bitmap_info *info = SB_AP_BITMAP(sb) + bitmap; | ||
1323 | struct buffer_head *bh; | 1316 | struct buffer_head *bh; |
1324 | 1317 | ||
1325 | /* Way old format filesystems had the bitmaps packed up front. | 1318 | /* Way old format filesystems had the bitmaps packed up front. |
@@ -1330,9 +1323,21 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, | |||
1330 | else if (bitmap == 0) | 1323 | else if (bitmap == 0) |
1331 | block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1; | 1324 | block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1; |
1332 | 1325 | ||
1333 | bh = sb_getblk(sb, block); | 1326 | bh = sb_bread(sb, block); |
1334 | if (!buffer_uptodate(bh)) | 1327 | if (bh == NULL) |
1335 | ll_rw_block(READ, 1, &bh); | 1328 | reiserfs_warning(sb, "sh-2029: %s: bitmap block (#%lu) " |
1329 | "reading failed", __FUNCTION__, bh->b_blocknr); | ||
1330 | else { | ||
1331 | if (buffer_locked(bh)) { | ||
1332 | PROC_INFO_INC(sb, scan_bitmap.wait); | ||
1333 | __wait_on_buffer(bh); | ||
1334 | } | ||
1335 | BUG_ON(!buffer_uptodate(bh)); | ||
1336 | BUG_ON(atomic_read(&bh->b_count) == 0); | ||
1337 | |||
1338 | if (info->first_zero_hint == 0) | ||
1339 | reiserfs_cache_bitmap_metadata(sb, bh, info); | ||
1340 | } | ||
1336 | 1341 | ||
1337 | return bh; | 1342 | return bh; |
1338 | } | 1343 | } |
@@ -1340,7 +1345,6 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, | |||
1340 | int reiserfs_init_bitmap_cache(struct super_block *sb) | 1345 | int reiserfs_init_bitmap_cache(struct super_block *sb) |
1341 | { | 1346 | { |
1342 | struct reiserfs_bitmap_info *bitmap; | 1347 | struct reiserfs_bitmap_info *bitmap; |
1343 | int i; | ||
1344 | 1348 | ||
1345 | bitmap = vmalloc(sizeof (*bitmap) * SB_BMAP_NR(sb)); | 1349 | bitmap = vmalloc(sizeof (*bitmap) * SB_BMAP_NR(sb)); |
1346 | if (bitmap == NULL) | 1350 | if (bitmap == NULL) |
@@ -1348,28 +1352,15 @@ int reiserfs_init_bitmap_cache(struct super_block *sb) | |||
1348 | 1352 | ||
1349 | memset(bitmap, 0, sizeof (*bitmap) * SB_BMAP_NR(sb)); | 1353 | memset(bitmap, 0, sizeof (*bitmap) * SB_BMAP_NR(sb)); |
1350 | 1354 | ||
1351 | for (i = 0; i < SB_BMAP_NR(sb); i++) | ||
1352 | bitmap[i].bh = reiserfs_read_bitmap_block(sb, i); | ||
1353 | |||
1354 | /* make sure we have them all */ | ||
1355 | for (i = 0; i < SB_BMAP_NR(sb); i++) { | ||
1356 | wait_on_buffer(bitmap[i].bh); | ||
1357 | if (!buffer_uptodate(bitmap[i].bh)) { | ||
1358 | reiserfs_warning(sb, "sh-2029: %s: " | ||
1359 | "bitmap block (#%lu) reading failed", | ||
1360 | __FUNCTION__, bitmap[i].bh->b_blocknr); | ||
1361 | for (i = 0; i < SB_BMAP_NR(sb); i++) | ||
1362 | brelse(bitmap[i].bh); | ||
1363 | vfree(bitmap); | ||
1364 | return -EIO; | ||
1365 | } | ||
1366 | } | ||
1367 | |||
1368 | /* Cache the info on the bitmaps before we get rolling */ | ||
1369 | for (i = 0; i < SB_BMAP_NR(sb); i++) | ||
1370 | reiserfs_cache_bitmap_metadata(sb, bitmap[i].bh, &bitmap[i]); | ||
1371 | |||
1372 | SB_AP_BITMAP(sb) = bitmap; | 1355 | SB_AP_BITMAP(sb) = bitmap; |
1373 | 1356 | ||
1374 | return 0; | 1357 | return 0; |
1375 | } | 1358 | } |
1359 | |||
1360 | void reiserfs_free_bitmap_cache(struct super_block *sb) | ||
1361 | { | ||
1362 | if (SB_AP_BITMAP(sb)) { | ||
1363 | vfree(SB_AP_BITMAP(sb)); | ||
1364 | SB_AP_BITMAP(sb) = NULL; | ||
1365 | } | ||
1366 | } | ||
diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c index 90d39fd3096f..315684793d1d 100644 --- a/fs/reiserfs/resize.c +++ b/fs/reiserfs/resize.c | |||
@@ -128,8 +128,9 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) | |||
128 | * transaction begins, and the new bitmaps don't matter if the | 128 | * transaction begins, and the new bitmaps don't matter if the |
129 | * transaction fails. */ | 129 | * transaction fails. */ |
130 | for (i = bmap_nr; i < bmap_nr_new; i++) { | 130 | for (i = bmap_nr; i < bmap_nr_new; i++) { |
131 | bh = sb_getblk(s, i * s->s_blocksize * 8); | 131 | /* don't use read_bitmap_block since it will cache |
132 | get_bh(bh); | 132 | * the uninitialized bitmap */ |
133 | bh = sb_bread(s, i * s->s_blocksize * 8); | ||
133 | memset(bh->b_data, 0, sb_blocksize(sb)); | 134 | memset(bh->b_data, 0, sb_blocksize(sb)); |
134 | reiserfs_test_and_set_le_bit(0, bh->b_data); | 135 | reiserfs_test_and_set_le_bit(0, bh->b_data); |
135 | reiserfs_cache_bitmap_metadata(s, bh, bitmap + i); | 136 | reiserfs_cache_bitmap_metadata(s, bh, bitmap + i); |
@@ -140,7 +141,6 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) | |||
140 | // update bitmap_info stuff | 141 | // update bitmap_info stuff |
141 | bitmap[i].first_zero_hint = 1; | 142 | bitmap[i].first_zero_hint = 1; |
142 | bitmap[i].free_count = sb_blocksize(sb) * 8 - 1; | 143 | bitmap[i].free_count = sb_blocksize(sb) * 8 - 1; |
143 | bitmap[i].bh = bh; | ||
144 | brelse(bh); | 144 | brelse(bh); |
145 | } | 145 | } |
146 | /* free old bitmap blocks array */ | 146 | /* free old bitmap blocks array */ |
@@ -157,8 +157,13 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) | |||
157 | 157 | ||
158 | /* Extend old last bitmap block - new blocks have been made available */ | 158 | /* Extend old last bitmap block - new blocks have been made available */ |
159 | info = SB_AP_BITMAP(s) + bmap_nr - 1; | 159 | info = SB_AP_BITMAP(s) + bmap_nr - 1; |
160 | bh = info->bh; | 160 | bh = reiserfs_read_bitmap_block(s, bmap_nr - 1); |
161 | get_bh(bh); | 161 | if (!bh) { |
162 | int jerr = journal_end(&th, s, 10); | ||
163 | if (jerr) | ||
164 | return jerr; | ||
165 | return -EIO; | ||
166 | } | ||
162 | 167 | ||
163 | reiserfs_prepare_for_journal(s, bh, 1); | 168 | reiserfs_prepare_for_journal(s, bh, 1); |
164 | for (i = block_r; i < s->s_blocksize * 8; i++) | 169 | for (i = block_r; i < s->s_blocksize * 8; i++) |
@@ -172,8 +177,13 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) | |||
172 | 177 | ||
173 | /* Correct new last bitmap block - It may not be full */ | 178 | /* Correct new last bitmap block - It may not be full */ |
174 | info = SB_AP_BITMAP(s) + bmap_nr_new - 1; | 179 | info = SB_AP_BITMAP(s) + bmap_nr_new - 1; |
175 | bh = info->bh; | 180 | bh = reiserfs_read_bitmap_block(s, bmap_nr_new - 1); |
176 | get_bh(bh); | 181 | if (!bh) { |
182 | int jerr = journal_end(&th, s, 10); | ||
183 | if (jerr) | ||
184 | return jerr; | ||
185 | return -EIO; | ||
186 | } | ||
177 | 187 | ||
178 | reiserfs_prepare_for_journal(s, bh, 1); | 188 | reiserfs_prepare_for_journal(s, bh, 1); |
179 | for (i = block_r_new; i < s->s_blocksize * 8; i++) | 189 | for (i = block_r_new; i < s->s_blocksize * 8; i++) |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index c78e99e196fa..c89aa2338191 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -432,7 +432,6 @@ int remove_save_link(struct inode *inode, int truncate) | |||
432 | 432 | ||
433 | static void reiserfs_put_super(struct super_block *s) | 433 | static void reiserfs_put_super(struct super_block *s) |
434 | { | 434 | { |
435 | int i; | ||
436 | struct reiserfs_transaction_handle th; | 435 | struct reiserfs_transaction_handle th; |
437 | th.t_trans_id = 0; | 436 | th.t_trans_id = 0; |
438 | 437 | ||
@@ -462,10 +461,7 @@ static void reiserfs_put_super(struct super_block *s) | |||
462 | */ | 461 | */ |
463 | journal_release(&th, s); | 462 | journal_release(&th, s); |
464 | 463 | ||
465 | for (i = 0; i < SB_BMAP_NR(s); i++) | 464 | reiserfs_free_bitmap_cache(s); |
466 | brelse(SB_AP_BITMAP(s)[i].bh); | ||
467 | |||
468 | vfree(SB_AP_BITMAP(s)); | ||
469 | 465 | ||
470 | brelse(SB_BUFFER_WITH_SB(s)); | 466 | brelse(SB_BUFFER_WITH_SB(s)); |
471 | 467 | ||
@@ -1344,7 +1340,6 @@ static int read_super_block(struct super_block *s, int offset) | |||
1344 | /* after journal replay, reread all bitmap and super blocks */ | 1340 | /* after journal replay, reread all bitmap and super blocks */ |
1345 | static int reread_meta_blocks(struct super_block *s) | 1341 | static int reread_meta_blocks(struct super_block *s) |
1346 | { | 1342 | { |
1347 | int i; | ||
1348 | ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s))); | 1343 | ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s))); |
1349 | wait_on_buffer(SB_BUFFER_WITH_SB(s)); | 1344 | wait_on_buffer(SB_BUFFER_WITH_SB(s)); |
1350 | if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) { | 1345 | if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) { |
@@ -1353,20 +1348,7 @@ static int reread_meta_blocks(struct super_block *s) | |||
1353 | return 1; | 1348 | return 1; |
1354 | } | 1349 | } |
1355 | 1350 | ||
1356 | for (i = 0; i < SB_BMAP_NR(s); i++) { | ||
1357 | ll_rw_block(READ, 1, &(SB_AP_BITMAP(s)[i].bh)); | ||
1358 | wait_on_buffer(SB_AP_BITMAP(s)[i].bh); | ||
1359 | if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) { | ||
1360 | reiserfs_warning(s, | ||
1361 | "reread_meta_blocks, error reading bitmap block number %d at %llu", | ||
1362 | i, | ||
1363 | (unsigned long long)SB_AP_BITMAP(s)[i]. | ||
1364 | bh->b_blocknr); | ||
1365 | return 1; | ||
1366 | } | ||
1367 | } | ||
1368 | return 0; | 1351 | return 0; |
1369 | |||
1370 | } | 1352 | } |
1371 | 1353 | ||
1372 | ///////////////////////////////////////////////////// | 1354 | ///////////////////////////////////////////////////// |
@@ -1547,7 +1529,6 @@ static int function2code(hashf_t func) | |||
1547 | static int reiserfs_fill_super(struct super_block *s, void *data, int silent) | 1529 | static int reiserfs_fill_super(struct super_block *s, void *data, int silent) |
1548 | { | 1530 | { |
1549 | struct inode *root_inode; | 1531 | struct inode *root_inode; |
1550 | int j; | ||
1551 | struct reiserfs_transaction_handle th; | 1532 | struct reiserfs_transaction_handle th; |
1552 | int old_format = 0; | 1533 | int old_format = 0; |
1553 | unsigned long blocks; | 1534 | unsigned long blocks; |
@@ -1793,19 +1774,17 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) | |||
1793 | if (jinit_done) { /* kill the commit thread, free journal ram */ | 1774 | if (jinit_done) { /* kill the commit thread, free journal ram */ |
1794 | journal_release_error(NULL, s); | 1775 | journal_release_error(NULL, s); |
1795 | } | 1776 | } |
1796 | if (SB_DISK_SUPER_BLOCK(s)) { | 1777 | |
1797 | for (j = 0; j < SB_BMAP_NR(s); j++) { | 1778 | reiserfs_free_bitmap_cache(s); |
1798 | if (SB_AP_BITMAP(s)) | ||
1799 | brelse(SB_AP_BITMAP(s)[j].bh); | ||
1800 | } | ||
1801 | vfree(SB_AP_BITMAP(s)); | ||
1802 | } | ||
1803 | if (SB_BUFFER_WITH_SB(s)) | 1779 | if (SB_BUFFER_WITH_SB(s)) |
1804 | brelse(SB_BUFFER_WITH_SB(s)); | 1780 | brelse(SB_BUFFER_WITH_SB(s)); |
1805 | #ifdef CONFIG_QUOTA | 1781 | #ifdef CONFIG_QUOTA |
1806 | for (j = 0; j < MAXQUOTAS; j++) { | 1782 | { |
1807 | kfree(sbi->s_qf_names[j]); | 1783 | int j; |
1808 | sbi->s_qf_names[j] = NULL; | 1784 | for (j = 0; j < MAXQUOTAS; j++) { |
1785 | kfree(sbi->s_qf_names[j]); | ||
1786 | sbi->s_qf_names[j] = NULL; | ||
1787 | } | ||
1809 | } | 1788 | } |
1810 | #endif | 1789 | #endif |
1811 | kfree(sbi); | 1790 | kfree(sbi); |
diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h index 4f21ad388c79..73e0becec086 100644 --- a/include/linux/reiserfs_fs_sb.h +++ b/include/linux/reiserfs_fs_sb.h | |||
@@ -267,7 +267,6 @@ struct reiserfs_bitmap_info { | |||
267 | // FIXME: Won't work with block sizes > 8K | 267 | // FIXME: Won't work with block sizes > 8K |
268 | __u16 first_zero_hint; | 268 | __u16 first_zero_hint; |
269 | __u16 free_count; | 269 | __u16 free_count; |
270 | struct buffer_head *bh; /* the actual bitmap */ | ||
271 | }; | 270 | }; |
272 | 271 | ||
273 | struct proc_dir_entry; | 272 | struct proc_dir_entry; |