aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Mahoney <jeffm@suse.com>2006-10-01 02:28:44 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-01 03:39:28 -0400
commit5065227b46235ec0131b383cc2f537069b55c6b6 (patch)
tree12187734ef619626c901b9d2b43ad72286d4d258
parent6f01046b35d940079822827498a7dd6d3eec8c6b (diff)
[PATCH] reiserfs: on-demand bitmap loading
This is the patch the three previous ones have been leading up to. It changes the behavior of ReiserFS from loading and caching all the bitmaps as special, to treating the bitmaps like any other bit of metadata and just letting the system-wide caches figure out what to hang on to. Buffer heads are allocated on the fly, so there is no need to retain pointers to all of them. The caching of the metadata occurs when the data is read and updated, and is considered invalid and uncached until then. I needed to remove the vs-4040 check for performing a duplicate operation on a particular bit. The reason is that while the other sites for working with bitmaps are allowed to schedule, is_reusable() is called from do_balance(), which will panic if a schedule occurs in certain places. The benefit of on-demand bitmaps clearly outweighs a sanity check that depends on a compile-time option that is discouraged. [akpm@osdl.org: warning fix] Signed-off-by: Jeff Mahoney <jeffm@suse.com> Cc: <reiserfs-dev@namesys.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--fs/reiserfs/bitmap.c97
-rw-r--r--fs/reiserfs/resize.c24
-rw-r--r--fs/reiserfs/super.c39
-rw-r--r--include/linux/reiserfs_fs_sb.h1
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,
60int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) 60int 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 */
286static inline int block_group_used(struct super_block *s, u32 id) 266static 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,
1340int reiserfs_init_bitmap_cache(struct super_block *sb) 1345int 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
1360void 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
433static void reiserfs_put_super(struct super_block *s) 433static 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 */
1345static int reread_meta_blocks(struct super_block *s) 1341static 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)
1547static int reiserfs_fill_super(struct super_block *s, void *data, int silent) 1529static 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
273struct proc_dir_entry; 272struct proc_dir_entry;