kern
changeset 94:b3351d018ac6
read/write superblock, get/put inode
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 11 Dec 2011 11:12:30 +0200 |
parents | 083849df660b |
children | ec62cbe00b55 |
files | include/kdef.h src/fs.c src/fs.h |
diffstat | 3 files changed, 114 insertions(+), 35 deletions(-) [+] |
line diff
1.1 --- a/include/kdef.h Sun Dec 11 10:17:58 2011 +0200 1.2 +++ b/include/kdef.h Sun Dec 11 11:12:30 2011 +0200 1.3 @@ -29,14 +29,17 @@ 1.4 1.5 /* --- defines for errno.h */ 1.6 #if defined(KERNEL) || defined(KDEF_ERRNO_H) 1.7 -#define EAGAIN 1 1.8 -#define EINVAL 2 1.9 -#define ECHILD 3 1.10 -#define EBUSY 4 1.11 -#define ENOMEM 5 1.12 -#define EIO 6 1.13 +#define EFOO 1 /* I just like to return -1 some times :) */ 1.14 1.15 -#define EBUG 127 /* error: feature not implemented yet */ 1.16 +#define EAGAIN 2 1.17 +#define EINVAL 3 1.18 +#define ECHILD 4 1.19 +#define EBUSY 5 1.20 +#define ENOMEM 6 1.21 +#define EIO 7 1.22 +#define ENOENT 8 1.23 + 1.24 +#define EBUG 127 /* for missing features and known bugs */ 1.25 #endif /* errno.h */ 1.26 1.27
2.1 --- a/src/fs.c Sun Dec 11 10:17:58 2011 +0200 2.2 +++ b/src/fs.c Sun Dec 11 11:12:30 2011 +0200 2.3 @@ -4,47 +4,52 @@ 2.4 */ 2.5 #include <stdio.h> 2.6 #include <stdlib.h> 2.7 +#include <string.h> 2.8 #include <errno.h> 2.9 +#include <assert.h> 2.10 #include "fs.h" 2.11 #include "bdev.h" 2.12 2.13 2.14 int openfs(struct filesys *fs, dev_t dev); 2.15 -static int read_superblock(struct block_device *bdev, struct superblock *sb); 2.16 - 2.17 +static int read_superblock(struct filesys *fs); 2.18 +static int write_superblock(struct filesys *fs); 2.19 +static int get_inode(struct filesys *fs, int ino, struct inode *inode); 2.20 +static int put_inode(struct filesys *fs, struct inode *inode); 2.21 2.22 int openfs(struct filesys *fs, dev_t dev) 2.23 { 2.24 int res; 2.25 struct block_device *bdev; 2.26 - struct superblock *sb = 0; 2.27 + 2.28 + assert(BLKSZ % sizeof(struct inode) == 0); 2.29 2.30 if(!(bdev = blk_open(dev))) { 2.31 return -ENOENT; 2.32 } 2.33 + fs->bdev = bdev; 2.34 2.35 /* read the superblock */ 2.36 - if(!(sb = malloc(BLKSZ))) { 2.37 + if(!(fs->sb = malloc(BLKSZ))) { 2.38 res = -ENOMEM; 2.39 goto done; 2.40 } 2.41 - if((res = read_superblock(bdev, sb)) != 0) { 2.42 + if((res = read_superblock(fs)) != 0) { 2.43 goto done; 2.44 } 2.45 2.46 2.47 - 2.48 - 2.49 done: 2.50 blk_close(bdev); 2.51 - free(sb); 2.52 return res; 2.53 } 2.54 2.55 -static int read_superblock(struct block_device *bdev, struct superblock *sb) 2.56 +static int read_superblock(struct filesys *fs) 2.57 { 2.58 + struct superblock *sb = fs->sb; 2.59 + 2.60 /* read superblock and verify */ 2.61 - if(blk_read(bdev, 1, 1, sb) == -1) { 2.62 + if(blk_read(fs->bdev, 1, 1, sb) == -1) { 2.63 printf("failed to read superblock\n"); 2.64 return -EIO; 2.65 } 2.66 @@ -65,7 +70,7 @@ 2.67 if(!(sb->ibm = malloc(sb->ibm_count * sb->blksize))) { 2.68 return -ENOMEM; 2.69 } 2.70 - if(blk_read(bdev, sb->ibm_start, sb->ibm_count, sb->ibm) == -1) { 2.71 + if(blk_read(fs->bdev, sb->ibm_start, sb->ibm_count, sb->ibm) == -1) { 2.72 printf("failed to read inode bitmap\n"); 2.73 free(sb->ibm); 2.74 return -EIO; 2.75 @@ -74,12 +79,80 @@ 2.76 free(sb->ibm); 2.77 return -ENOMEM; 2.78 } 2.79 - if(blk_read(bdev, sb->bm_start, sb->bm_count, sb->bm) == -1) { 2.80 + if(blk_read(fs->bdev, sb->bm_start, sb->bm_count, sb->bm) == -1) { 2.81 printf("failed to read block bitmap\n"); 2.82 free(sb->ibm); 2.83 free(sb->bm); 2.84 return -EIO; 2.85 } 2.86 2.87 + /* read the root inode */ 2.88 + if(!(sb->root = malloc(sizeof *sb->root))) { 2.89 + free(sb->ibm); 2.90 + free(sb->bm); 2.91 + return -ENOMEM; 2.92 + } 2.93 + if(get_inode(fs, sb->root_ino, sb->root) == -1) { 2.94 + printf("failed to read root inode\n"); 2.95 + return -1; 2.96 + } 2.97 + 2.98 return 0; 2.99 } 2.100 + 2.101 +static int write_superblock(struct filesys *fs) 2.102 +{ 2.103 + struct superblock *sb = fs->sb; 2.104 + 2.105 + /* write back any changes in the root inode */ 2.106 + if(put_inode(fs, sb->root) == -1) { 2.107 + return -1; 2.108 + } 2.109 + /* write back the block bitmap */ 2.110 + if(blk_write(fs->bdev, sb->bm_start, sb->bm_count, sb->bm) == -1) { 2.111 + return -1; 2.112 + } 2.113 + /* write back the inode bitmap */ 2.114 + if(blk_write(fs->bdev, sb->ibm_start, sb->ibm_count, sb->ibm) == -1) { 2.115 + return -1; 2.116 + } 2.117 + return 0; 2.118 +} 2.119 + 2.120 +/* number of inodes in a block */ 2.121 +#define BLK_INODES (BLKSZ / sizeof(struct inode)) 2.122 + 2.123 +/* copy the requested inode from the disk, into the buffer passed in the last arg */ 2.124 +static int get_inode(struct filesys *fs, int ino, struct inode *inode) 2.125 +{ 2.126 + struct inode *buf = malloc(BLKSZ); 2.127 + assert(buf); 2.128 + 2.129 + if(blk_read(fs->bdev, fs->sb->itbl_start + ino / BLK_INODES, 1, buf) == -1) { 2.130 + free(buf); 2.131 + return -1; 2.132 + } 2.133 + memcpy(inode, buf + ino % BLK_INODES, sizeof *inode); 2.134 + free(buf); 2.135 + return 0; 2.136 +} 2.137 + 2.138 +/* write the inode to the disk */ 2.139 +static int put_inode(struct filesys *fs, struct inode *inode) 2.140 +{ 2.141 + struct inode *buf = malloc(BLKSZ); 2.142 + assert(buf); 2.143 + 2.144 + if(blk_read(fs->bdev, fs->sb->itbl_start + inode->ino / BLK_INODES, 1, buf) == -1) { 2.145 + free(buf); 2.146 + return -1; 2.147 + } 2.148 + memcpy(buf + inode->ino % BLK_INODES, inode, sizeof *inode); 2.149 + 2.150 + if(blk_write(fs->bdev, fs->sb->itbl_start + inode->ino / BLK_INODES, 1, buf) == -1) { 2.151 + free(buf); 2.152 + return -1; 2.153 + } 2.154 + free(buf); 2.155 + return 0; 2.156 +}
3.1 --- a/src/fs.h Sun Dec 11 10:17:58 2011 +0200 3.2 +++ b/src/fs.h Sun Dec 11 11:12:30 2011 +0200 3.3 @@ -17,6 +17,22 @@ 3.4 typedef uint32_t dev_t; 3.5 typedef uint32_t blkid; 3.6 3.7 + 3.8 +/* 20 direct blocks + 10 attributes + 2 indirect = 128 bytes per inode */ 3.9 +#define NDIRBLK 20 3.10 +struct inode { 3.11 + int ino; 3.12 + int uid, gid, mode; 3.13 + int nlink; 3.14 + dev_t dev; 3.15 + uint32_t atime, ctime, mtime; 3.16 + uint32_t size; 3.17 + blkid blk[NDIRBLK]; /* direct blocks */ 3.18 + blkid ind; /* indirect */ 3.19 + blkid dind; /* double-indirect */ 3.20 +} __attribute__((packed)); 3.21 + 3.22 + 3.23 struct superblock { 3.24 uint32_t magic; /* magic number */ 3.25 int ver; /* filesystem version */ 3.26 @@ -34,33 +50,19 @@ 3.27 blkid bm_start; 3.28 unsigned int bm_count; 3.29 3.30 - int root_ino; /* root direcotry inode */ 3.31 + int root_ino; /* root direcotry inode number */ 3.32 3.33 /* the following are valid only at runtime, ignored on disk */ 3.34 uint32_t *ibm; /* in-memory inode bitmap */ 3.35 uint32_t *bm; /* in-memory block bitmap */ 3.36 + struct inode *root; /* in-memory root inode */ 3.37 3.38 } __attribute__((packed)); 3.39 3.40 3.41 -/* 20 direct blocks + 10 attributes + 2 indirect = 128 bytes per inode */ 3.42 -#define NDIRBLK 20 3.43 -struct inode { 3.44 - int ino; 3.45 - int uid, gid, mode; 3.46 - int nlink; 3.47 - dev_t dev; 3.48 - uint32_t atime, ctime, mtime; 3.49 - uint32_t size; 3.50 - blkid blk[NDIRBLK]; /* direct blocks */ 3.51 - blkid ind; /* indirect */ 3.52 - blkid dind; /* double-indirect */ 3.53 -} __attribute__((packed)); 3.54 - 3.55 3.56 struct filesys { 3.57 struct block_device *bdev; 3.58 - struct partition part; 3.59 3.60 struct superblock *sb; 3.61 3.62 @@ -69,6 +71,7 @@ 3.63 3.64 /* defined in fs.c */ 3.65 int openfs(struct filesys *fs, dev_t dev); 3.66 +void closefs(struct filesys *fs); 3.67 int find_inode(const char *path); 3.68 3.69 /* defined in fs_sys.c */