All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hans Reiser <reiser@namesys.com>
To: Jeff Mahoney <jeffm@suse.com>
Cc: ReiserFS List <reiserfs-list@namesys.com>
Subject: Re: [PATCH 4/4] reiserfs: on-demand bitmap loading
Date: Tue, 17 Jan 2006 10:34:25 -0800	[thread overview]
Message-ID: <43CD38B1.2020804@namesys.com> (raw)
In-Reply-To: <20060117135417.GA8374@locomotive.unixthugs.org>

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 <jeffm@suse.com>
>
>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	other threads:[~2006-01-17 18:34 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-01-17 13:54 [PATCH 4/4] reiserfs: on-demand bitmap loading Jeff Mahoney
2006-01-17 18:34 ` Hans Reiser [this message]
2006-01-17 18:59   ` Jeff Mahoney
2006-01-17 19:03     ` Hans Reiser
  -- strict thread matches above, loose matches on Subject: below --
2006-01-17 20:30 Jeff Mahoney

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=43CD38B1.2020804@namesys.com \
    --to=reiser@namesys.com \
    --cc=jeffm@suse.com \
    --cc=reiserfs-list@namesys.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.