kern
diff src/fs.c @ 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 |
line diff
1.1 --- a/src/fs.c Sun Dec 11 10:17:58 2011 +0200 1.2 +++ b/src/fs.c Sun Dec 11 11:12:30 2011 +0200 1.3 @@ -4,47 +4,52 @@ 1.4 */ 1.5 #include <stdio.h> 1.6 #include <stdlib.h> 1.7 +#include <string.h> 1.8 #include <errno.h> 1.9 +#include <assert.h> 1.10 #include "fs.h" 1.11 #include "bdev.h" 1.12 1.13 1.14 int openfs(struct filesys *fs, dev_t dev); 1.15 -static int read_superblock(struct block_device *bdev, struct superblock *sb); 1.16 - 1.17 +static int read_superblock(struct filesys *fs); 1.18 +static int write_superblock(struct filesys *fs); 1.19 +static int get_inode(struct filesys *fs, int ino, struct inode *inode); 1.20 +static int put_inode(struct filesys *fs, struct inode *inode); 1.21 1.22 int openfs(struct filesys *fs, dev_t dev) 1.23 { 1.24 int res; 1.25 struct block_device *bdev; 1.26 - struct superblock *sb = 0; 1.27 + 1.28 + assert(BLKSZ % sizeof(struct inode) == 0); 1.29 1.30 if(!(bdev = blk_open(dev))) { 1.31 return -ENOENT; 1.32 } 1.33 + fs->bdev = bdev; 1.34 1.35 /* read the superblock */ 1.36 - if(!(sb = malloc(BLKSZ))) { 1.37 + if(!(fs->sb = malloc(BLKSZ))) { 1.38 res = -ENOMEM; 1.39 goto done; 1.40 } 1.41 - if((res = read_superblock(bdev, sb)) != 0) { 1.42 + if((res = read_superblock(fs)) != 0) { 1.43 goto done; 1.44 } 1.45 1.46 1.47 - 1.48 - 1.49 done: 1.50 blk_close(bdev); 1.51 - free(sb); 1.52 return res; 1.53 } 1.54 1.55 -static int read_superblock(struct block_device *bdev, struct superblock *sb) 1.56 +static int read_superblock(struct filesys *fs) 1.57 { 1.58 + struct superblock *sb = fs->sb; 1.59 + 1.60 /* read superblock and verify */ 1.61 - if(blk_read(bdev, 1, 1, sb) == -1) { 1.62 + if(blk_read(fs->bdev, 1, 1, sb) == -1) { 1.63 printf("failed to read superblock\n"); 1.64 return -EIO; 1.65 } 1.66 @@ -65,7 +70,7 @@ 1.67 if(!(sb->ibm = malloc(sb->ibm_count * sb->blksize))) { 1.68 return -ENOMEM; 1.69 } 1.70 - if(blk_read(bdev, sb->ibm_start, sb->ibm_count, sb->ibm) == -1) { 1.71 + if(blk_read(fs->bdev, sb->ibm_start, sb->ibm_count, sb->ibm) == -1) { 1.72 printf("failed to read inode bitmap\n"); 1.73 free(sb->ibm); 1.74 return -EIO; 1.75 @@ -74,12 +79,80 @@ 1.76 free(sb->ibm); 1.77 return -ENOMEM; 1.78 } 1.79 - if(blk_read(bdev, sb->bm_start, sb->bm_count, sb->bm) == -1) { 1.80 + if(blk_read(fs->bdev, sb->bm_start, sb->bm_count, sb->bm) == -1) { 1.81 printf("failed to read block bitmap\n"); 1.82 free(sb->ibm); 1.83 free(sb->bm); 1.84 return -EIO; 1.85 } 1.86 1.87 + /* read the root inode */ 1.88 + if(!(sb->root = malloc(sizeof *sb->root))) { 1.89 + free(sb->ibm); 1.90 + free(sb->bm); 1.91 + return -ENOMEM; 1.92 + } 1.93 + if(get_inode(fs, sb->root_ino, sb->root) == -1) { 1.94 + printf("failed to read root inode\n"); 1.95 + return -1; 1.96 + } 1.97 + 1.98 return 0; 1.99 } 1.100 + 1.101 +static int write_superblock(struct filesys *fs) 1.102 +{ 1.103 + struct superblock *sb = fs->sb; 1.104 + 1.105 + /* write back any changes in the root inode */ 1.106 + if(put_inode(fs, sb->root) == -1) { 1.107 + return -1; 1.108 + } 1.109 + /* write back the block bitmap */ 1.110 + if(blk_write(fs->bdev, sb->bm_start, sb->bm_count, sb->bm) == -1) { 1.111 + return -1; 1.112 + } 1.113 + /* write back the inode bitmap */ 1.114 + if(blk_write(fs->bdev, sb->ibm_start, sb->ibm_count, sb->ibm) == -1) { 1.115 + return -1; 1.116 + } 1.117 + return 0; 1.118 +} 1.119 + 1.120 +/* number of inodes in a block */ 1.121 +#define BLK_INODES (BLKSZ / sizeof(struct inode)) 1.122 + 1.123 +/* copy the requested inode from the disk, into the buffer passed in the last arg */ 1.124 +static int get_inode(struct filesys *fs, int ino, struct inode *inode) 1.125 +{ 1.126 + struct inode *buf = malloc(BLKSZ); 1.127 + assert(buf); 1.128 + 1.129 + if(blk_read(fs->bdev, fs->sb->itbl_start + ino / BLK_INODES, 1, buf) == -1) { 1.130 + free(buf); 1.131 + return -1; 1.132 + } 1.133 + memcpy(inode, buf + ino % BLK_INODES, sizeof *inode); 1.134 + free(buf); 1.135 + return 0; 1.136 +} 1.137 + 1.138 +/* write the inode to the disk */ 1.139 +static int put_inode(struct filesys *fs, struct inode *inode) 1.140 +{ 1.141 + struct inode *buf = malloc(BLKSZ); 1.142 + assert(buf); 1.143 + 1.144 + if(blk_read(fs->bdev, fs->sb->itbl_start + inode->ino / BLK_INODES, 1, buf) == -1) { 1.145 + free(buf); 1.146 + return -1; 1.147 + } 1.148 + memcpy(buf + inode->ino % BLK_INODES, inode, sizeof *inode); 1.149 + 1.150 + if(blk_write(fs->bdev, fs->sb->itbl_start + inode->ino / BLK_INODES, 1, buf) == -1) { 1.151 + free(buf); 1.152 + return -1; 1.153 + } 1.154 + free(buf); 1.155 + return 0; 1.156 +}