summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Peterson <rpeterso@redhat.com>2007-08-09 01:52:09 +0400
committerSteven Whitehouse <swhiteho@redhat.com>2007-10-10 11:55:10 +0400
commit5f3eae7546093d845ca8ada1b95714202a136a1a (patch)
treec5b45d1a313f8a7357e7ab25954356904b68c010
parent8fbbfd214c853102b614f4705c1904ed14f5a808 (diff)
downloadlinux-5f3eae7546093d845ca8ada1b95714202a136a1a.tar.xz
[GFS2] invalid metadata block - REVISED
This is for bugzilla bug #248176: GFS2: invalid metadata block Patches 1 thru 3 were accepted upstream, but there were problems with 4 and 5. Those issues have been resolved and now the recovery tests are passing without errors. This code has gone through 41 * 3 successful gfs2 recovery tests before it hit an unrelated (openais) problem. This is a complete rewrite of patch 4 for bug #248176. Part of the problem was that inodes were being recycled before their buffers were flushed to the journal logs. Another problem was that the clone bitmaps were being searched for deleted inodes to recycle, but only the "real" bitmaps should be searched for that purpose. Signed-off-by: Bob Peterson <rpeterso@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r--fs/gfs2/rgrp.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index b93ac45b88bb..2d7f7ea0c9a8 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -865,12 +865,15 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked)
struct inode *inode;
u32 goal = 0, block;
u64 no_addr;
+ struct gfs2_sbd *sdp = rgd->rd_sbd;
for(;;) {
if (goal >= rgd->rd_data)
break;
+ down_write(&sdp->sd_log_flush_lock);
block = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED,
GFS2_BLKST_UNLINKED);
+ up_write(&sdp->sd_log_flush_lock);
if (block == BFITNOENT)
break;
/* rgblk_search can return a block < goal, so we need to
@@ -1295,7 +1298,9 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
allocatable block anywhere else, we want to be able wrap around and
search in the first part of our first-searched bit block. */
for (x = 0; x <= length; x++) {
- if (bi->bi_clone)
+ /* The GFS2_BLKST_UNLINKED state doesn't apply to the clone
+ bitmaps, so we must search the originals for that. */
+ if (old_state != GFS2_BLKST_UNLINKED && bi->bi_clone)
blk = gfs2_bitfit(rgd, bi->bi_clone + bi->bi_offset,
bi->bi_len, goal, old_state);
else