aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>2013-12-04 01:31:57 +0900
committerDaniel Phillips <daniel@tux3.org>2013-12-04 01:31:57 +0900
commit4f4d78e2da786be67e2254406f3485ef914210d0 (patch)
tree1ac1a553dfe575d50375c36bce94ce9ca9a6f0b4
parentdde62b7b18777292cde2f1e15651b82cc6cf5a42 (diff)
downloadlinux-tux3-4f4d78e2da786be67e2254406f3485ef914210d0.tar.gz
tux3: Add sb parameter to defer_bfree()
To add sanity check for defer_bfree(), this adds "sb" parameter to defer_bfree(). With this check, we can notify the bug early, not after commit. Already, some bugs found on tests/* with this. Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
-rw-r--r--fs/tux3/btree.c8
-rw-r--r--fs/tux3/dleaf.c4
-rw-r--r--fs/tux3/dleaf2.c2
-rw-r--r--fs/tux3/filemap.c4
-rw-r--r--fs/tux3/log.c8
-rw-r--r--fs/tux3/replay.c6
-rw-r--r--fs/tux3/tux3.h3
7 files changed, 20 insertions, 15 deletions
diff --git a/fs/tux3/btree.c b/fs/tux3/btree.c
index e1e58f822a6cd7..a9b93fa534299e 100644
--- a/fs/tux3/btree.c
+++ b/fs/tux3/btree.c
@@ -601,12 +601,12 @@ int cursor_redirect(struct cursor *cursor)
/* This is leaf buffer */
mark_buffer_dirty_atomic(clone);
log_leaf_redirect(sb, oldblock, newblock);
- defer_bfree(&sb->defree, oldblock, 1);
+ defer_bfree(sb, &sb->defree, oldblock, 1);
} else {
/* This is bnode buffer */
mark_buffer_unify_atomic(clone);
log_bnode_redirect(sb, oldblock, newblock);
- defer_bfree(&sb->deunify, oldblock, 1);
+ defer_bfree(sb, &sb->deunify, oldblock, 1);
}
trace("update parent");
@@ -1274,7 +1274,7 @@ int free_empty_btree(struct btree *btree)
assert(ops->leaf_can_free(btree, bufdata(leafbuf)));
blockput_free(sb, leafbuf);
} else {
- defer_bfree(&sb->defree, leaf, 1);
+ defer_bfree(sb, &sb->defree, leaf, 1);
log_bfree(sb, leaf, 1);
if (leafbuf) {
assert(ops->leaf_can_free(btree, bufdata(leafbuf)));
@@ -1292,7 +1292,7 @@ int free_empty_btree(struct btree *btree)
log_bnode_free(sb, bufindex(rootbuf));
blockput_free_unify(sb, rootbuf);
} else {
- defer_bfree(&sb->deunify, bufindex(rootbuf), 1);
+ defer_bfree(sb, &sb->deunify, bufindex(rootbuf), 1);
log_bfree_on_unify(sb, bufindex(rootbuf), 1);
blockput(rootbuf);
}
diff --git a/fs/tux3/dleaf.c b/fs/tux3/dleaf.c
index 34788ae0ad361f..48eb1b9411580d 100644
--- a/fs/tux3/dleaf.c
+++ b/fs/tux3/dleaf.c
@@ -853,7 +853,7 @@ static int dleaf_chop(struct btree *btree, tuxkey_t start, u64 len, void *vleaf)
block_t block = dwalk_block(&walk);
unsigned count = start - dwalk_index(&walk);
- defer_bfree(&sb->defree, block + count, dwalk_count(&walk) - count);
+ defer_bfree(sb, &sb->defree, block + count, dwalk_count(&walk) - count);
log_bfree(sb, block + count, dwalk_count(&walk) - count);
dwalk_update(&walk, make_extent(block, count));
@@ -862,7 +862,7 @@ static int dleaf_chop(struct btree *btree, tuxkey_t start, u64 len, void *vleaf)
}
struct dwalk rewind = walk;
do {
- defer_bfree(&sb->defree, dwalk_block(&walk), dwalk_count(&walk));
+ defer_bfree(sb, &sb->defree, dwalk_block(&walk), dwalk_count(&walk));
log_bfree(sb, dwalk_block(&walk), dwalk_count(&walk));
} while (dwalk_next(&walk));
dwalk_chop(&rewind);
diff --git a/fs/tux3/dleaf2.c b/fs/tux3/dleaf2.c
index e90e4ccb5715ca..b277cf42b8571b 100644
--- a/fs/tux3/dleaf2.c
+++ b/fs/tux3/dleaf2.c
@@ -339,7 +339,7 @@ static int dleaf2_chop(struct btree *btree, tuxkey_t start, u64 len, void *leaf)
get_extent(dex, &ex);
count = ex.logical - start;
if (block && count) {
- defer_bfree(&sb->defree, block, count);
+ defer_bfree(sb, &sb->defree, block, count);
log_bfree(sb, block, count);
}
diff --git a/fs/tux3/filemap.c b/fs/tux3/filemap.c
index 6b3b6b03b271f9..0c7930f2d3ba32 100644
--- a/fs/tux3/filemap.c
+++ b/fs/tux3/filemap.c
@@ -75,10 +75,10 @@ static int map_bfree(struct inode *inode, block_t block, unsigned count)
struct sb *sb = tux_sb(inode->i_sb);
if (inode == sb->bitmap) {
log_bfree_on_unify(sb, block, count);
- defer_bfree(&sb->deunify, block, count);
+ defer_bfree(sb, &sb->deunify, block, count);
} else {
log_bfree(sb, block, count);
- defer_bfree(&sb->defree, block, count);
+ defer_bfree(sb, &sb->defree, block, count);
}
return 0;
}
diff --git a/fs/tux3/log.c b/fs/tux3/log.c
index 8932c53b4f1097..d60ccb40b1f9de 100644
--- a/fs/tux3/log.c
+++ b/fs/tux3/log.c
@@ -214,7 +214,7 @@ int tux3_logmap_io(int rw, struct bufvec *bufvec)
* We can obsolete the log blocks after next unify
* by LOG_BFREE_RELOG.
*/
- defer_bfree(&sb->deunify, seg.block, seg.count);
+ defer_bfree(sb, &sb->deunify, seg.block, seg.count);
/* Add count of log on this delta to unify logcount */
be32_add_cpu(&sb->super.logcount, seg.count);
@@ -579,10 +579,14 @@ int stash_walk(struct sb *sb, struct stash *stash, unstash_t actor)
/* Deferred free blocks list */
-int defer_bfree(struct stash *defree, block_t block, unsigned count)
+int defer_bfree(struct sb *sb, struct stash *defree,
+ block_t block, unsigned count)
{
static const unsigned limit = ULLONG_MAX >> 48;
+ assert(count > 0);
+ assert(block + count <= sb->volblocks);
+
/*
* count field of stash is 16bits. So, this separates to
* multiple records to avoid overflow.
diff --git a/fs/tux3/replay.c b/fs/tux3/replay.c
index d0ccc5f6e2fd25..09939902bfd2e1 100644
--- a/fs/tux3/replay.c
+++ b/fs/tux3/replay.c
@@ -348,7 +348,7 @@ static int replay_log_stage2(struct replay *rp, struct buffer_head *logbuf)
if (err)
return err;
/* Mark log block as deunify block */
- defer_bfree(&sb->deunify, blocknr, 1);
+ defer_bfree(sb, &sb->deunify, blocknr, 1);
/* If log is before latest unify, those were already applied to FS. */
if (bufindex(logbuf) < rp->unify_index) {
@@ -377,7 +377,7 @@ static int replay_log_stage2(struct replay *rp, struct buffer_head *logbuf)
if (code == LOG_BALLOC)
err = replay_update_bitmap(rp, block, count, 1);
else if (code == LOG_BFREE_ON_UNIFY)
- defer_bfree(&sb->deunify, block, count);
+ defer_bfree(sb, &sb->deunify, block, count);
else
err = replay_update_bitmap(rp, block, count, 0);
if (err)
@@ -401,7 +401,7 @@ static int replay_log_stage2(struct replay *rp, struct buffer_head *logbuf)
return err;
} else {
/* newblock is not flushing yet */
- defer_bfree(&sb->deunify, oldblock, 1);
+ defer_bfree(sb, &sb->deunify, oldblock, 1);
}
break;
}
diff --git a/fs/tux3/tux3.h b/fs/tux3/tux3.h
index fbc3b899458025..2519115c74134b 100644
--- a/fs/tux3/tux3.h
+++ b/fs/tux3/tux3.h
@@ -865,7 +865,8 @@ void stash_init(struct stash *stash);
int stash_value(struct stash *stash, u64 value);
int unstash(struct sb *sb, struct stash *defree, unstash_t actor);
int stash_walk(struct sb *sb, struct stash *stash, unstash_t actor);
-int defer_bfree(struct stash *defree, block_t block, unsigned count);
+int defer_bfree(struct sb *sb, struct stash *defree,
+ block_t block, unsigned count);
void destroy_defer_bfree(struct stash *defree);
/* orphan.c */