-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

 Currently, ReiserFS will read and keep in memory all the bitmaps for
 the filesystem on mount. After the journal is replayed, it will read
 them in again. On huge filesystems, this can be a resource hog and a
 performance/ availability problem.

 For example, on a maximum size (~16 TB) ReiserFS filesystem, there are
 2^32 blocks, which require 131072 bitmaps to describe them. This means
 that without loading any of the metadata tree or accessing file data,
 just over 512M of RAM must be allocated (and is unswappable) for the
 filesystem to be mounted and completely idle. All of that data is
 distributed evenly over the entire disk, and must be read (twice!)
 on mount.

 There have been reports of large filesystems taking an unacceptably
 long time to mount. These mount times can take your 5 9's down pretty
 quickly.

 The following patch implements on-demand loading for bitmaps. Rather
 than pin all the bitmaps in memory as we do now, when a bitmap is
 needed it is read from disk. If it is needed frequently, the buffer
 cache will use existing heuristics to keep it around. The caching of
 bitmap metadata is kept, so that bitmaps that are known to be full are
 skipped completely.

 I have done some very basic testing on this, but I'd like to have some
 more eyes take a look.

 Caveats:

 The error handling in this revision is incomplete. This is a known
 issue as I would like to end up applying this patch after reworking
 the error handling in ReiserFS as a whole. Ultimately, a
 reiserfs_error() similar to ext3 will be introduced, which will allow
 smoother handling of errors than currently available.

 The "old bitmap" code is untested. In principle, the difference boils
 down to only where the bitmap block is located.

- -Jeff

- --
Jeff Mahoney
SuSE Labs
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)

iD8DBQFCzEt/LPWxlyuTD7IRAt4iAJ48L0ldd+jgowf1Qf6f6e90wbgacwCgjo5o
RSQzCzJAnYeLpYQDzkLBGVc=
=5ux1
-----END PGP SIGNATURE-----
From: Jeff Mahoney <[EMAIL PROTECTED]>
Subject: [PATCH] reiserfs: implement on-demand bitmap loading (testing only)

 Currently, ReiserFS will read and keep in memory all the bitmaps for the
 filesystem on mount. After the journal is replayed, it will read them in
 again. On huge filesystems, this can be a resource hog and a performance/
 availability problem.

 For example, on a maximum size (~16 TB) ReiserFS filesystem, there are
 2^32 blocks, which require 131072 bitmaps to describe them. This means that
 without loading any of the metadata tree or accessing file data, just over
 512M of RAM must be allocated (and is unswappable) for the filesystem to
 be mounted and completely idle. All of that data is distributed evenly over
 the entire disk, and must be read (twice!) on mount.

 There have been reports of large filesystems taking an unacceptably long time
 to mount. These mount times can take your 5 9's down pretty quickly.

 The following patch implements on-demand loading for bitmaps. Rather than pin
 all the bitmaps in memory as we do now, when a bitmap is needed it is read
 from disk. If it is needed frequently, the buffer cache will use existing
 heuristics to keep it around. The caching of bitmap metadata is kept, so that
 bitmaps that are known to be full are skipped completely.

 I have done some very basic testing on this, but I'd like to have some more
 eyes take a look.

 Caveats:

 The error handling in this revision is incomplete. This is a known issue
 as I would like to end up applying this patch after reworking the error
 handling in ReiserFS as a whole. Ultimately, a reiserfs_error() similar to
 ext3 will be introduced, which will allow smoother handling of errors than
 currently available.

 The "old bitmap" code is untested. In principle, the difference boils down to
 only where the bitmap block is located.

Signed-off-by: Jeff Mahoney <[EMAIL PROTECTED]>

diff -ruNpX dontdiff linux-2.6.12.1/fs/reiserfs/bitmap.c linux-2.6.12.1.devel/fs/reiserfs/bitmap.c
--- linux-2.6.12.1/fs/reiserfs/bitmap.c	2005-06-30 12:51:42.000000000 -0400
+++ linux-2.6.12.1.devel/fs/reiserfs/bitmap.c	2005-06-30 16:40:29.000000000 -0400
@@ -61,6 +61,8 @@ static inline void get_bit_address (stru
 int is_reusable (struct super_block * s, b_blocknr_t block, int bit_value)
 {
     int i, j;
+    unsigned int bmap = block >> s->s_blocksize_bits;
+    struct buffer_head *bh;
 
     if (block == 0 || block >= SB_BLOCK_COUNT (s)) {
 	reiserfs_warning (s, "vs-4010: is_reusable: block number is out of range %lu (%u)",
@@ -68,14 +70,29 @@ int is_reusable (struct super_block * s,
 	return 0;
     }
 
-    /* it can't be one of the bitmap blocks */
-    for (i = 0; i < SB_BMAP_NR (s); i ++)
-	if (block == SB_AP_BITMAP (s)[i].bh->b_blocknr) {
-	    reiserfs_warning (s, "vs: 4020: is_reusable: "
-			      "bitmap block %lu(%u) can't be freed or reused",
-			      block, SB_BMAP_NR (s));
-	    return 0;
-	}
+    /* Old format filesystem? Unlikely, but the bitmaps are all up front so
+     * we need to account for it. */
+    if (unlikely (test_bit(REISERFS_OLD_FORMAT,
+                           &(REISERFS_SB(sb)->s_properties)))) {
+            block_nr_t bmap1 = REISERFS_SB(sb)->s_bh->b_blocknr + 1;
+            if (block >= REISERFS_SB(sb)->s_bh->b_blocknr + 1 + bmap &&
+                block <= REISERFS_SB(sb)->s_bh->b_blocknr + 1 + SB_BMAP_NR(s)) {
+                    reiserfs_warning (s, "vs: 4019: is_reusable: "
+                                      "bitmap block %lu(%u) can't be freed or "
+                                      "reused", block, SB_BMAP_NR (s));
+                    return 0
+            }
+    } else {
+            if (block & ((s->s_blocksize << 3) - 1 ) == 0)
+                    reiserfs_warning (s, "vs: 4020: is_reusable: "
+                                      "bitmap block %lu(%u) can't be freed or "
+                                      "reused", block, SB_BMAP_NR (s));
+                    return 0;
+                }
+            }
+    }
+
+
   
     get_bit_address (s, block, &i, &j);
 
@@ -85,16 +102,22 @@ int is_reusable (struct super_block * s,
 	return 0;
     }
 
+    bh  = read_bitmap_block (s, bmap);
+    if (!bh)
+        return 0;
+
     if ((bit_value == 0 && 
-         reiserfs_test_le_bit(j, SB_AP_BITMAP(s)[i].bh->b_data)) ||
+         reiserfs_test_le_bit(j, bh->b_data)) ||
 	(bit_value == 1 && 
-	 reiserfs_test_le_bit(j, SB_AP_BITMAP (s)[i].bh->b_data) == 0)) {
+	 reiserfs_test_le_bit(j, bh->b_data) == 0)) {
 	reiserfs_warning (s, "vs-4040: is_reusable: corresponding bit of block %lu does not "
 			  "match required value (i==%d, j==%d) test_bit==%d",
-		block, i, j, reiserfs_test_le_bit (j, SB_AP_BITMAP (s)[i].bh->b_data));
+		block, i, j, reiserfs_test_le_bit (j, bh->b_data));
 
+	brelse (bh);
 	return 0;
     }
+    brelse (bh);
 
     if (bit_value == 0 && block == SB_ROOT_BLOCK (s)) {
 	reiserfs_warning (s, "vs-4050: is_reusable: this is root block (%u), "
@@ -134,6 +157,7 @@ static int scan_bitmap_block (struct rei
 {
     struct super_block *s = th->t_super;
     struct reiserfs_bitmap_info *bi=&SB_AP_BITMAP(s)[bmap_n];
+    struct buffer_head *bh;
     int end, next;
     int org = *beg;
 
@@ -150,22 +174,22 @@ static int scan_bitmap_block (struct rei
 	reiserfs_warning (s, "NULL bitmap info pointer for bitmap %d", bmap_n);
 	return 0;
     }
-    if (buffer_locked (bi->bh)) {
-       PROC_INFO_INC( s, scan_bitmap.wait );
-       __wait_on_buffer (bi->bh);
-    }
+
+    bh = read_bitmap_block (s, bmap_n);
+    if (!bh)
+        return 0;
 
     while (1) {
-	cont:
 	if (bi->free_count < min)
 		return 0; // No free blocks in this bitmap
 
 	/* search for a first zero bit -- beggining of a window */
 	*beg = reiserfs_find_next_zero_le_bit
-	        ((unsigned long*)(bi->bh->b_data), boundary, *beg);
+	        ((unsigned long*)(bh->b_data), boundary, *beg);
   
 	if (*beg + min > boundary) { /* search for a zero bit fails or the rest of bitmap block
 				      * cannot contain a zero window of minimum size */
+	    brelse (bh);
 	    return 0;
 	}
 
@@ -173,7 +197,7 @@ static int scan_bitmap_block (struct rei
 	    continue;
 	/* first zero bit found; we check next bits */
 	for (end = *beg + 1;; end ++) {
-	    if (end >= *beg + max || end >= boundary || reiserfs_test_le_bit (end, bi->bh->b_data)) {
+	    if (end >= *beg + max || end >= boundary || reiserfs_test_le_bit (end, bh->b_data)) {
 		next = end;
 		break;
 	    }
@@ -187,11 +211,11 @@ static int scan_bitmap_block (struct rei
 	 * (end) points to one bit after the window end */
 	if (end - *beg >= min) { /* it seems we have found window of proper size */
 	    int i;
-	    reiserfs_prepare_for_journal (s, bi->bh, 1);
+	    reiserfs_prepare_for_journal (s, bh, 1);
 	    /* try to set all blocks used checking are they still free */
 	    for (i = *beg; i < end; i++) {
 		/* It seems that we should not check in journal again. */
-		if (reiserfs_test_and_set_le_bit (i, bi->bh->b_data)) {
+		if (reiserfs_test_and_set_le_bit (i, bh->b_data)) {
 		    /* bit was set by another process
 		     * while we slept in prepare_for_journal() */
 		    PROC_INFO_INC( s, scan_bitmap.stolen );
@@ -202,21 +226,22 @@ static int scan_bitmap_block (struct rei
 		    }
 		    /* otherwise we clear all bit were set ... */
 		    while (--i >= *beg)
-			reiserfs_test_and_clear_le_bit (i, bi->bh->b_data);
-		    reiserfs_restore_prepared_buffer (s, bi->bh);
+			reiserfs_test_and_clear_le_bit (i, bh->b_data);
+		    reiserfs_restore_prepared_buffer (s, bh);
 		    *beg = org;
 		    /* ... and search again in current block from beginning */
-		    goto cont;	
+		    continue;
 		}
 	    }
 	    bi->free_count -= (end - *beg);
-	    journal_mark_dirty (th, s, bi->bh);
+	    journal_mark_dirty (th, s, bh);
 
 	    /* free block count calculation */
 	    reiserfs_prepare_for_journal (s, SB_BUFFER_WITH_SB(s), 1);
 	    PUT_SB_FREE_BLOCKS(s, SB_FREE_BLOCKS(s) - (end - *beg));
 	    journal_mark_dirty (th, s, SB_BUFFER_WITH_SB(s));
 
+	    brelse (bh);
 	    return end - (*beg);
 	} else {
 	    *beg = next;
@@ -349,7 +374,7 @@ static void _reiserfs_free_block (struct
 {
     struct super_block * s = th->t_super;
     struct reiserfs_super_block * rs;
-    struct buffer_head * sbh;
+    struct buffer_head * sbh, *bmbh;
     struct reiserfs_bitmap_info *apbi;
     int nr, offset;
 
@@ -370,16 +395,23 @@ static void _reiserfs_free_block (struct
 	return;
     }
 
-    reiserfs_prepare_for_journal(s, apbi[nr].bh, 1 ) ;
+    bmbh = read_bitmap_block (s, nr);
+    if (!bmbh) {
+        reiserfs_warning (s, "jdm-4077: reiserfs_free_block: couldn't read bitmap %d\n", nr);
+        return;
+    }
+
+    reiserfs_prepare_for_journal(s, bmbh, 1 ) ;
 
     /* clear bit for the given block in bit map */
-    if (!reiserfs_test_and_clear_le_bit (offset, apbi[nr].bh->b_data)) {
+    if (!reiserfs_test_and_clear_le_bit (offset, bmbh->b_data)) {
 	reiserfs_warning (s, "vs-4080: reiserfs_free_block: "
 			  "free_block (%s:%lu)[dev:blocknr]: bit already cleared",
 			  reiserfs_bdevname (s), block);
     }
     apbi[nr].free_count ++;
-    journal_mark_dirty (th, s, apbi[nr].bh);
+    journal_mark_dirty (th, s, bmbh);
+    brelse (bmbh);
 
     reiserfs_prepare_for_journal(s, sbh, 1) ;
     /* update super block */
@@ -1168,3 +1200,82 @@ int reiserfs_can_fit_pages ( struct supe
 
 	return space>0?space:0;
 }
+
+/* cache_bitmap_metadata - Caches bitmap metadata so that the bitmap itself
+ *                         need not be reloaded only to find that it is full.
+ * @bh: buffer_head containing the bitmap data
+ * @info: info struct to cache the data
+ *
+ * This will cache the number of free blocks and which block is the first
+ * available. 
+ *
+ * The values are considered uncached if ->first_zero_hint is 0, since
+ * the bitmap block itself always occupies block 0 of the bitmap.
+ *
+ */
+static void
+cache_bitmap_metadata (struct super_block *sb, struct buffer_head *bh,
+                       struct reiserfs_bitmap_info *info)
+{
+	unsigned long *cur = (unsigned long *)bh->b_data;
+	int i;
+
+	for (i = sb->s_blocksize / sizeof (*cur); i > 0; i--, cur++) {
+		/* 0 and ~0 are special, we can optimize for them */
+		if (*cur == 0) {
+			info->first_zero_hint = i << 3;
+			info->free_count += sizeof (*cur) << 3;
+		} else if (*cur != ~0L) { /* A mix, investigate */
+			int b;
+			for (b = sizeof (*cur) << 3; b >= 0; b--) {
+				if (!reiserfs_test_le_bit (b, cur)) {
+					info->first_zero_hint = (i << 3) + b;
+					info->free_count++;
+				}
+			}
+		}
+	}
+
+	/* The first bit must ALWAYS be 1 */
+	BUG_ON (info->first_zero_hint == 0);
+}
+
+/* read_bitmap_block - reads a bitmap block from disk dynamically
+ * @sb: super_block associated with filesystem
+ * @bitmap: bitmap number to load
+ *
+ * On huge filesystems, the initial load time for bitmaps is unacceptably long.
+ * Mount time as long as 15 minutes have been reported on huge (~ 15 TiB)
+ * filesystems. Pinning the bitmaps in memory on these huge filesystems is
+ * also a non-trivial resource use - 480 MB on that same 15 TiB filesystem.
+ * Loading the bitmaps dynamically on demand alleviates both problems.
+ */
+struct buffer_head *
+read_bitmap_block (struct super_block *sb, unsigned int bitmap)
+{
+	unsigned int block = (sb->s_blocksize << 3) * bitmap;
+	struct reiserfs_bitmap_info *info = SB_AP_BITMAP (sb) + bitmap;
+	struct buffer_head *bh;
+
+	/* Way old format filesystems had the bitmaps packed up front.
+	 * I doubt there are any of these left, but just in case... */
+	if (test_bit(REISERFS_OLD_FORMAT, &(REISERFS_SB(sb)->s_properties))) {
+		block = REISERFS_SB (sb)->s_sbh->b_blocknr + 1 + bitmap;
+	}
+
+	bh = sb_bread (sb, block);
+
+	if (bh == NULL) {
+		reiserfs_warning (sb, "jdm-4900: Cannot read bitmap %u "
+		                      "(block %u)", bitmap, block);
+		return NULL;
+	}
+
+	/* If we've already cached the metadata, ->first_zero_hint must be > 0,
+	 * since the bitmap itself occupies the first block described by the
+	 * bitmap */
+	if (info->first_zero_hint == 0)
+		cache_bitmap_metadata (sb, bh, info);
+
+	return bh;
+}
diff -ruNpX dontdiff linux-2.6.12.1/fs/reiserfs/resize.c linux-2.6.12.1.devel/fs/reiserfs/resize.c
--- linux-2.6.12.1/fs/reiserfs/resize.c	2005-03-02 02:37:55.000000000 -0500
+++ linux-2.6.12.1.devel/fs/reiserfs/resize.c	2005-06-30 16:13:07.000000000 -0400
@@ -21,9 +21,9 @@ int reiserfs_resize (struct super_block 
 {
         int err = 0;
 	struct reiserfs_super_block * sb;
-        struct reiserfs_bitmap_info *bitmap;
+	struct reiserfs_bitmap_info *bitmap, *info;
 	struct reiserfs_bitmap_info *old_bitmap = SB_AP_BITMAP(s);
-	struct buffer_head * bh;
+	struct buffer_head * bh, *bmbh;
 	struct reiserfs_transaction_handle th;
 	unsigned int bmap_nr_new, bmap_nr;
 	unsigned int block_r_new, block_r;
@@ -107,29 +107,31 @@ int reiserfs_resize (struct super_block 
 	
 	    /* allocate additional bitmap blocks, reallocate array of bitmap
 	     * block pointers */
-	    bitmap = vmalloc(sizeof(struct reiserfs_bitmap_info) * bmap_nr_new);
+	    bitmap = vmalloc(sizeof(*bitmap) * bmap_nr_new);
 	    if (!bitmap) {
 		/* Journal bitmaps are still supersized, but the memory isn't
 		 * leaked, so I guess it's ok */
 		printk("reiserfs_resize: unable to allocate memory.\n");
 		return -ENOMEM;
 	    }
-	    memset (bitmap, 0, sizeof (struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
-	    for (i = 0; i < bmap_nr; i++)
-		bitmap[i] = old_bitmap[i];
+
+	    /* Copy what we have, clear out the rest */
+	    memcpy (bitmap, old_bitmap, sizeof (*bitmap) * SB_BMAP_NR(s));
+	    memset (bitmap + SB_BMAP_NR(s), 0,
+	            sizeof (*bitmap) * (bmap_nr - SB_BMAP_NR(s)));
 
 	    /* This doesn't go through the journal, but it doesn't have to.
 	     * The changes are still atomic: We're synced up when the journal
 	     * transaction begins, and the new bitmaps don't matter if the
 	     * transaction fails. */
 	    for (i = bmap_nr; i < bmap_nr_new; i++) {
-		bitmap[i].bh = sb_getblk(s, i * s->s_blocksize * 8);
-		memset(bitmap[i].bh->b_data, 0, sb_blocksize(sb));
-		reiserfs_test_and_set_le_bit(0, bitmap[i].bh->b_data);
-
-		set_buffer_uptodate(bitmap[i].bh);
-		mark_buffer_dirty(bitmap[i].bh) ;
-		sync_dirty_buffer(bitmap[i].bh);
+		bmbh = sb_bread (s, i * s->s_blocksize * 8);
+		memset(bmbh->b_data, 0, sb_blocksize(sb));
+		reiserfs_test_and_set_le_bit(0, bmbh->b_data);
+
+		set_buffer_uptodate(bmbh);
+		mark_buffer_dirty(bmbh) ;
+		sync_dirty_buffer(bmbh);
 		// update bitmap_info stuff
 		bitmap[i].first_zero_hint=1;
 		bitmap[i].free_count = sb_blocksize(sb) * 8 - 1;
@@ -146,27 +148,46 @@ int reiserfs_resize (struct super_block 
 	if (err)
 	    return err;
 
-	/* correct last bitmap blocks in old and new disk layout */
-	reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr - 1].bh, 1);
-	for (i = block_r; i < s->s_blocksize * 8; i++)
-	    reiserfs_test_and_clear_le_bit(i, 
-					   SB_AP_BITMAP(s)[bmap_nr - 1].bh->b_data);
-	SB_AP_BITMAP(s)[bmap_nr - 1].free_count += s->s_blocksize * 8 - block_r;
-	if ( !SB_AP_BITMAP(s)[bmap_nr - 1].first_zero_hint)
-	    SB_AP_BITMAP(s)[bmap_nr - 1].first_zero_hint = block_r;
+	/* Extend old last bitmap block - new blocks have been made available */
+	bmbh = read_bitmap_block (s, bmap_nr - 1);
+	if (!bmbh) {
+	    int jerr = journal_end (&th, s, 10);
+	    if (jerr)
+		return jerr;
+	    return -EIO;
+	}
 
-	journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr - 1].bh);
+	info = SB_AP_BITMAP(s) + bmap_nr - 1;
+	reiserfs_prepare_for_journal(s, bmbh, 1);
+	for (i = block_r; i < s->s_blocksize * 8; i++)
+	    reiserfs_test_and_clear_le_bit(i, bmbh->b_data);
+	info->free_count += s->s_blocksize * 8 - block_r;
+	if ( !info->first_zero_hint)
+	    info->first_zero_hint = block_r;
+
+	journal_mark_dirty(&th, s, bmbh);
+	brelse (bmbh);
+
+	/* Correct new last bitmap block - It may not be full */
+	bmbh = read_bitmap_block (s, bmap_nr_new - 1);
+	info = SB_AP_BITMAP(s) + bmap_nr_new - 1;
+	if (!bmbh) {
+	    int jerr = journal_end (&th, s, 10);
+	    if (jerr)
+		return jerr;
+	    return -EIO;
+	}
 
-	reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr_new - 1].bh, 1);
+	reiserfs_prepare_for_journal(s, bmbh, 1);
 	for (i = block_r_new; i < s->s_blocksize * 8; i++)
-	    reiserfs_test_and_set_le_bit(i,
-					 SB_AP_BITMAP(s)[bmap_nr_new - 1].bh->b_data);
-	journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr_new - 1].bh);
+	    reiserfs_test_and_set_le_bit(i, bmbh->b_data);
+	journal_mark_dirty(&th, s, bmbh);
  
-	SB_AP_BITMAP(s)[bmap_nr_new - 1].free_count -= s->s_blocksize * 8 - block_r_new;
+	info->free_count -= s->s_blocksize * 8 - block_r_new;
 	/* Extreme case where last bitmap is the only valid block in itself. */
-	if ( !SB_AP_BITMAP(s)[bmap_nr_new - 1].free_count )
-	    SB_AP_BITMAP(s)[bmap_nr_new - 1].first_zero_hint = 0;
+	if ( !info->free_count )
+	    info->first_zero_hint = 0;
+
  	/* update super */
 	reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
 	free_blocks = SB_FREE_BLOCKS(s);
diff -ruNpX dontdiff linux-2.6.12.1/fs/reiserfs/super.c linux-2.6.12.1.devel/fs/reiserfs/super.c
--- linux-2.6.12.1/fs/reiserfs/super.c	2005-06-30 12:51:42.000000000 -0400
+++ linux-2.6.12.1.devel/fs/reiserfs/super.c	2005-06-30 16:15:26.000000000 -0400
@@ -417,7 +417,6 @@ int remove_save_link (struct inode * ino
 
 static void reiserfs_put_super (struct super_block * s)
 {
-  int i;
   struct reiserfs_transaction_handle th ;
   th.t_trans_id = 0;
 
@@ -445,9 +444,6 @@ static void reiserfs_put_super (struct s
   */
   journal_release(&th, s) ;
 
-  for (i = 0; i < SB_BMAP_NR (s); i ++)
-    brelse (SB_AP_BITMAP (s)[i].bh);
-
   vfree (SB_AP_BITMAP (s));
 
   brelse (SB_BUFFER_WITH_SB (s));
@@ -1188,6 +1184,20 @@ static int reiserfs_remount (struct supe
   return 0;
 }
 
+static struct reiserfs_bitmap_info *
+init_bitmap_cache (struct super_block *sb)
+{
+	struct reiserfs_bitmap_info *bitmap;
+
+	bitmap = vmalloc (sizeof (*bitmap) * SB_BMAP_NR (sb));
+	if (bitmap)
+		memset (bitmap, 0, sizeof (*bitmap) * SB_BMAP_NR (sb));
+
+	return bitmap;
+}
+
+
+#if 0
 /* load_bitmap_info_data - Sets up the reiserfs_bitmap_info structure from disk.
  * @sb - superblock for this filesystem
  * @bi - the bitmap info to be loaded. Requires that bi->bh is valid.
@@ -1293,6 +1303,7 @@ static int read_old_bitmaps (struct supe
   return 0;
 }
 
+#endif
 static int read_super_block (struct super_block * s, int offset)
 {
     struct buffer_head * bh;
@@ -1389,7 +1400,6 @@ static int read_super_block (struct supe
 
 /* after journal replay, reread all bitmap and super blocks */
 static int reread_meta_blocks(struct super_block *s) {
-  int i ;
   ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s))) ;
   wait_on_buffer(SB_BUFFER_WITH_SB(s)) ;
   if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) {
@@ -1397,6 +1407,7 @@ static int reread_meta_blocks(struct sup
     return 1 ;
   }
 
+#if 0
   for (i = 0; i < SB_BMAP_NR(s) ; i++) {
     ll_rw_block(READ, 1, &(SB_AP_BITMAP(s)[i].bh)) ;
     wait_on_buffer(SB_AP_BITMAP(s)[i].bh) ;
@@ -1406,6 +1417,7 @@ static int reread_meta_blocks(struct sup
       return 1 ;
     }
   }
+#endif
   return 0 ;
 
 }
@@ -1639,8 +1651,9 @@ static int reiserfs_fill_super (struct s
     sbi->s_mount_state = SB_REISERFS_STATE(s);
     sbi->s_mount_state = REISERFS_VALID_FS ;
 
-    if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) {
-	SWARN(silent, s, "jmacd-8: reiserfs_fill_super: unable to read bitmap");
+    SB_AP_BITMAP(s) = init_bitmap_cache (s);
+    if (!SB_AP_BITMAP(s)) {
+	SWARN(silent, s, "jdm-8: reiserfs_fill_super: unable to init bitmap cache");
 	goto error;
     }
 #ifdef CONFIG_REISERFS_CHECK
@@ -1799,12 +1812,7 @@ static int reiserfs_fill_super (struct s
 	journal_release_error(NULL, s) ;
     }
     if (SB_DISK_SUPER_BLOCK (s)) {
-	for (j = 0; j < SB_BMAP_NR (s); j ++) {
-	    if (SB_AP_BITMAP (s))
-		brelse (SB_AP_BITMAP (s)[j].bh);
-	}
-	if (SB_AP_BITMAP (s))
-	    vfree (SB_AP_BITMAP (s));
+	vfree (SB_AP_BITMAP (s));
     }
     if (SB_BUFFER_WITH_SB (s))
 	brelse(SB_BUFFER_WITH_SB (s));
diff -ruNpX dontdiff linux-2.6.12.1/include/linux/reiserfs_fs.h linux-2.6.12.1.devel/include/linux/reiserfs_fs.h
--- linux-2.6.12.1/include/linux/reiserfs_fs.h	2005-06-30 12:51:48.000000000 -0400
+++ linux-2.6.12.1.devel/include/linux/reiserfs_fs.h	2005-06-30 16:13:59.000000000 -0400
@@ -2111,6 +2111,7 @@ void reiserfs_init_alloc_options (struct
  */
 __le32 reiserfs_choose_packing(struct inode *dir);
 
+struct buffer_head * read_bitmap_block (struct super_block *sb, unsigned int bitmap);
 int is_reusable (struct super_block * s, b_blocknr_t block, int bit_value);
 void reiserfs_free_block (struct reiserfs_transaction_handle *th, struct inode *, b_blocknr_t, int for_unformatted);
 int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t *, b_blocknr_t * , int, int);
diff -ruNpX dontdiff linux-2.6.12.1/include/linux/reiserfs_fs_sb.h linux-2.6.12.1.devel/include/linux/reiserfs_fs_sb.h
--- linux-2.6.12.1/include/linux/reiserfs_fs_sb.h	2005-03-02 02:38:09.000000000 -0500
+++ linux-2.6.12.1.devel/include/linux/reiserfs_fs_sb.h	2005-06-30 15:43:09.000000000 -0400
@@ -269,7 +269,6 @@ struct reiserfs_bitmap_info
     // FIXME: Won't work with block sizes > 8K
     __u16  first_zero_hint;
     __u16  free_count;
-    struct buffer_head *bh; /* the actual bitmap */
 };
 
 struct proc_dir_entry;
@@ -419,6 +418,7 @@ struct reiserfs_sb_info
 /* Definitions of reiserfs on-disk properties: */
 #define REISERFS_3_5 0
 #define REISERFS_3_6 1
+#define REISERFS_OLD_FORMAT 2
 
 enum reiserfs_mount_options {
 /* Mount options */

Reply via email to