kern

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