aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>2014-01-31 02:52:43 +0900
committerDaniel Phillips <daniel@tux3.org>2014-01-31 02:52:43 +0900
commit1e78fd478ab812419cd4e61ad24d390124599532 (patch)
treea787523770c9af2f16b9c90b40e1cc5d4386a05f
parenta8d57f9f3fd6c96750e96d10691f18cd4af16b80 (diff)
downloadlinux-tux3-1e78fd478ab812419cd4e61ad24d390124599532.tar.gz
tux3: bitmap-modify-consolidate
Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
-rw-r--r--fs/tux3/balloc.c65
1 files changed, 15 insertions, 50 deletions
diff --git a/fs/tux3/balloc.c b/fs/tux3/balloc.c
index bb713458450194..c5148086a7aedf 100644
--- a/fs/tux3/balloc.c
+++ b/fs/tux3/balloc.c
@@ -148,59 +148,13 @@ static int bitmap_modify_bits(struct sb *sb, struct buffer_head *buffer,
}
/*
- * Modify bits on multiple blocks. Caller may want to check range is
- * excepted state.
- *
- * FIXME: If error happened on middle of blocks, modified bits and
- * ->freeblocks are not restored to original. What to do?
- */
-static int bitmap_modify(struct sb *sb, block_t start, unsigned blocks, int set)
-{
- struct inode *bitmap = sb->bitmap;
- unsigned mapshift = sb->blockbits + 3;
- unsigned mapsize = 1 << mapshift;
- unsigned mapmask = mapsize - 1;
- unsigned mapoffset = start & mapmask;
- block_t mapblock, mapblocks = (start + blocks + mapmask) >> mapshift;
-
- assert(blocks > 0);
- assert(start + blocks <= sb->volblocks);
-
- for (mapblock = start >> mapshift; mapblock < mapblocks; mapblock++) {
- struct buffer_head *buffer;
- unsigned len;
- int err;
-
- buffer = blockread(mapping(bitmap), mapblock);
- if (!buffer) {
- tux3_err(sb, "block read failed");
- // !!! error return sucks here
- return -EIO;
- }
-
- len = min(mapsize - mapoffset, blocks);
- err = bitmap_modify_bits(sb, buffer, mapoffset, len, set);
- if (err) {
- blockput(buffer);
- /* FIXME: error handling */
- return err;
- }
-
- mapoffset = 0;
- blocks -= len;
- }
-
- return 0;
-}
-
-/*
* If bits on multiple blocks is excepted state, modify bits.
*
* FIXME: If error happened on middle of blocks, modified bits and
* ->freeblocks are not restored to original. What to do?
*/
-static int bitmap_test_and_modify(struct sb *sb, block_t start, unsigned blocks,
- int set)
+static int __bitmap_modify(struct sb *sb, block_t start, unsigned blocks,
+ int set, int (*test)(u8 *, unsigned, unsigned))
{
struct inode *bitmap = sb->bitmap;
unsigned mapshift = sb->blockbits + 3;
@@ -208,7 +162,6 @@ static int bitmap_test_and_modify(struct sb *sb, block_t start, unsigned blocks,
unsigned mapmask = mapsize - 1;
unsigned mapoffset = start & mapmask;
block_t mapblock, mapblocks = (start + blocks + mapmask) >> mapshift;
- int (*test)(u8 *, unsigned, unsigned) = set ? all_clear : all_set;
assert(blocks > 0);
assert(start + blocks <= sb->volblocks);
@@ -226,7 +179,7 @@ static int bitmap_test_and_modify(struct sb *sb, block_t start, unsigned blocks,
}
len = min(mapsize - mapoffset, blocks);
- if (!test(bufdata(buffer), mapoffset, len)) {
+ if (test && !test(bufdata(buffer), mapoffset, len)) {
blockput(buffer);
tux3_fs_error(sb, "%s: start 0x%Lx, count %x",
@@ -250,6 +203,18 @@ static int bitmap_test_and_modify(struct sb *sb, block_t start, unsigned blocks,
return 0;
}
+static int bitmap_modify(struct sb *sb, block_t start, unsigned blocks, int set)
+{
+ return __bitmap_modify(sb, start, blocks, set, NULL);
+}
+
+static int bitmap_test_and_modify(struct sb *sb, block_t start, unsigned blocks,
+ int set)
+{
+ int (*test)(u8 *, unsigned, unsigned) = set ? all_clear : all_set;
+ return __bitmap_modify(sb, start, blocks, set, test);
+}
+
static inline int mergable(struct block_segment *seg, block_t block)
{
return seg->block + seg->count == block;