Are you saying that you allow bitmaps to be unloaded?  If yes, how about
making that a separate option, and not the default?

Hans

Jeff Mahoney wrote:

> 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.
>
> fs/reiserfs/bitmap.c           |   76 
> ++++++++++++++++++++---------------------
> fs/reiserfs/resize.c           |   24 +++++++++---
> fs/reiserfs/super.c            |   25 -------------
> include/linux/reiserfs_fs_sb.h |    1 
> 4 files changed, 56 insertions(+), 70 deletions(-)
>
>Signed-off-by: Jeff Mahoney <[EMAIL PROTECTED]>
>
>diff -ruNpX ../dontdiff linux-2.6.15.orig.staging1/fs/reiserfs/bitmap.c 
>linux-2.6.15.orig.staging2/fs/reiserfs/bitmap.c
>--- linux-2.6.15.orig.staging1/fs/reiserfs/bitmap.c    2006-01-16 
>16:53:33.626628760 -0500
>+++ linux-2.6.15.orig.staging2/fs/reiserfs/bitmap.c    2006-01-16 
>16:53:33.634627544 -0500
>@@ -101,8 +101,9 @@ int is_reusable(struct super_block *s, b
>               return 0;
>       }
> 
>-      bh = SB_AP_BITMAP(s)[i].bh;
>-      get_bh(bh);
>+      bh = reiserfs_read_bitmap_block(s, bmap);
>+      if (bh == NULL)
>+              return 0;
> 
>       if ((bit_value == 0 && reiserfs_test_le_bit(j, bh->b_data)) ||
>           (bit_value == 1 && reiserfs_test_le_bit(j, bh->b_data) == 0)) {
>@@ -175,13 +176,10 @@ static int scan_bitmap_block(struct reis
>                                bmap_n);
>               return 0;
>       }
>-      bh = bi->bh;
>-      get_bh(bh);
> 
>-      if (buffer_locked(bi->bh)) {
>-              PROC_INFO_INC(s, scan_bitmap.wait);
>-              __wait_on_buffer(bh);
>-      }
>+      bh = reiserfs_read_bitmap_block(s, bmap_n);
>+      if (bh == NULL)
>+              return 0;
> 
>       while (1) {
>               if (bi->free_count < min) {
>@@ -286,9 +284,20 @@ static int bmap_hash_id(struct super_blo
>  */
> static inline int block_group_used(struct super_block *s, u32 id)
> {
>-      int bm;
>-      bm = bmap_hash_id(s, id);
>-      if (SB_AP_BITMAP(s)[bm].free_count > ((s->s_blocksize << 3) * 60 / 
>100)) {
>+      int bm = bmap_hash_id(s, id);
>+      struct reiserfs_bitmap_info *info = &SB_AP_BITMAP(s)[bm];
>+
>+      /* If we don't have cached information on this bitmap block, we're
>+       * going to have to load it later anyway. Loading it here allows us
>+       * to make a better decision. This favors long-term performace gain
>+       * with a better on-disk layout vs. a short term gain of skipping the
>+       * read and potentially having a bad placement. */
>+      if (info->first_zero_hint == 0) {
>+              struct buffer_head *bh = reiserfs_read_bitmap_block(s, bm);
>+              brelse(bh);
>+      }
>+
>+      if (info->free_count > ((s->s_blocksize << 3) * 60 / 100)) {
>               return 0;
>       }
>       return 1;
>@@ -414,8 +423,9 @@ static void _reiserfs_free_block(struct 
>               return;
>       }
> 
>-      bmbh = apbi[nr].bh;
>-      get_bh(bmbh);
>+      bmbh = reiserfs_read_bitmap_block(s, nr);
>+      if (!bmbh)
>+              return;
> 
>       reiserfs_prepare_for_journal(s, bmbh, 1);
> 
>@@ -1319,6 +1329,7 @@ struct buffer_head *reiserfs_read_bitmap
>                                                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.
>@@ -1326,9 +1337,20 @@ struct buffer_head *reiserfs_read_bitmap
>       if (test_bit(REISERFS_OLD_FORMAT, &(REISERFS_SB(sb)->s_properties)))
>               block = REISERFS_SB(sb)->s_sbh->b_blocknr + 1 + bitmap;
> 
>-      bh = sb_getblk(sb, block);
>-      if (!buffer_uptodate(bh))
>-              ll_rw_block(READ, 1, &bh);
>+      bh = sb_bread(sb, block);
>+      if (bh == NULL)
>+              reiserfs_warning(sb, "sh-2029: reiserfs read_bitmaps: "
>+                               "bitmap block (#%lu) reading failed",
>+                               bh->b_blocknr);
>+      else {
>+              if (buffer_locked(bh)) {
>+                      PROC_INFO_INC(s, scan_bitmap.wait);
>+                      __wait_on_buffer(bh);
>+              }
>+              
>+              if (info->first_zero_hint == 0)
>+                      reiserfs_cache_bitmap_metadata(sb, bh, info);
>+      }
> 
>       return bh;
> }
>@@ -1336,7 +1358,6 @@ struct buffer_head *reiserfs_read_bitmap
> int reiserfs_init_bitmap_cache(struct super_block *sb)
> {
>       struct reiserfs_bitmap_info *bitmap;
>-      int i;
> 
>       bitmap = vmalloc(sizeof (*bitmap) * SB_BMAP_NR(sb));
>       if (bitmap == NULL)
>@@ -1344,27 +1365,6 @@ int reiserfs_init_bitmap_cache(struct su
> 
>       memset(bitmap, 0, sizeof (*bitmap) * SB_BMAP_NR(sb));
> 
>-      for (i = 0; i < SB_BMAP_NR(sb); i++)
>-              bitmap[i].bh = reiserfs_read_bitmap_block(sb, i);
>-
>-      /* make sure we have them all */
>-      for (i = 0; i < SB_BMAP_NR(sb); i++) {
>-              wait_on_buffer(bitmap[i].bh);
>-              if (!buffer_uptodate(bitmap[i].bh)) {
>-                      reiserfs_warning(sb, "sh-2029: reiserfs read_bitmaps: "
>-                                       "bitmap block (#%lu) reading failed",
>-                                       bitmap[i].bh->b_blocknr);
>-                      for (i = 0; i < SB_BMAP_NR(sb); i++)
>-                              brelse(bitmap[i].bh);
>-                      vfree(bitmap);
>-                      return 1;
>-              }
>-      }
>-
>-      /* Cache the info on the bitmaps before we get rolling */
>-      for (i = 0; i < SB_BMAP_NR(sb); i++)
>-              reiserfs_cache_bitmap_metadata(sb, bitmap[i].bh, &bitmap[i]);
>-
>       SB_AP_BITMAP(sb) = bitmap;
> 
>       return 0;
>diff -ruNpX ../dontdiff linux-2.6.15.orig.staging1/fs/reiserfs/resize.c 
>linux-2.6.15.orig.staging2/fs/reiserfs/resize.c
>--- linux-2.6.15.orig.staging1/fs/reiserfs/resize.c    2006-01-16 
>16:53:33.626628760 -0500
>+++ linux-2.6.15.orig.staging2/fs/reiserfs/resize.c    2006-01-16 
>16:53:33.636627240 -0500
>@@ -128,8 +128,9 @@ int reiserfs_resize(struct super_block *
>                * transaction begins, and the new bitmaps don't matter if the
>                * transaction fails. */
>               for (i = bmap_nr; i < bmap_nr_new; i++) {
>-                      bh = sb_getblk(s, i * s->s_blocksize * 8);
>-                      get_bh(bh);
>+                      /* don't use read_bitmap_block since it will cache
>+                       * the uninitialized bitmap */
>+                      bh = sb_bread(s, i * s->s_blocksize * 8);
>                       memset(bh->b_data, 0, sb_blocksize(sb));
>                       reiserfs_test_and_set_le_bit(0, bh->b_data);
>                       reiserfs_cache_bitmap_metadata(s, bh, bitmap + i);
>@@ -140,7 +141,6 @@ int reiserfs_resize(struct super_block *
>                       // update bitmap_info stuff
>                       bitmap[i].first_zero_hint = 1;
>                       bitmap[i].free_count = sb_blocksize(sb) * 8 - 1;
>-                      bitmap[i].bh = bh;
>                       brelse(bh);
>               }
>               /* free old bitmap blocks array */
>@@ -157,8 +157,13 @@ int reiserfs_resize(struct super_block *
> 
>       /* Extend old last bitmap block - new blocks have been made available */
>       info = SB_AP_BITMAP(s) + bmap_nr - 1;
>-      bh = info->bh;
>-      get_bh(bh);
>+      bh = reiserfs_read_bitmap_block(s, bmap_nr - 1);
>+      if (!bh) {
>+              int jerr = journal_end(&th, s, 10);
>+              if (jerr)
>+                      return jerr;
>+              return -EIO;
>+      }
> 
>       reiserfs_prepare_for_journal(s, bh, 1);
>       for (i = block_r; i < s->s_blocksize * 8; i++)
>@@ -172,8 +177,13 @@ int reiserfs_resize(struct super_block *
> 
>       /* Correct new last bitmap block - It may not be full */
>       info = SB_AP_BITMAP(s) + bmap_nr_new - 1;
>-      bh = info->bh;
>-      get_bh(bh);
>+      bh = reiserfs_read_bitmap_block(s, bmap_nr_new - 1);
>+      if (!bh) {
>+              int jerr = journal_end(&th, s, 10);
>+              if (jerr)
>+                      return jerr;
>+              return -EIO;
>+      }
> 
>       reiserfs_prepare_for_journal(s, bh, 1);
>       for (i = block_r_new; i < s->s_blocksize * 8; i++)
>diff -ruNpX ../dontdiff linux-2.6.15.orig.staging1/fs/reiserfs/super.c 
>linux-2.6.15.orig.staging2/fs/reiserfs/super.c
>--- linux-2.6.15.orig.staging1/fs/reiserfs/super.c     2006-01-16 
>16:53:33.628628456 -0500
>+++ linux-2.6.15.orig.staging2/fs/reiserfs/super.c     2006-01-16 
>16:53:33.637627088 -0500
>@@ -433,7 +433,6 @@ int remove_save_link(struct inode *inode
> 
> static void reiserfs_put_super(struct super_block *s)
> {
>-      int i;
>       struct reiserfs_transaction_handle th;
>       th.t_trans_id = 0;
> 
>@@ -463,9 +462,6 @@ static void reiserfs_put_super(struct su
>        */
>       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));
>@@ -1365,7 +1361,6 @@ static int read_super_block(struct super
> /* 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))) {
>@@ -1374,20 +1369,7 @@ static int reread_meta_blocks(struct sup
>               return 1;
>       }
> 
>-      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);
>-              if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) {
>-                      reiserfs_warning(s,
>-                                       "reread_meta_blocks, error reading 
>bitmap block number %d at %llu",
>-                                       i,
>-                                       (unsigned long long)SB_AP_BITMAP(s)[i].
>-                                       bh->b_blocknr);
>-                      return 1;
>-              }
>-      }
>       return 0;
>-
> }
> 
> /////////////////////////////////////////////////////
>@@ -1814,13 +1796,8 @@ static int reiserfs_fill_super(struct su
>       if (jinit_done) {       /* kill the commit thread, free journal ram */
>               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_DISK_SUPER_BLOCK(s))
>               vfree(SB_AP_BITMAP(s));
>-      }
>       if (SB_BUFFER_WITH_SB(s))
>               brelse(SB_BUFFER_WITH_SB(s));
> #ifdef CONFIG_QUOTA
>diff -ruNpX ../dontdiff 
>linux-2.6.15.orig.staging1/include/linux/reiserfs_fs_sb.h 
>linux-2.6.15.orig.staging2/include/linux/reiserfs_fs_sb.h
>--- linux-2.6.15.orig.staging1/include/linux/reiserfs_fs_sb.h  2006-01-16 
>16:53:29.453263208 -0500
>+++ linux-2.6.15.orig.staging2/include/linux/reiserfs_fs_sb.h  2006-01-16 
>16:53:33.638626936 -0500
>@@ -267,7 +267,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;
>
>
>  
>

Reply via email to