# HG changeset patch # User John Tsiombikas # Date 1323594750 -7200 # Node ID b3351d018ac6373c4b288978b889702defbb1936 # Parent 083849df660b14f40f59c9064637da9abf3f4ae3 read/write superblock, get/put inode diff -r 083849df660b -r b3351d018ac6 include/kdef.h --- a/include/kdef.h Sun Dec 11 10:17:58 2011 +0200 +++ b/include/kdef.h Sun Dec 11 11:12:30 2011 +0200 @@ -29,14 +29,17 @@ /* --- defines for errno.h */ #if defined(KERNEL) || defined(KDEF_ERRNO_H) -#define EAGAIN 1 -#define EINVAL 2 -#define ECHILD 3 -#define EBUSY 4 -#define ENOMEM 5 -#define EIO 6 +#define EFOO 1 /* I just like to return -1 some times :) */ -#define EBUG 127 /* error: feature not implemented yet */ +#define EAGAIN 2 +#define EINVAL 3 +#define ECHILD 4 +#define EBUSY 5 +#define ENOMEM 6 +#define EIO 7 +#define ENOENT 8 + +#define EBUG 127 /* for missing features and known bugs */ #endif /* errno.h */ diff -r 083849df660b -r b3351d018ac6 src/fs.c --- a/src/fs.c Sun Dec 11 10:17:58 2011 +0200 +++ b/src/fs.c Sun Dec 11 11:12:30 2011 +0200 @@ -4,47 +4,52 @@ */ #include #include +#include #include +#include #include "fs.h" #include "bdev.h" int openfs(struct filesys *fs, dev_t dev); -static int read_superblock(struct block_device *bdev, struct superblock *sb); - +static int read_superblock(struct filesys *fs); +static int write_superblock(struct filesys *fs); +static int get_inode(struct filesys *fs, int ino, struct inode *inode); +static int put_inode(struct filesys *fs, struct inode *inode); int openfs(struct filesys *fs, dev_t dev) { int res; struct block_device *bdev; - struct superblock *sb = 0; + + assert(BLKSZ % sizeof(struct inode) == 0); if(!(bdev = blk_open(dev))) { return -ENOENT; } + fs->bdev = bdev; /* read the superblock */ - if(!(sb = malloc(BLKSZ))) { + if(!(fs->sb = malloc(BLKSZ))) { res = -ENOMEM; goto done; } - if((res = read_superblock(bdev, sb)) != 0) { + if((res = read_superblock(fs)) != 0) { goto done; } - - done: blk_close(bdev); - free(sb); return res; } -static int read_superblock(struct block_device *bdev, struct superblock *sb) +static int read_superblock(struct filesys *fs) { + struct superblock *sb = fs->sb; + /* read superblock and verify */ - if(blk_read(bdev, 1, 1, sb) == -1) { + if(blk_read(fs->bdev, 1, 1, sb) == -1) { printf("failed to read superblock\n"); return -EIO; } @@ -65,7 +70,7 @@ if(!(sb->ibm = malloc(sb->ibm_count * sb->blksize))) { return -ENOMEM; } - if(blk_read(bdev, sb->ibm_start, sb->ibm_count, sb->ibm) == -1) { + if(blk_read(fs->bdev, sb->ibm_start, sb->ibm_count, sb->ibm) == -1) { printf("failed to read inode bitmap\n"); free(sb->ibm); return -EIO; @@ -74,12 +79,80 @@ free(sb->ibm); return -ENOMEM; } - if(blk_read(bdev, sb->bm_start, sb->bm_count, sb->bm) == -1) { + if(blk_read(fs->bdev, sb->bm_start, sb->bm_count, sb->bm) == -1) { printf("failed to read block bitmap\n"); free(sb->ibm); free(sb->bm); return -EIO; } + /* read the root inode */ + if(!(sb->root = malloc(sizeof *sb->root))) { + free(sb->ibm); + free(sb->bm); + return -ENOMEM; + } + if(get_inode(fs, sb->root_ino, sb->root) == -1) { + printf("failed to read root inode\n"); + return -1; + } + return 0; } + +static int write_superblock(struct filesys *fs) +{ + struct superblock *sb = fs->sb; + + /* write back any changes in the root inode */ + if(put_inode(fs, sb->root) == -1) { + return -1; + } + /* write back the block bitmap */ + if(blk_write(fs->bdev, sb->bm_start, sb->bm_count, sb->bm) == -1) { + return -1; + } + /* write back the inode bitmap */ + if(blk_write(fs->bdev, sb->ibm_start, sb->ibm_count, sb->ibm) == -1) { + return -1; + } + return 0; +} + +/* number of inodes in a block */ +#define BLK_INODES (BLKSZ / sizeof(struct inode)) + +/* copy the requested inode from the disk, into the buffer passed in the last arg */ +static int get_inode(struct filesys *fs, int ino, struct inode *inode) +{ + struct inode *buf = malloc(BLKSZ); + assert(buf); + + if(blk_read(fs->bdev, fs->sb->itbl_start + ino / BLK_INODES, 1, buf) == -1) { + free(buf); + return -1; + } + memcpy(inode, buf + ino % BLK_INODES, sizeof *inode); + free(buf); + return 0; +} + +/* write the inode to the disk */ +static int put_inode(struct filesys *fs, struct inode *inode) +{ + struct inode *buf = malloc(BLKSZ); + assert(buf); + + if(blk_read(fs->bdev, fs->sb->itbl_start + inode->ino / BLK_INODES, 1, buf) == -1) { + free(buf); + return -1; + } + memcpy(buf + inode->ino % BLK_INODES, inode, sizeof *inode); + + if(blk_write(fs->bdev, fs->sb->itbl_start + inode->ino / BLK_INODES, 1, buf) == -1) { + free(buf); + return -1; + } + free(buf); + return 0; +} diff -r 083849df660b -r b3351d018ac6 src/fs.h --- a/src/fs.h Sun Dec 11 10:17:58 2011 +0200 +++ b/src/fs.h Sun Dec 11 11:12:30 2011 +0200 @@ -17,6 +17,22 @@ typedef uint32_t dev_t; typedef uint32_t blkid; + +/* 20 direct blocks + 10 attributes + 2 indirect = 128 bytes per inode */ +#define NDIRBLK 20 +struct inode { + int ino; + int uid, gid, mode; + int nlink; + dev_t dev; + uint32_t atime, ctime, mtime; + uint32_t size; + blkid blk[NDIRBLK]; /* direct blocks */ + blkid ind; /* indirect */ + blkid dind; /* double-indirect */ +} __attribute__((packed)); + + struct superblock { uint32_t magic; /* magic number */ int ver; /* filesystem version */ @@ -34,33 +50,19 @@ blkid bm_start; unsigned int bm_count; - int root_ino; /* root direcotry inode */ + int root_ino; /* root direcotry inode number */ /* the following are valid only at runtime, ignored on disk */ uint32_t *ibm; /* in-memory inode bitmap */ uint32_t *bm; /* in-memory block bitmap */ + struct inode *root; /* in-memory root inode */ } __attribute__((packed)); -/* 20 direct blocks + 10 attributes + 2 indirect = 128 bytes per inode */ -#define NDIRBLK 20 -struct inode { - int ino; - int uid, gid, mode; - int nlink; - dev_t dev; - uint32_t atime, ctime, mtime; - uint32_t size; - blkid blk[NDIRBLK]; /* direct blocks */ - blkid ind; /* indirect */ - blkid dind; /* double-indirect */ -} __attribute__((packed)); - struct filesys { struct block_device *bdev; - struct partition part; struct superblock *sb; @@ -69,6 +71,7 @@ /* defined in fs.c */ int openfs(struct filesys *fs, dev_t dev); +void closefs(struct filesys *fs); int find_inode(const char *path); /* defined in fs_sys.c */