diff options
author | OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> | 2013-12-04 01:31:57 +0900 |
---|---|---|
committer | Daniel Phillips <daniel@tux3.org> | 2013-12-04 01:31:57 +0900 |
commit | 4f4d78e2da786be67e2254406f3485ef914210d0 (patch) | |
tree | 1ac1a553dfe575d50375c36bce94ce9ca9a6f0b4 | |
parent | dde62b7b18777292cde2f1e15651b82cc6cf5a42 (diff) | |
download | linux-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.c | 8 | ||||
-rw-r--r-- | fs/tux3/dleaf.c | 4 | ||||
-rw-r--r-- | fs/tux3/dleaf2.c | 2 | ||||
-rw-r--r-- | fs/tux3/filemap.c | 4 | ||||
-rw-r--r-- | fs/tux3/log.c | 8 | ||||
-rw-r--r-- | fs/tux3/replay.c | 6 | ||||
-rw-r--r-- | fs/tux3/tux3.h | 3 |
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 */ |