diff options
author | OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> | 2014-03-22 01:10:33 +0900 |
---|---|---|
committer | Daniel Phillips <daniel@tux3.org> | 2014-03-22 01:10:33 +0900 |
commit | ae8c2c541b3c8ac9b7fefc7fd6fc9c2051392b30 (patch) | |
tree | b8f62afbca2763e9cc35dcc8fb68a7570fe8f05e | |
parent | a41a72645ffa366fba9cce5354a8933e6718a31a (diff) | |
download | linux-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.c | 2 | ||||
-rw-r--r-- | fs/tux3/replay.c | 19 |
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); |