[kernel] r7721 - in dists/trunk/linux-2.6/debian: . patches/features patches/series

maximilian attems maks-guest at alioth.debian.org
Wed Nov 8 23:14:09 UTC 2006


Author: maks-guest
Date: Thu Nov  9 00:14:08 2006
New Revision: 7721

Added:
   dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-bitmap-block-cleanup.patch
   dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-bitmap-block-optimization.patch
   dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-bitmap-on-demand-loading.patch
   dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-bitmap-reorganize.patch
   dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-fsync-barriers.patch
   dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-gcc-flags.patch
   dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-latency-journal_begin.patch
   dists/trunk/linux-2.6/debian/patches/series/6
Modified:
   dists/trunk/linux-2.6/debian/changelog
Log:
open 2.6.18-6: start adding first set of reiserfs backport


Modified: dists/trunk/linux-2.6/debian/changelog
==============================================================================
--- dists/trunk/linux-2.6/debian/changelog	(original)
+++ dists/trunk/linux-2.6/debian/changelog	Thu Nov  9 00:14:08 2006
@@ -1,3 +1,16 @@
+linux-2.6 (2.6.18-6) UNRELEASED; urgency=low
+
+  * reiserfs backport 2.6.19 SUSE fixes: 
+   - use gcc -O1 in fs/reiserfs only for ancient gcc versions
+   - reiserfs_fsync should only use barriers when they are enabled
+   - Fix reiserfs latencies caused by data=ordered
+   - fix is_reusable bitmap check to not traverse the bitmap info array
+   - clean up bitmap block buffer head references
+   - reorganize bitmap loading functions
+   - on-demand bitmap loading
+
+ -- maximilian attems <maks at sternwelten.at>  Thu,  9 Nov 2006 00:09:36 +0100
+
 linux-2.6 (2.6.18-5) unstable; urgency=low
 
   [ maximilian attems ]

Added: dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-bitmap-block-cleanup.patch
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-bitmap-block-cleanup.patch	Thu Nov  9 00:14:08 2006
@@ -0,0 +1,291 @@
+From git-commits-head-owner at vger.kernel.org Wed Oct  4 17:36:49 2006
+Date: Sun, 1 Oct 2006 08:01:29 GMT
+Message-Id: <200610010801.k9181TNv010078 at hera.kernel.org>
+From: Linux Kernel Mailing List <linux-kernel at vger.kernel.org>
+To: git-commits-head at vger.kernel.org
+Subject: [PATCH] reiserfs: clean up bitmap block buffer head references
+
+commit 0b3dc17bc0c0997bde9f5d7691ec0cae24258cf7
+tree ecdbb6f830737358706b0ba7c628f47f9fdc0ff4
+parent e1fabd3ccf02901374bffa434e0af472749a5bd9
+author Jeff Mahoney <jeffm at suse.com> 1159684122 -0700
+committer Linus Torvalds <torvalds at g5.osdl.org> 1159688367 -0700
+
+[PATCH] reiserfs: clean up bitmap block buffer head references
+
+Similar to the SB_JOURNAL cleanup that was accepted a while ago, this patch
+uses a temporary variable for buffer head references from the bitmap info
+array.
+
+This makes the code much more readable in some areas.
+
+It also uses proper reference counting, doing a get_bh() after using the
+pointer from the array and brelse()'ing it later.  This may seem silly, but a
+later patch will replace the simple temporary variables with an actual read,
+so the reference freeing will be used then.
+
+Signed-off-by: Jeff Mahoney <jeffm at suse.com>
+Cc: <reiserfs-dev at namesys.com>
+Signed-off-by: Andrew Morton <akpm at osdl.org>
+Signed-off-by: Linus Torvalds <torvalds at osdl.org>
+
+ fs/reiserfs/bitmap.c |   60 ++++++++++++++++++++++++++++++---------------------
+ fs/reiserfs/resize.c |   60 +++++++++++++++++++++++++++++----------------------
+ 2 files changed, 71 insertions(+), 49 deletions(-)
+
+diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
+index 1022347..44d9410 100644
+--- a/fs/reiserfs/bitmap.c
++++ b/fs/reiserfs/bitmap.c
+@@ -59,6 +59,7 @@ #ifdef CONFIG_REISERFS_CHECK
+ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value)
+ {
+ 	int bmap, offset;
++	struct buffer_head *bh;
+ 
+ 	if (block == 0 || block >= SB_BLOCK_COUNT(s)) {
+ 		reiserfs_warning(s,
+@@ -96,20 +97,21 @@ int is_reusable(struct super_block *s, b
+ 		return 0;
+ 	}
+ 
+-	if ((bit_value == 0 &&
+-	     reiserfs_test_le_bit(offset, SB_AP_BITMAP(s)[bmap].bh->b_data)) ||
+-	    (bit_value == 1 &&
+-	     reiserfs_test_le_bit(offset, SB_AP_BITMAP(s)[bmap].bh->b_data) == 0)) {
++	bh = SB_AP_BITMAP(s)[bmap].bh;
++	get_bh(bh);
++
++	if ((bit_value == 0 && reiserfs_test_le_bit(offset, bh->b_data)) ||
++	    (bit_value == 1 && reiserfs_test_le_bit(offset, bh->b_data) == 0)) {
+ 		reiserfs_warning(s,
+ 				 "vs-4040: is_reusable: corresponding bit of block %lu does not "
+ 				 "match required value (bmap==%d, offset==%d) test_bit==%d",
+-				 block, bmap, offset, reiserfs_test_le_bit(offset,
+-								   SB_AP_BITMAP
+-								   (s)[bmap].bh->
+-								   b_data));
++				 block, bmap, offset,
++				 reiserfs_test_le_bit(offset, bh->b_data));
+ 
++		brelse(bh);
+ 		return 0;
+ 	}
++	brelse(bh);
+ 
+ 	if (bit_value == 0 && block == SB_ROOT_BLOCK(s)) {
+ 		reiserfs_warning(s,
+@@ -151,6 +153,7 @@ static int scan_bitmap_block(struct reis
+ {
+ 	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;
+ 
+@@ -169,22 +172,28 @@ static int scan_bitmap_block(struct reis
+ 				 bmap_n);
+ 		return 0;
+ 	}
+-	if (buffer_locked(bi->bh)) {
++	bh = bi->bh;
++	get_bh(bh);
++
++	if (buffer_locked(bh)) {
+ 		PROC_INFO_INC(s, scan_bitmap.wait);
+-		__wait_on_buffer(bi->bh);
++		__wait_on_buffer(bh);
+ 	}
+ 
+ 	while (1) {
+ 	      cont:
+-		if (bi->free_count < min)
++		if (bi->free_count < min) {
++			brelse(bh);
+ 			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;
+ 		}
+ 
+@@ -193,7 +202,7 @@ static int scan_bitmap_block(struct reis
+ 		/* 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)) {
++			    || reiserfs_test_le_bit(end, bh->b_data)) {
+ 				next = end;
+ 				break;
+ 			}
+@@ -207,12 +216,12 @@ static int scan_bitmap_block(struct reis
+ 		 * (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)) {
++				    (i, bh->b_data)) {
+ 					/* bit was set by another process
+ 					 * while we slept in prepare_for_journal() */
+ 					PROC_INFO_INC(s, scan_bitmap.stolen);
+@@ -224,17 +233,16 @@ static int scan_bitmap_block(struct reis
+ 					/* 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);
++						    (i, bh->b_data);
++					reiserfs_restore_prepared_buffer(s, bh);
+ 					*beg = org;
+ 					/* ... and search again in current block from beginning */
+ 					goto cont;
+ 				}
+ 			}
+ 			bi->free_count -= (end - *beg);
+-			journal_mark_dirty(th, s, bi->bh);
++			journal_mark_dirty(th, s, bh);
++			brelse(bh);
+ 
+ 			/* free block count calculation */
+ 			reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s),
+@@ -383,7 +391,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;
+ 
+@@ -404,16 +412,20 @@ static void _reiserfs_free_block(struct 
+ 		return;
+ 	}
+ 
+-	reiserfs_prepare_for_journal(s, apbi[nr].bh, 1);
++	bmbh = apbi[nr].bh;
++	get_bh(bmbh);
++
++	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 */
+diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c
+index 39cc7f4..958b759 100644
+--- a/fs/reiserfs/resize.c
++++ b/fs/reiserfs/resize.c
+@@ -22,6 +22,7 @@ int reiserfs_resize(struct super_block *
+ 	int err = 0;
+ 	struct reiserfs_super_block *sb;
+ 	struct reiserfs_bitmap_info *bitmap;
++	struct reiserfs_bitmap_info *info;
+ 	struct reiserfs_bitmap_info *old_bitmap = SB_AP_BITMAP(s);
+ 	struct buffer_head *bh;
+ 	struct reiserfs_transaction_handle th;
+@@ -127,16 +128,19 @@ 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++) {
+-			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);
++			bh = sb_getblk(s, i * s->s_blocksize * 8);
++			get_bh(bh);
++			memset(bh->b_data, 0, sb_blocksize(sb));
++			reiserfs_test_and_set_le_bit(0, bh->b_data);
++
++			set_buffer_uptodate(bh);
++			mark_buffer_dirty(bh);
++			sync_dirty_buffer(bh);
+ 			// 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 */
+ 		SB_AP_BITMAP(s) = bitmap;
+@@ -150,30 +154,36 @@ 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);
++	/* 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);
++
++	reiserfs_prepare_for_journal(s, 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;
++		reiserfs_test_and_clear_le_bit(i, bh->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, bh);
++	brelse(bh);
+ 
+-	journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr - 1].bh);
++	/* 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);
+ 
+-	reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr_new - 1].bh, 1);
++	reiserfs_prepare_for_journal(s, bh, 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, bh->b_data);
++	journal_mark_dirty(&th, s, bh);
++	brelse(bh);
+ 
+-	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);

Added: dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-bitmap-block-optimization.patch
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-bitmap-block-optimization.patch	Thu Nov  9 00:14:08 2006
@@ -0,0 +1,184 @@
+From git-commits-head-owner at vger.kernel.org Wed Oct  4 17:36:47 2006
+Return-Path: <git-commits-head-owner at vger.kernel.org>
+Delivered-To: unknown
+Received: from baikonur.stro.at (213.239.196.228) by nancy with IMAP4-SSL; 04
+  Oct 2006 15:36:47 -0000
+X-Original-To: janitor at sternwelten.at
+Delivered-To: janitor at sternwelten.at
+Received: from vger.kernel.org (vger.kernel.org [209.132.176.167])
+	by baikonur.stro.at (Postfix) with ESMTP id 3DFD35C066
+	for <janitor at sternwelten.at>; Sun,  1 Oct 2006 10:01:38 +0200 (CEST)
+Received: (majordomo at vger.kernel.org) by vger.kernel.org via listexpand
+	id S932105AbWJAIBp (ORCPT <rfc822;janitor at sternwelten.at>);
+	Sun, 1 Oct 2006 04:01:45 -0400
+Received: (majordomo at vger.kernel.org) by vger.kernel.org id S932106AbWJAIBp
+	(ORCPT <rfc822;git-commits-head-outgoing>);
+	Sun, 1 Oct 2006 04:01:45 -0400
+Received: from hera.kernel.org ([140.211.167.34]:36786 "EHLO hera.kernel.org")
+	by vger.kernel.org with ESMTP id S932105AbWJAIB3 (ORCPT
+	<rfc822;git-commits-head at vger.kernel.org>);
+	Sun, 1 Oct 2006 04:01:29 -0400
+Received: from hera.kernel.org (IDENT:U2FsdGVkX1/qIwMDDPAqUjfbNz4+pldcJIqmPXsPjR0 at localhost [127.0.0.1])
+	by hera.kernel.org (8.13.7/8.13.7) with ESMTP id k9181St4010065
+	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO)
+	for <git-commits-head at vger.kernel.org>; Sun, 1 Oct 2006 08:01:28 GMT
+Received: (from dwmw2 at localhost)
+	by hera.kernel.org (8.13.7/8.13.1/Submit) id k9181Rot010064
+	for git-commits-head at vger.kernel.org; Sun, 1 Oct 2006 08:01:27 GMT
+Date: Sun, 1 Oct 2006 08:01:27 GMT
+Message-Id: <200610010801.k9181Rot010064 at hera.kernel.org>
+From: Linux Kernel Mailing List <linux-kernel at vger.kernel.org>
+To: git-commits-head at vger.kernel.org
+Subject: [PATCH] reiserfs: fix is_reusable bitmap check to not traverse the bitmap info array
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+X-Git-Commit: e1fabd3ccf02901374bffa434e0af472749a5bd9
+X-Git-Parent: 8ef386092d7c2891bd7acefb2a87f878f7e9a0d6
+Sender: git-commits-head-owner at vger.kernel.org
+Precedence: bulk
+X-Mailing-List: git-commits-head at vger.kernel.org
+X-Virus-Scanned: by Amavis (ClamAV) at stro.at
+Status: RO
+Content-Length: 5049
+
+commit e1fabd3ccf02901374bffa434e0af472749a5bd9
+tree 66d618e98020422874a521142ca2da797c9930f3
+parent 8ef386092d7c2891bd7acefb2a87f878f7e9a0d6
+author Jeff Mahoney <jeffm at suse.com> 1159684120 -0700
+committer Linus Torvalds <torvalds at g5.osdl.org> 1159688367 -0700
+
+[PATCH] reiserfs: fix is_reusable bitmap check to not traverse the bitmap info array
+
+There is a check in is_reusable to determine if a particular block is a bitmap
+block.  It verifies this by going through the array of bitmap block buffer
+heads and comparing the block number to each one.
+
+Bitmap blocks are at defined locations on the disk in both old and current
+formats.  Simply checking against the known good values is enough.
+
+This is a trivial optimization for a non-production codepath, but this is the
+first in a series of patches that will ultimately remove the buffer heads from
+that array.
+
+Signed-off-by: Jeff Mahoney <jeffm at suse.com>
+Cc: <reiserfs-dev at namesys.com>
+Signed-off-by: Andrew Morton <akpm at osdl.org>
+Signed-off-by: Linus Torvalds <torvalds at osdl.org>
+
+ fs/reiserfs/bitmap.c           |   40 +++++++++++++++++++++++++---------------
+ fs/reiserfs/super.c            |    2 ++
+ include/linux/reiserfs_fs_sb.h |    1 +
+ 3 files changed, 28 insertions(+), 15 deletions(-)
+
+diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
+index 4a7dbde..1022347 100644
+--- a/fs/reiserfs/bitmap.c
++++ b/fs/reiserfs/bitmap.c
+@@ -50,16 +50,15 @@ static inline void get_bit_address(struc
+ {
+ 	/* It is in the bitmap block number equal to the block
+ 	 * number divided by the number of bits in a block. */
+-	*bmap_nr = block / (s->s_blocksize << 3);
++	*bmap_nr = block >> (s->s_blocksize_bits + 3);
+ 	/* Within that bitmap block it is located at bit offset *offset. */
+ 	*offset = block & ((s->s_blocksize << 3) - 1);
+-	return;
+ }
+ 
+ #ifdef CONFIG_REISERFS_CHECK
+ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value)
+ {
+-	int i, j;
++	int bmap, offset;
+ 
+ 	if (block == 0 || block >= SB_BLOCK_COUNT(s)) {
+ 		reiserfs_warning(s,
+@@ -68,34 +67,45 @@ int is_reusable(struct super_block *s, b
+ 		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) {
++	get_bit_address(s, block, &bmap, &offset);
++
++	/* 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(s)->s_properties)))) {
++		b_blocknr_t bmap1 = REISERFS_SB(s)->s_sbh->b_blocknr + 1;
++		if (block >= bmap1 && block <= bmap1 + 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 (offset == 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);
+-
+-	if (i >= SB_BMAP_NR(s)) {
++	if (bmap >= SB_BMAP_NR(s)) {
+ 		reiserfs_warning(s,
+ 				 "vs-4030: is_reusable: there is no so many bitmap blocks: "
+-				 "block=%lu, bitmap_nr=%d", block, i);
++				 "block=%lu, bitmap_nr=%d", block, bmap);
+ 		return 0;
+ 	}
+ 
+ 	if ((bit_value == 0 &&
+-	     reiserfs_test_le_bit(j, SB_AP_BITMAP(s)[i].bh->b_data)) ||
++	     reiserfs_test_le_bit(offset, SB_AP_BITMAP(s)[bmap].bh->b_data)) ||
+ 	    (bit_value == 1 &&
+-	     reiserfs_test_le_bit(j, SB_AP_BITMAP(s)[i].bh->b_data) == 0)) {
++	     reiserfs_test_le_bit(offset, SB_AP_BITMAP(s)[bmap].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,
++				 "match required value (bmap==%d, offset==%d) test_bit==%d",
++				 block, bmap, offset, reiserfs_test_le_bit(offset,
+ 								   SB_AP_BITMAP
+-								   (s)[i].bh->
++								   (s)[bmap].bh->
+ 								   b_data));
+ 
+ 		return 0;
+diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
+index 80fc3b3..db2c581 100644
+--- a/fs/reiserfs/super.c
++++ b/fs/reiserfs/super.c
+@@ -1818,6 +1818,8 @@ #endif
+ 	if (is_reiserfs_3_5(rs)
+ 	    || (is_reiserfs_jr(rs) && SB_VERSION(s) == REISERFS_VERSION_1))
+ 		set_bit(REISERFS_3_5, &(sbi->s_properties));
++	else if (old_format)
++		set_bit(REISERFS_OLD_FORMAT, &(sbi->s_properties));
+ 	else
+ 		set_bit(REISERFS_3_6, &(sbi->s_properties));
+ 
+diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
+index 31b4c0b..4f21ad3 100644
+--- a/include/linux/reiserfs_fs_sb.h
++++ b/include/linux/reiserfs_fs_sb.h
+@@ -414,6 +414,7 @@ #endif
+ /* 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 */
+-
+To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
+the body of a message to majordomo at vger.kernel.org
+More majordomo info at  http://vger.kernel.org/majordomo-info.html
+

Added: dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-bitmap-on-demand-loading.patch
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-bitmap-on-demand-loading.patch	Thu Nov  9 00:14:08 2006
@@ -0,0 +1,368 @@
+From git-commits-head-owner at vger.kernel.org Wed Oct  4 17:36:49 2006
+Date: Sun, 1 Oct 2006 08:01:31 GMT
+Message-Id: <200610010801.k9181V7G010116 at hera.kernel.org>
+From: Linux Kernel Mailing List <linux-kernel at vger.kernel.org>
+To: git-commits-head at vger.kernel.org
+Subject: [PATCH] reiserfs: on-demand bitmap loading
+
+commit 5065227b46235ec0131b383cc2f537069b55c6b6
+tree 12187734ef619626c901b9d2b43ad72286d4d258
+parent 6f01046b35d940079822827498a7dd6d3eec8c6b
+author Jeff Mahoney <jeffm at suse.com> 1159684124 -0700
+committer Linus Torvalds <torvalds at g5.osdl.org> 1159688368 -0700
+
+[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 at osdl.org: warning fix]
+Signed-off-by: Jeff Mahoney <jeffm at suse.com>
+Cc: <reiserfs-dev at namesys.com>
+Signed-off-by: Andrew Morton <akpm at osdl.org>
+Signed-off-by: Linus Torvalds <torvalds at osdl.org>
+
+ fs/reiserfs/bitmap.c           |   97 ++++++++++++++++++-----------------------
+ fs/reiserfs/resize.c           |   24 +++++++---
+ fs/reiserfs/super.c            |   39 +++-------------
+ 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 abdd6d9..cca1dbf 100644
+--- a/fs/reiserfs/bitmap.c
++++ b/fs/reiserfs/bitmap.c
+@@ -60,7 +60,6 @@ #ifdef CONFIG_REISERFS_CHECK
+ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value)
+ {
+ 	int bmap, offset;
+-	struct buffer_head *bh;
+ 
+ 	if (block == 0 || block >= SB_BLOCK_COUNT(s)) {
+ 		reiserfs_warning(s,
+@@ -98,22 +97,6 @@ int is_reusable(struct super_block *s, b
+ 		return 0;
+ 	}
+ 
+-	bh = SB_AP_BITMAP(s)[bmap].bh;
+-	get_bh(bh);
+-
+-	if ((bit_value == 0 && reiserfs_test_le_bit(offset, bh->b_data)) ||
+-	    (bit_value == 1 && reiserfs_test_le_bit(offset, bh->b_data) == 0)) {
+-		reiserfs_warning(s,
+-				 "vs-4040: is_reusable: corresponding bit of block %lu does not "
+-				 "match required value (bmap==%d, offset==%d) test_bit==%d",
+-				 block, bmap, offset,
+-				 reiserfs_test_le_bit(offset, 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), "
+@@ -173,13 +156,10 @@ static int scan_bitmap_block(struct reis
+ 				 bmap_n);
+ 		return 0;
+ 	}
+-	bh = bi->bh;
+-	get_bh(bh);
+ 
+-	if (buffer_locked(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) {
+ 	      cont:
+@@ -285,9 +265,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;
+@@ -413,8 +404,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);
+ 
+@@ -1320,6 +1312,7 @@ struct buffer_head *reiserfs_read_bitmap
+                                                unsigned int bitmap)
+ {
+ 	b_blocknr_t 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.
+@@ -1330,9 +1323,21 @@ struct buffer_head *reiserfs_read_bitmap
+ 	else if (bitmap == 0)
+ 		block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1;
+ 
+-	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: %s: bitmap block (#%lu) "
++		                 "reading failed", __FUNCTION__, bh->b_blocknr);
++	else {
++		if (buffer_locked(bh)) {
++			PROC_INFO_INC(sb, scan_bitmap.wait);
++			__wait_on_buffer(bh);
++		}
++		BUG_ON(!buffer_uptodate(bh));
++		BUG_ON(atomic_read(&bh->b_count) == 0);
++
++		if (info->first_zero_hint == 0)
++			reiserfs_cache_bitmap_metadata(sb, bh, info);
++	}
+ 
+ 	return bh;
+ }
+@@ -1340,7 +1345,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)
+@@ -1348,28 +1352,15 @@ 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: %s: "
+-					 "bitmap block (#%lu) reading failed",
+-			                 __FUNCTION__, bitmap[i].bh->b_blocknr);
+-			for (i = 0; i < SB_BMAP_NR(sb); i++)
+-				brelse(bitmap[i].bh);
+-			vfree(bitmap);
+-			return -EIO;
+-		}
+-	}
+-
+-	/* 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;
+ }
++
++void reiserfs_free_bitmap_cache(struct super_block *sb)
++{
++	if (SB_AP_BITMAP(sb)) {
++		vfree(SB_AP_BITMAP(sb));
++		SB_AP_BITMAP(sb) = NULL;
++	}
++}
+diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c
+index 90d39fd..3156847 100644
+--- a/fs/reiserfs/resize.c
++++ b/fs/reiserfs/resize.c
+@@ -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 --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
+index c78e99e..c89aa23 100644
+--- a/fs/reiserfs/super.c
++++ b/fs/reiserfs/super.c
+@@ -432,7 +432,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;
+ 
+@@ -462,10 +461,7 @@ 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));
++	reiserfs_free_bitmap_cache(s);
+ 
+ 	brelse(SB_BUFFER_WITH_SB(s));
+ 
+@@ -1344,7 +1340,6 @@ #endif
+ /* 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))) {
+@@ -1353,20 +1348,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;
+-
+ }
+ 
+ /////////////////////////////////////////////////////
+@@ -1547,7 +1529,6 @@ #define SWARN(silent, s, ...)			\
+ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
+ {
+ 	struct inode *root_inode;
+-	int j;
+ 	struct reiserfs_transaction_handle th;
+ 	int old_format = 0;
+ 	unsigned long blocks;
+@@ -1793,19 +1774,17 @@ #endif
+ 	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);
+-		}
+-		vfree(SB_AP_BITMAP(s));
+-	}
++
++	reiserfs_free_bitmap_cache(s);
+ 	if (SB_BUFFER_WITH_SB(s))
+ 		brelse(SB_BUFFER_WITH_SB(s));
+ #ifdef CONFIG_QUOTA
+-	for (j = 0; j < MAXQUOTAS; j++) {
+-		kfree(sbi->s_qf_names[j]);
+-		sbi->s_qf_names[j] = NULL;
++	{
++		int j;
++		for (j = 0; j < MAXQUOTAS; j++) {
++			kfree(sbi->s_qf_names[j]);
++			sbi->s_qf_names[j] = NULL;
++		}
+ 	}
+ #endif
+ 	kfree(sbi);
+diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
+index 4f21ad3..73e0bec 100644
+--- a/include/linux/reiserfs_fs_sb.h
++++ b/include/linux/reiserfs_fs_sb.h
+@@ -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;

Added: dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-bitmap-reorganize.patch
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-bitmap-reorganize.patch	Thu Nov  9 00:14:08 2006
@@ -0,0 +1,314 @@
+From git-commits-head-owner at vger.kernel.org Wed Oct  4 17:36:48 2006
+Date: Sun, 1 Oct 2006 08:01:30 GMT
+Message-Id: <200610010801.k9181U4g010098 at hera.kernel.org>
+From: Linux Kernel Mailing List <linux-kernel at vger.kernel.org>
+To: git-commits-head at vger.kernel.org
+Subject: [PATCH] reiserfs: reorganize bitmap loading functions
+
+commit 6f01046b35d940079822827498a7dd6d3eec8c6b
+tree e65426389691c9d3e7d4f29da73725d15ee8e2f6
+parent 0b3dc17bc0c0997bde9f5d7691ec0cae24258cf7
+author Jeff Mahoney <jeffm at suse.com> 1159684123 -0700
+committer Linus Torvalds <torvalds at g5.osdl.org> 1159688367 -0700
+
+[PATCH] reiserfs: reorganize bitmap loading functions
+
+This patch moves the bitmap loading code from super.c to bitmap.c
+
+The code is also restructured somewhat.  The only difference between new
+format bitmaps and old format bitmaps is where they are.  That's a two liner
+before loading the block to use the correct one.  There's no need for an
+entirely separate code path.
+
+The load path is generally the same, with the pattern being to throw out a
+bunch of requests and then wait for them, then cache the metadata from the
+contents.
+
+Again, like the previous patches, the purpose is to set up for later ones.
+
+Update: There was a bug in the previously posted version of this that resulted
+in corruption.  The problem was that bitmap 0 on new format file systems must
+be treated specially, and wasn't.  A stupid bug with an easy fix.
+
+This is hopefully the last fix for the disaster that is the reiserfs bitmap
+patch set.
+
+If a bitmap block was full, first_zero_hint would end up at zero since it
+would never be changed from it's zeroed out value.  This just sets it
+beyond the end of the bitmap block.  If any bits are freed, it will be
+reset to a valid bit.  When info->free_count = 0, then we already know it's
+full.
+
+Signed-off-by: Jeff Mahoney <jeffm at suse.com>
+Cc: <reiserfs-dev at namesys.com>
+Signed-off-by: Andrew Morton <akpm at osdl.org>
+Signed-off-by: Linus Torvalds <torvalds at osdl.org>
+
+ fs/reiserfs/bitmap.c        |   88 +++++++++++++++++++++++++++++++++
+ fs/reiserfs/resize.c        |    1 
+ fs/reiserfs/super.c         |  114 --------------------------------------------
+ include/linux/reiserfs_fs.h |    4 +
+ 4 files changed, 94 insertions(+), 113 deletions(-)
+
+diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
+index 44d9410..abdd6d9 100644
+--- a/fs/reiserfs/bitmap.c
++++ b/fs/reiserfs/bitmap.c
+@@ -9,6 +9,7 @@ #include <linux/errno.h>
+ #include <linux/buffer_head.h>
+ #include <linux/kernel.h>
+ #include <linux/pagemap.h>
++#include <linux/vmalloc.h>
+ #include <linux/reiserfs_fs_sb.h>
+ #include <linux/reiserfs_fs_i.h>
+ #include <linux/quotaops.h>
+@@ -1285,3 +1286,90 @@ int reiserfs_can_fit_pages(struct super_
+ 
+ 	return space > 0 ? space : 0;
+ }
++
++void reiserfs_cache_bitmap_metadata(struct super_block *sb,
++                                    struct buffer_head *bh,
++                                    struct reiserfs_bitmap_info *info)
++{
++	unsigned long *cur = (unsigned long *)(bh->b_data + bh->b_size);
++
++	info->first_zero_hint = 1 << (sb->s_blocksize_bits + 3);
++
++	while (--cur >= (unsigned long *)bh->b_data) {
++		int base = ((char *)cur - bh->b_data) << 3;
++
++		/* 0 and ~0 are special, we can optimize for them */
++		if (*cur == 0) {
++			info->first_zero_hint = base;
++			info->free_count += BITS_PER_LONG;
++		} else if (*cur != ~0L) {       /* A mix, investigate */
++			int b;
++			for (b = BITS_PER_LONG - 1; b >= 0; b--) {
++				if (!reiserfs_test_le_bit(b, cur)) {
++					info->first_zero_hint = base + b;
++					info->free_count++;
++				}
++			}
++		}
++	}
++	/* The first bit must ALWAYS be 1 */
++	BUG_ON(info->first_zero_hint == 0);
++}
++
++struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb,
++                                               unsigned int bitmap)
++{
++	b_blocknr_t block = (sb->s_blocksize << 3) * 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 (unlikely(test_bit(REISERFS_OLD_FORMAT,
++	                      &(REISERFS_SB(sb)->s_properties))))
++		block = REISERFS_SB(sb)->s_sbh->b_blocknr + 1 + bitmap;
++	else if (bitmap == 0)
++		block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1;
++
++	bh = sb_getblk(sb, block);
++	if (!buffer_uptodate(bh))
++		ll_rw_block(READ, 1, &bh);
++
++	return bh;
++}
++
++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)
++		return -ENOMEM;
++
++	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: %s: "
++					 "bitmap block (#%lu) reading failed",
++			                 __FUNCTION__, bitmap[i].bh->b_blocknr);
++			for (i = 0; i < SB_BMAP_NR(sb); i++)
++				brelse(bitmap[i].bh);
++			vfree(bitmap);
++			return -EIO;
++		}
++	}
++
++	/* 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 --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c
+index 958b759..90d39fd 100644
+--- a/fs/reiserfs/resize.c
++++ b/fs/reiserfs/resize.c
+@@ -132,6 +132,7 @@ int reiserfs_resize(struct super_block *
+ 			get_bh(bh);
+ 			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);
+ 
+ 			set_buffer_uptodate(bh);
+ 			mark_buffer_dirty(bh);
+diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
+index db2c581..c78e99e 100644
+--- a/fs/reiserfs/super.c
++++ b/fs/reiserfs/super.c
+@@ -1243,118 +1243,6 @@ #endif
+ 	return 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.
+- *
+- * This routine counts how many free bits there are, finding the first zero
+- * as a side effect. Could also be implemented as a loop of test_bit() calls, or
+- * a loop of find_first_zero_bit() calls. This implementation is similar to
+- * find_first_zero_bit(), but doesn't return after it finds the first bit.
+- * Should only be called on fs mount, but should be fairly efficient anyways.
+- *
+- * bi->first_zero_hint is considered unset if it == 0, since the bitmap itself
+- * will * invariably occupt block 0 represented in the bitmap. The only
+- * exception to this is when free_count also == 0, since there will be no
+- * free blocks at all.
+- */
+-
+-static void load_bitmap_info_data(struct super_block *sb,
+-				  struct reiserfs_bitmap_info *bi)
+-{
+-	unsigned long *cur = (unsigned long *)bi->bh->b_data;
+-
+-	while ((char *)cur < (bi->bh->b_data + sb->s_blocksize)) {
+-
+-		/* No need to scan if all 0's or all 1's.
+-		 * Since we're only counting 0's, we can simply ignore all 1's */
+-		if (*cur == 0) {
+-			if (bi->first_zero_hint == 0) {
+-				bi->first_zero_hint =
+-				    ((char *)cur - bi->bh->b_data) << 3;
+-			}
+-			bi->free_count += sizeof(unsigned long) * 8;
+-		} else if (*cur != ~0L) {
+-			int b;
+-			for (b = 0; b < sizeof(unsigned long) * 8; b++) {
+-				if (!reiserfs_test_le_bit(b, cur)) {
+-					bi->free_count++;
+-					if (bi->first_zero_hint == 0)
+-						bi->first_zero_hint =
+-						    (((char *)cur -
+-						      bi->bh->b_data) << 3) + b;
+-				}
+-			}
+-		}
+-		cur++;
+-	}
+-
+-#ifdef CONFIG_REISERFS_CHECK
+-// This outputs a lot of unneded info on big FSes
+-//    reiserfs_warning ("bitmap loaded from block %d: %d free blocks",
+-//                    bi->bh->b_blocknr, bi->free_count);
+-#endif
+-}
+-
+-static int read_bitmaps(struct super_block *s)
+-{
+-	int i, bmap_nr;
+-
+-	SB_AP_BITMAP(s) =
+-	    vmalloc(sizeof(struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
+-	if (SB_AP_BITMAP(s) == 0)
+-		return 1;
+-	memset(SB_AP_BITMAP(s), 0,
+-	       sizeof(struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
+-	for (i = 0, bmap_nr =
+-	     REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize + 1;
+-	     i < SB_BMAP_NR(s); i++, bmap_nr = s->s_blocksize * 8 * i) {
+-		SB_AP_BITMAP(s)[i].bh = sb_getblk(s, bmap_nr);
+-		if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh))
+-			ll_rw_block(READ, 1, &SB_AP_BITMAP(s)[i].bh);
+-	}
+-	for (i = 0; i < SB_BMAP_NR(s); i++) {
+-		wait_on_buffer(SB_AP_BITMAP(s)[i].bh);
+-		if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) {
+-			reiserfs_warning(s, "sh-2029: reiserfs read_bitmaps: "
+-					 "bitmap block (#%lu) reading failed",
+-					 SB_AP_BITMAP(s)[i].bh->b_blocknr);
+-			for (i = 0; i < SB_BMAP_NR(s); i++)
+-				brelse(SB_AP_BITMAP(s)[i].bh);
+-			vfree(SB_AP_BITMAP(s));
+-			SB_AP_BITMAP(s) = NULL;
+-			return 1;
+-		}
+-		load_bitmap_info_data(s, SB_AP_BITMAP(s) + i);
+-	}
+-	return 0;
+-}
+-
+-static int read_old_bitmaps(struct super_block *s)
+-{
+-	int i;
+-	struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(s);
+-	int bmp1 = (REISERFS_OLD_DISK_OFFSET_IN_BYTES / s->s_blocksize) + 1;	/* first of bitmap blocks */
+-
+-	/* read true bitmap */
+-	SB_AP_BITMAP(s) =
+-	    vmalloc(sizeof(struct reiserfs_buffer_info *) * sb_bmap_nr(rs));
+-	if (SB_AP_BITMAP(s) == 0)
+-		return 1;
+-
+-	memset(SB_AP_BITMAP(s), 0,
+-	       sizeof(struct reiserfs_buffer_info *) * sb_bmap_nr(rs));
+-
+-	for (i = 0; i < sb_bmap_nr(rs); i++) {
+-		SB_AP_BITMAP(s)[i].bh = sb_bread(s, bmp1 + i);
+-		if (!SB_AP_BITMAP(s)[i].bh)
+-			return 1;
+-		load_bitmap_info_data(s, SB_AP_BITMAP(s) + i);
+-	}
+-
+-	return 0;
+-}
+-
+ static int read_super_block(struct super_block *s, int offset)
+ {
+ 	struct buffer_head *bh;
+@@ -1736,7 +1624,7 @@ static int reiserfs_fill_super(struct su
+ 	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)) {
++	if ((errval = reiserfs_init_bitmap_cache(s))) {
+ 		SWARN(silent, s,
+ 		      "jmacd-8: reiserfs_fill_super: unable to read bitmap");
+ 		goto error;
+diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
+index 9c63abf..7bc6bfb 100644
+--- a/include/linux/reiserfs_fs.h
++++ b/include/linux/reiserfs_fs.h
+@@ -2073,6 +2073,10 @@ void reiserfs_init_alloc_options(struct 
+  */
+ __le32 reiserfs_choose_packing(struct inode *dir);
+ 
++int reiserfs_init_bitmap_cache(struct super_block *sb);
++void reiserfs_free_bitmap_cache(struct super_block *sb);
++void reiserfs_cache_bitmap_metadata(struct super_block *sb, struct buffer_head *bh, struct reiserfs_bitmap_info *info);
++struct buffer_head *reiserfs_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);

Added: dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-fsync-barriers.patch
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-fsync-barriers.patch	Thu Nov  9 00:14:08 2006
@@ -0,0 +1,38 @@
+From git-commits-head-owner at vger.kernel.org Sat Sep 30 01:10:37 2006
+Date: Fri, 29 Sep 2006 17:02:12 GMT
+Message-Id: <200609291702.k8TH2C5A031438 at hera.kernel.org>
+From: Linux Kernel Mailing List <linux-kernel at vger.kernel.org>
+To: git-commits-head at vger.kernel.org
+Subject: [PATCH] reiserfs_fsync should only use barriers when they are enabled
+
+commit 25736b1c692d436508585d1d710912e6f76be2d8
+tree 8cf9a65b5a6d464ceabfe992b49a028a9a939198
+parent d4328b40af16bae62ff8f854060d33daad237093
+author Chris Mason <mason at suse.com> 1159520394 -0700
+committer Linus Torvalds <torvalds at g5.osdl.org> 1159546691 -0700
+
+[PATCH] reiserfs_fsync should only use barriers when they are enabled
+
+make sure that reiserfs_fsync only triggers barriers when mounted with -o
+barrier=flush
+
+Signed-off-by: Chris Mason <mason at suse.com>
+Signed-off-by: Andrew Morton <akpm at osdl.org>
+Signed-off-by: Linus Torvalds <torvalds at osdl.org>
+
+ fs/reiserfs/file.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
+index 1627edd..1cfbe85 100644
+--- a/fs/reiserfs/file.c
++++ b/fs/reiserfs/file.c
+@@ -130,7 +130,7 @@ static int reiserfs_sync_file(struct fil
+ 	reiserfs_write_lock(p_s_inode->i_sb);
+ 	barrier_done = reiserfs_commit_for_inode(p_s_inode);
+ 	reiserfs_write_unlock(p_s_inode->i_sb);
+-	if (barrier_done != 1)
++	if (barrier_done != 1 && reiserfs_barrier_flush(p_s_inode->i_sb))
+ 		blkdev_issue_flush(p_s_inode->i_sb->s_bdev, NULL);
+ 	if (barrier_done < 0)
+ 		return barrier_done;

Added: dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-gcc-flags.patch
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-gcc-flags.patch	Thu Nov  9 00:14:08 2006
@@ -0,0 +1,40 @@
+From git-commits-head-owner at vger.kernel.org Sat Sep 30 01:10:28 2006
+Date: Fri, 29 Sep 2006 17:01:39 GMT
+Message-Id: <200609291701.k8TH1dVv030631 at hera.kernel.org>
+From: Linux Kernel Mailing List <linux-kernel at vger.kernel.org>
+To: git-commits-head at vger.kernel.org
+Subject: [PATCH] use gcc -O1 in fs/reiserfs only for ancient gcc versions
+
+commit 42012cc4a2183c555a907eee32d7ce4fc7dc3a6a
+tree 90fbd712085050fac8f06544e3186736539cf2bc
+parent 4d24607bfaab3d02fd0d6e0ffc22f29c2bc8eb30
+author Olaf Hering <olh at suse.de> 1159520361 -0700
+committer Linus Torvalds <torvalds at g5.osdl.org> 1159546687 -0700
+
+[PATCH] use gcc -O1 in fs/reiserfs only for ancient gcc versions
+
+Only compile with -O1 if the (very old) compiler is broken.  We use
+reiserfs alot since SLES9 on ppc64, and it was never seen with gcc33.
+Assume the broken gcc is gcc-3.4 or older.
+
+Signed-off-by: Olaf Hering <olh at suse.de>
+Signed-off-by: Andrew Morton <akpm at osdl.org>
+Signed-off-by: Linus Torvalds <torvalds at osdl.org>
+
+ fs/reiserfs/Makefile |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/reiserfs/Makefile b/fs/reiserfs/Makefile
+index 3a59309..0eb7ac0 100644
+--- a/fs/reiserfs/Makefile
++++ b/fs/reiserfs/Makefile
+@@ -28,7 +28,7 @@ # and causing a panic. Since this behavi
+ # will work around it. If any other architecture displays this behavior,
+ # add it here.
+ ifeq ($(CONFIG_PPC32),y)
+-EXTRA_CFLAGS := -O1
++EXTRA_CFLAGS := $(call cc-ifversion, -lt, 0400, -O1)
+ endif
+ 
+ TAGS:
+

Added: dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-latency-journal_begin.patch
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/features/fs-reiserfs-latency-journal_begin.patch	Thu Nov  9 00:14:08 2006
@@ -0,0 +1,119 @@
+From git-commits-head-owner at vger.kernel.org Sat Sep 30 01:10:36 2006
+Date: Fri, 29 Sep 2006 17:02:13 GMT
+Message-Id: <200609291702.k8TH2D50031449 at hera.kernel.org>
+From: Linux Kernel Mailing List <linux-kernel at vger.kernel.org>
+To: git-commits-head at vger.kernel.org
+Subject: [PATCH] Fix reiserfs latencies caused by data=ordered
+
+commit a3172027148120b8f8797cbecc7d0a0b215736a1
+tree 9da7b5eafe136c8c5b9e76e9a9cccd70899df252
+parent 25736b1c692d436508585d1d710912e6f76be2d8
+author Chris Mason <mason at suse.com> 1159520396 -0700
+committer Linus Torvalds <torvalds at g5.osdl.org> 1159546691 -0700
+
+[PATCH] Fix reiserfs latencies caused by data=ordered
+
+ReiserFS does periodic cleanup of old transactions in order to limit the
+length of time a journal replay may take after a crash.  Sometimes, writing
+metadata from an old (already committed) transaction may require committing
+a newer transaction, which also requires writing all data=ordered buffers.
+This can cause very long stalls on journal_begin.
+
+This patch makes sure new transactions will not need to be committed before
+trying a periodic reclaim of an old transaction.  It is low risk because if
+a bad decision is made, it just means a slightly longer journal replay
+after a crash.
+
+Signed-off-by: Chris Mason <mason at suse.com>
+Signed-off-by: Andrew Morton <akpm at osdl.org>
+Signed-off-by: Linus Torvalds <torvalds at osdl.org>
+
+ fs/reiserfs/journal.c |   54 +++++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 43 insertions(+), 11 deletions(-)
+
+diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
+index 9b3672d..e6b5ccf 100644
+--- a/fs/reiserfs/journal.c
++++ b/fs/reiserfs/journal.c
+@@ -1186,6 +1186,21 @@ static struct reiserfs_journal_list *fin
+ 	return NULL;
+ }
+ 
++static int newer_jl_done(struct reiserfs_journal_cnode *cn)
++{
++	struct super_block *sb = cn->sb;
++	b_blocknr_t blocknr = cn->blocknr;
++
++	cn = cn->hprev;
++	while (cn) {
++		if (cn->sb == sb && cn->blocknr == blocknr && cn->jlist &&
++		    atomic_read(&cn->jlist->j_commit_left) != 0)
++				    return 0;
++		cn = cn->hprev;
++	}
++	return 1;
++}
++
+ static void remove_journal_hash(struct super_block *,
+ 				struct reiserfs_journal_cnode **,
+ 				struct reiserfs_journal_list *, unsigned long,
+@@ -1604,6 +1619,31 @@ #endif
+ 	return err;
+ }
+ 
++static int test_transaction(struct super_block *s,
++                            struct reiserfs_journal_list *jl)
++{
++	struct reiserfs_journal_cnode *cn;
++
++	if (jl->j_len == 0 || atomic_read(&jl->j_nonzerolen) == 0)
++		return 1;
++
++	cn = jl->j_realblock;
++	while (cn) {
++		/* if the blocknr == 0, this has been cleared from the hash,
++		 ** skip it
++		 */
++		if (cn->blocknr == 0) {
++			goto next;
++		}
++		if (cn->bh && !newer_jl_done(cn))
++			return 0;
++	      next:
++		cn = cn->next;
++		cond_resched();
++	}
++	return 0;
++}
++
+ static int write_one_transaction(struct super_block *s,
+ 				 struct reiserfs_journal_list *jl,
+ 				 struct buffer_chunk *chunk)
+@@ -3433,16 +3473,6 @@ static void flush_async_commits(void *p)
+ 		flush_commit_list(p_s_sb, jl, 1);
+ 	}
+ 	unlock_kernel();
+-	/*
+-	 * this is a little racey, but there's no harm in missing
+-	 * the filemap_fdata_write
+-	 */
+-	if (!atomic_read(&journal->j_async_throttle)
+-	    && !reiserfs_is_journal_aborted(journal)) {
+-		atomic_inc(&journal->j_async_throttle);
+-		filemap_fdatawrite(p_s_sb->s_bdev->bd_inode->i_mapping);
+-		atomic_dec(&journal->j_async_throttle);
+-	}
+ }
+ 
+ /*
+@@ -3844,7 +3874,9 @@ static void flush_old_journal_lists(stru
+ 		entry = journal->j_journal_list.next;
+ 		jl = JOURNAL_LIST_ENTRY(entry);
+ 		/* this check should always be run, to send old lists to disk */
+-		if (jl->j_timestamp < (now - (JOURNAL_MAX_TRANS_AGE * 4))) {
++		if (jl->j_timestamp < (now - (JOURNAL_MAX_TRANS_AGE * 4)) &&
++		    atomic_read(&jl->j_commit_left) == 0 &&
++		    test_transaction(s, jl)) {
+ 			flush_used_journal_lists(s, jl);
+ 		} else {
+ 			break;

Added: dists/trunk/linux-2.6/debian/patches/series/6
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/series/6	Thu Nov  9 00:14:08 2006
@@ -0,0 +1,7 @@
++ features/fs-reiserfs-gcc-flags.patch
++ features/fs-reiserfs-fsync-barriers.patch
++ features/fs-reiserfs-latency-journal_begin.patch
++ features/fs-reiserfs-bitmap-block-optimization.patch
++ features/fs-reiserfs-bitmap-block-cleanup.patch
++ features/fs-reiserfs-bitmap-reorganize.patch
++ features/fs-reiserfs-bitmap-on-demand-loading.patch



More information about the Kernel-svn-changes mailing list