kern

view 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 source
1 /* This code is used by the kernel AND by userspace filesystem-related tools.
2 * The kernel-specific parts are conditionally compiled in #ifdef KERNEL blocks
3 * the rest of the code should be independent.
4 */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <errno.h>
9 #include <assert.h>
10 #include "fs.h"
11 #include "bdev.h"
14 int openfs(struct filesys *fs, dev_t dev);
15 static int read_superblock(struct filesys *fs);
16 static int write_superblock(struct filesys *fs);
17 static int get_inode(struct filesys *fs, int ino, struct inode *inode);
18 static int put_inode(struct filesys *fs, struct inode *inode);
20 int openfs(struct filesys *fs, dev_t dev)
21 {
22 int res;
23 struct block_device *bdev;
25 assert(BLKSZ % sizeof(struct inode) == 0);
27 if(!(bdev = blk_open(dev))) {
28 return -ENOENT;
29 }
30 fs->bdev = bdev;
32 /* read the superblock */
33 if(!(fs->sb = malloc(BLKSZ))) {
34 res = -ENOMEM;
35 goto done;
36 }
37 if((res = read_superblock(fs)) != 0) {
38 goto done;
39 }
42 done:
43 blk_close(bdev);
44 return res;
45 }
47 static int read_superblock(struct filesys *fs)
48 {
49 struct superblock *sb = fs->sb;
51 /* read superblock and verify */
52 if(blk_read(fs->bdev, 1, 1, sb) == -1) {
53 printf("failed to read superblock\n");
54 return -EIO;
55 }
56 if(sb->magic != MAGIC) {
57 printf("invalid magic\n");
58 return -EINVAL;
59 }
60 if(sb->ver > FS_VER) {
61 printf("invalid version: %d\n", sb->ver);
62 return -EINVAL;
63 }
64 if(sb->blksize != BLKSZ) {
65 printf("invalid block size: %d\n", sb->blksize);
66 return -EINVAL;
67 }
69 /* allocate and populate in-memory bitmaps */
70 if(!(sb->ibm = malloc(sb->ibm_count * sb->blksize))) {
71 return -ENOMEM;
72 }
73 if(blk_read(fs->bdev, sb->ibm_start, sb->ibm_count, sb->ibm) == -1) {
74 printf("failed to read inode bitmap\n");
75 free(sb->ibm);
76 return -EIO;
77 }
78 if(!(sb->bm = malloc(sb->bm_count * sb->blksize))) {
79 free(sb->ibm);
80 return -ENOMEM;
81 }
82 if(blk_read(fs->bdev, sb->bm_start, sb->bm_count, sb->bm) == -1) {
83 printf("failed to read block bitmap\n");
84 free(sb->ibm);
85 free(sb->bm);
86 return -EIO;
87 }
89 /* read the root inode */
90 if(!(sb->root = malloc(sizeof *sb->root))) {
91 free(sb->ibm);
92 free(sb->bm);
93 return -ENOMEM;
94 }
95 if(get_inode(fs, sb->root_ino, sb->root) == -1) {
96 printf("failed to read root inode\n");
97 return -1;
98 }
100 return 0;
101 }
103 static int write_superblock(struct filesys *fs)
104 {
105 struct superblock *sb = fs->sb;
107 /* write back any changes in the root inode */
108 if(put_inode(fs, sb->root) == -1) {
109 return -1;
110 }
111 /* write back the block bitmap */
112 if(blk_write(fs->bdev, sb->bm_start, sb->bm_count, sb->bm) == -1) {
113 return -1;
114 }
115 /* write back the inode bitmap */
116 if(blk_write(fs->bdev, sb->ibm_start, sb->ibm_count, sb->ibm) == -1) {
117 return -1;
118 }
119 return 0;
120 }
122 /* number of inodes in a block */
123 #define BLK_INODES (BLKSZ / sizeof(struct inode))
125 /* copy the requested inode from the disk, into the buffer passed in the last arg */
126 static int get_inode(struct filesys *fs, int ino, struct inode *inode)
127 {
128 struct inode *buf = malloc(BLKSZ);
129 assert(buf);
131 if(blk_read(fs->bdev, fs->sb->itbl_start + ino / BLK_INODES, 1, buf) == -1) {
132 free(buf);
133 return -1;
134 }
135 memcpy(inode, buf + ino % BLK_INODES, sizeof *inode);
136 free(buf);
137 return 0;
138 }
140 /* write the inode to the disk */
141 static int put_inode(struct filesys *fs, struct inode *inode)
142 {
143 struct inode *buf = malloc(BLKSZ);
144 assert(buf);
146 if(blk_read(fs->bdev, fs->sb->itbl_start + inode->ino / BLK_INODES, 1, buf) == -1) {
147 free(buf);
148 return -1;
149 }
150 memcpy(buf + inode->ino % BLK_INODES, inode, sizeof *inode);
152 if(blk_write(fs->bdev, fs->sb->itbl_start + inode->ino / BLK_INODES, 1, buf) == -1) {
153 free(buf);
154 return -1;
155 }
156 free(buf);
157 return 0;
158 }