[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