aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>2014-03-22 01:10:33 +0900
committerDaniel Phillips <daniel@tux3.org>2014-03-22 01:10:33 +0900
commitae8c2c541b3c8ac9b7fefc7fd6fc9c2051392b30 (patch)
treeb8f62afbca2763e9cc35dcc8fb68a7570fe8f05e
parenta41a72645ffa366fba9cce5354a8933e6718a31a (diff)
downloadlinux-tux3-ae8c2c541b3c8ac9b7fefc7fd6fc9c2051392b30.tar.gz
tux3: Fix order of LOG_BNODE_FREE dirty cancel in replay
If log was following order, LOG_BNODE_FREE(block-A) LOG_BNODE_REDIRECT(old, block-A) dirty state cancel of LOG_BNODE_FREE must be before LOG_BNODE_REDIRECT replay. But, current code is canceling dirty state in stage2. So, regardless of LOG_BNODE_FREE order, LOG_BNODE_FREE cancels dirty state in LOG_BNODE_REDIRECT of stage1 This moves the dirty cancel to stage1 to respect order of log records. Also, LOG_BNODE_MERGE has to be fixed. Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
-rw-r--r--fs/tux3/btree.c2
-rw-r--r--fs/tux3/replay.c19
2 files changed, 10 insertions, 11 deletions
diff --git a/fs/tux3/btree.c b/fs/tux3/btree.c
index d07766fce4289e..3b4ece31dc528c 100644
--- a/fs/tux3/btree.c
+++ b/fs/tux3/btree.c
@@ -1504,7 +1504,7 @@ int replay_bnode_merge(struct replay *rp, block_t src, block_t dst)
blockput(dstbuf);
error_put_srcbuf:
- blockput(srcbuf);
+ blockput_free_unify(sb, srcbuf);
error:
return err;
}
diff --git a/fs/tux3/replay.c b/fs/tux3/replay.c
index 09939902bfd2e1..dce101a00e2d9d 100644
--- a/fs/tux3/replay.c
+++ b/fs/tux3/replay.c
@@ -298,6 +298,14 @@ static int replay_log_stage1(struct replay *rp, struct buffer_head *logbuf)
return err;
break;
}
+ case LOG_BNODE_FREE:
+ {
+ u64 block;
+ data = decode48(data, &block);
+ trace("%s: block %Lx", log_name[code], block);
+ blockput_free_unify(sb, vol_find_get_block(sb, block));
+ break;
+ }
case LOG_FREEBLOCKS:
{
u64 freeblocks;
@@ -313,7 +321,6 @@ static int replay_log_stage1(struct replay *rp, struct buffer_head *logbuf)
case LOG_BFREE_RELOG:
case LOG_LEAF_REDIRECT:
case LOG_LEAF_FREE:
- case LOG_BNODE_FREE:
case LOG_ORPHAN_ADD:
case LOG_ORPHAN_DEL:
case LOG_UNIFY:
@@ -414,12 +421,6 @@ static int replay_log_stage2(struct replay *rp, struct buffer_head *logbuf)
err = replay_update_bitmap(rp, block, 1, 0);
if (err)
return err;
-
- if (code == LOG_BNODE_FREE) {
- struct buffer_head *buffer =
- vol_find_get_block(sb, block);
- blockput_free_unify(sb, buffer);
- }
break;
}
case LOG_BNODE_ROOT:
@@ -463,8 +464,6 @@ static int replay_log_stage2(struct replay *rp, struct buffer_head *logbuf)
err = replay_update_bitmap(rp, src, 1, 0);
if (err)
return err;
-
- blockput_free_unify(sb, vol_find_get_block(sb, src));
break;
}
case LOG_ORPHAN_ADD:
@@ -522,7 +521,7 @@ static int replay_logblocks(struct replay *rp, replay_log_t replay_log_func)
return 0;
}
-/* Replay physical update like bnode, etc. */
+/* Replay physical update like bnode, buffer state, etc. */
struct replay *replay_stage1(struct sb *sb)
{
struct replay *rp = replay_prepare(sb);