From 2710b3222fc9feeec55ee36e76bbb7a410485593 Mon Sep 17 00:00:00 2001 From: Liu Aleaxander Date: Sun, 30 May 2010 16:13:38 +0800 Subject: [PATCH] iallo.c implemented Signed-off-by: Liu Aleaxander --- balloc.c | 31 ++++----------------- ialloc.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tfs.h | 16 ++++++++++- utils.c | 18 ++++++++++++ 4 files changed, 135 insertions(+), 26 deletions(-) create mode 100644 ialloc.c diff --git a/balloc.c b/balloc.c index 95f5ca7..903a790 100644 --- a/balloc.c +++ b/balloc.c @@ -3,7 +3,7 @@ #include "tfs.h" -void * tfs_read_block_bitmap(struct tfs_sb_info *sbi) +static void * tfs_read_block_bitmap(struct tfs_sb_info *sbi) { char *buf = malloc(sbi->s_block_size); @@ -13,9 +13,9 @@ void * tfs_read_block_bitmap(struct tfs_sb_info *sbi) } /* - * Free a block, return -1 if failed, or return the block just freed + * Free a block, return -1 if failed, or return 0 */ -uint32_t tfs_free_block(struct tfs_sb_info *sbi, uint32_t block) +int tfs_free_block(struct tfs_sb_info *sbi, uint32_t block) { char *bitmap = tfs_read_block_bitmap(sbi); @@ -30,32 +30,13 @@ uint32_t tfs_free_block(struct tfs_sb_info *sbi, uint32_t block) return block; } -static int find_first_zero(struct tfs_sb_info *sbi, void *buf) -{ - uint32_t *p = (uint32_t *)buf; - uint32_t *end = (uint32_t *)(buf + sbi->s_block_size); - uint32_t block = 0; - int i; - - while (*p == 0xffffffff && p < end) { - p++; - block += 32; - } - if (p >= end) - return -1; - - for (i = 0; i < 32; i++) - if (test_bit(p, i) == 0) - return block + i; -} - int tfs_alloc_block(struct tfs_sb_info *sbi, uint32_t block) { char *bitmap = tfs_read_block_bitmap(sbi); /* try the target first */ if (test_bit(bitmap, block) != 0) - block = find_first_zero(sbi, bitmap); + block = find_first_zero(bitmap, bitmap + sbi->s_block_size); if (block != -1) { set_bit(bitmap, block); tfs_bwrite(sbi, sbi->s_block_bitmap, bitmap); @@ -95,14 +76,14 @@ int main(int argc, char *argv[]) block = atoi(blocks[i]); printf("trying to alloc block %u\n", block); block = tfs_alloc_block(sbi, block); - printf("block number: %d allocated\n"); + printf("block number: %u allocated\n", block); } } else if (strcmp(command, "free") == 0) { for (i = 0; i < count; i++) { block = atoi(blocks[i]); printf("trying to free block %u\n", block); block = tfs_free_block(sbi, block); - printf("block number: %d freed\n"); + printf("block number: %u freed\n", block); } } else { printf("Unknown command!\n"); diff --git a/ialloc.c b/ialloc.c new file mode 100644 index 0000000..a3c82c5 --- /dev/null +++ b/ialloc.c @@ -0,0 +1,96 @@ +#include +#include + +#include "tfs.h" + + +static void * tfs_read_inode_bitmap(struct tfs_sb_info *sbi) +{ + char *buf = malloc(sbi->s_block_size); + + tfs_bread(sbi, sbi->s_inode_bitmap, buf); + + return buf; +} + +/* + * free an inode, return -1 if failed, or return 9 + */ +int tfs_free_inode(struct tfs_sb_info *sbi, uint32_t inr) +{ + char *bitmap = tfs_read_inode_bitmap(sbi); + + /* inode number count from 1 */ + if (clear_bit(bitmap, inr - 1) == 0) { + printf("ERROR: trying to free an unallocated inode!\n"); + free(bitmap); + return -1; + } + + tfs_bwrite(sbi, sbi->s_inode_bitmap, bitmap); + free(bitmap); + return 0; +} + +uint32_t tfs_alloc_inode(struct tfs_sb_info *sbi, uint32_t inr) +{ + char *bitmap = tfs_read_inode_bitmap(sbi); + + /* try the target first */ + if (test_bit(bitmap, inr - 1) != 0) + inr = find_first_zero(bitmap, bitmap + sbi->s_block_size) + 1; + if (inr != -1) { + set_bit(bitmap, inr - 1); + tfs_bwrite(sbi, sbi->s_inode_bitmap, bitmap); + } + + free(bitmap); + return inr; +} + +#if 1 /* the deubg part */ +#include +int main(int argc, char *argv[]) +{ + int i; + int inr; + struct tfs_sb_info *sbi; + char *fs = argv[1]; + char *command = argv[2]; + char **inodes = argv + 3; + int count = argc - 3; + + if (argc < 4) { + printf("Usage: ialloc tfs.img command inodes...\n"); + printf(" alloc, to alloc inodes\n"); + printf(" feee, to free inodes\n"); + return 1; + } + + sbi = tfs_mount_by_fsname(fs); + if (!sbi) { + printf("tfs mount failed!\n"); + return 1; + } + + if (strcmp(command, "alloc") == 0) { + for (i = 0; i < count; i++) { + inr = atoi(inodes[i]); + printf("trying to alloc inode %u\n", inr); + inr = tfs_alloc_inode(sbi, inr); + printf("inode number: %u allocated\n", inr); + } + } else if (strcmp(command, "free") == 0) { + for (i = 0; i < count; i++) { + inr = atoi(inodes[i]); + printf("trying to free inode %u\n", inr); + inr = tfs_free_inode(sbi, inr); + printf("inode number: %d freed\n", inr); + } + } else { + printf("Unknown command!\n"); + } + + return 0; +} +#endif diff --git a/tfs.h b/tfs.h index 007e52a..09fb5f9 100644 --- a/tfs.h +++ b/tfs.h @@ -19,7 +19,20 @@ struct tfs_inode { uint32_t i_reserved[1]; }; - +/* + * The inode structure in memory, including the detail file information + */ +struct inode { + int i_mode; /* FILE or DIR */ + uint32_t i_size; + uint32_t i_ino; /* Inode number */ + uint32_t i_atime; /* Access time */ + uint32_t i_mtime; /* Modify time */ + uint32_t i_ctime; /* Create time */ + uint32_t i_dtime; /* Delete time */ + uint32_t * i_data; /* The block address array where the file stores */ + uint32_t i_flags; +}; /* The max lenght of each file name */ #define TFS_NAME_LEN 28 @@ -74,6 +87,7 @@ struct tfs_sb_info { extern int set_bit(void *, unsigned int); extern int clear_bit(void *, unsigned int); extern int test_bit(const void *, unsigned int); +extern uint32_t find_first_zero(void *, void *); extern int write_sector(uint32_t, void *, int); extern int read_sector(uint32_t, void *, int); diff --git a/utils.c b/utils.c index ddfa1ed..1304d10 100644 --- a/utils.c +++ b/utils.c @@ -64,6 +64,24 @@ int test_bit(const void * addr, unsigned int nr) return (mask & *ADDR); } +uint32_t find_first_zero(void *buf, void *end) +{ + uint32_t *p = (uint32_t *)buf; + uint32_t block = 0; + int i; + + while (*p == 0xffffffff && (void *)p < end) { + p++; + block += 32; + } + if ((void *)p >= end) + return -1; + + for (i = 0; i < 32; i++) + if (test_bit(p, i) == 0) + return block + i; +} + int read_sector(uint32_t sector, void *buf, int counts) { if (lseek(fd, sector << 9, SEEK_SET) < 0) { -- 2.11.4.GIT