diff options
author | OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> | 2014-01-31 02:52:43 +0900 |
---|---|---|
committer | Daniel Phillips <daniel@tux3.org> | 2014-01-31 02:52:43 +0900 |
commit | 1e78fd478ab812419cd4e61ad24d390124599532 (patch) | |
tree | a787523770c9af2f16b9c90b40e1cc5d4386a05f | |
parent | a8d57f9f3fd6c96750e96d10691f18cd4af16b80 (diff) | |
download | linux-tux3-1e78fd478ab812419cd4e61ad24d390124599532.tar.gz |
tux3: bitmap-modify-consolidate
Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
-rw-r--r-- | fs/tux3/balloc.c | 65 |
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; |