# HG changeset patch # User John Tsiombikas # Date 1323591478 -7200 # Node ID 083849df660b14f40f59c9064637da9abf3f4ae3 # Parent f83f50c17c3b1505ac122867d8be68e9472caf3c split the system call implementations out of fs.c into fs_sys.c diff -r f83f50c17c3b -r 083849df660b fstools/mkfs/mkfs.c --- a/fstools/mkfs/mkfs.c Fri Dec 09 15:29:54 2011 +0200 +++ b/fstools/mkfs/mkfs.c Sun Dec 11 10:17:58 2011 +0200 @@ -47,10 +47,12 @@ { struct superblock *sb; - if(!(sb = malloc(BLKSZ))) { - perror("failed to allocate memory"); - return -1; - } + sb = malloc(BLKSZ); + assert(sb); + + sb->magic = MAGIC; + sb->ver = 0; + sb->num_blocks = nblocks; } uint32_t get_block_count(int fd, int blksize) @@ -84,23 +86,23 @@ return 0; } -int user_readblock(int dev, uint32_t blk, void *buf) +int blk_read(void*, uint32_t blk, int count, void *buf) { if(lseek(fd, blk * BLKSZ, SEEK_SET) == -1) { return -1; } - if(read(fd, buf, BLKSZ) < BLKSZ) { + if(read(fd, buf, BLKSZ * count) < BLKSZ * count) { return -1; } return 0; } -int user_writeblock(int dev, uint32_t blk, void *buf) +int blk_write(void*, uint32_t blk, int count, void *buf) { if(lseek(fd, blk * BLKSZ, SEEK_SET) == -1) { return -1; } - if(write(fd, buf, BLKSZ) < BLKSZ) { + if(write(fd, buf, BLKSZ * count) < BLKSZ * count) { return -1; } return 0; diff -r f83f50c17c3b -r 083849df660b include/kdef.h --- a/include/kdef.h Fri Dec 09 15:29:54 2011 +0200 +++ b/include/kdef.h Sun Dec 11 10:17:58 2011 +0200 @@ -32,8 +32,11 @@ #define EAGAIN 1 #define EINVAL 2 #define ECHILD 3 +#define EBUSY 4 +#define ENOMEM 5 +#define EIO 6 -#define EBUG 255 /* not implemented yet */ +#define EBUG 127 /* error: feature not implemented yet */ #endif /* errno.h */ diff -r f83f50c17c3b -r 083849df660b src/bdev.c --- a/src/bdev.c Fri Dec 09 15:29:54 2011 +0200 +++ b/src/bdev.c Sun Dec 11 10:17:58 2011 +0200 @@ -40,11 +40,13 @@ bdev->offset = SECT_TO_BLK(plist->start_sect); bdev->size = SECT_TO_BLK(plist->size_sect); + bdev->ptype = get_part_type(plist); free_part_list(plist); } else { bdev->offset = 0; bdev->size = SECT_TO_BLK(ata_num_sectors(devno)); + bdev->ptype = 0; } return bdev; @@ -57,13 +59,13 @@ #define NSECT (BLKSZ / 512) -int blk_read(struct block_device *bdev, uint32_t blk, void *buf) +int blk_read(struct block_device *bdev, uint32_t blk, int count, void *buf) { int i; char *ptr = buf; - uint32_t sect = blk * NSECT; + uint32_t sect = blk * NSECT + bdev->offset; - for(i=0; iata_dev, sect++, ptr) == -1) { return -1; } @@ -72,13 +74,13 @@ return 0; } -int blk_write(struct block_device *bdev, uint32_t blk, void *buf) +int blk_write(struct block_device *bdev, uint32_t blk, int count, void *buf) { int i; char *ptr = buf; - uint32_t sect = blk * NSECT; + uint32_t sect = blk * NSECT + bdev->offset; - for(i=0; iata_dev, sect++, ptr) == -1) { return -1; } @@ -116,5 +118,5 @@ } minor = MKMINOR(atadev, part); - return DEVNO(0, minor); + return DEVNO(1, minor); } diff -r f83f50c17c3b -r 083849df660b src/bdev.h --- a/src/bdev.h Fri Dec 09 15:29:54 2011 +0200 +++ b/src/bdev.h Sun Dec 11 10:17:58 2011 +0200 @@ -8,13 +8,19 @@ struct block_device { int ata_dev; uint32_t offset, size; + + /* Partition type (if the blkdev is a partition), otherwise 0. + * Used as just an extra sanity check to make sure we don't + * try to mount the wrong filesystem. + */ + int ptype; }; struct block_device *blk_open(dev_t dev); void blk_close(struct block_device *bdev); -int blk_read(struct block_device *bdev, uint32_t blk, void *buf); -int blk_write(struct block_device *bdev, uint32_t blk, void *buf); +int blk_read(struct block_device *bdev, uint32_t blk, int count, void *buf); +int blk_write(struct block_device *bdev, uint32_t blk, int count, void *buf); dev_t bdev_by_name(const char *name); diff -r f83f50c17c3b -r 083849df660b src/fs.c --- a/src/fs.c Fri Dec 09 15:29:54 2011 +0200 +++ b/src/fs.c Sun Dec 11 10:17:58 2011 +0200 @@ -4,117 +4,82 @@ */ #include #include -#include #include #include "fs.h" -#include "part.h" +#include "bdev.h" -#ifdef KERNEL -#include "ata.h" -#include "panic.h" -#endif -struct filesys { - int dev; - struct partition part; +int openfs(struct filesys *fs, dev_t dev); +static int read_superblock(struct block_device *bdev, struct superblock *sb); - struct superblock *sb; - struct filesys *next; -}; +int openfs(struct filesys *fs, dev_t dev) +{ + int res; + struct block_device *bdev; + struct superblock *sb = 0; -static int find_rootfs(struct filesys *fs); -static int readblock(int dev, uint32_t blk, void *buf); -static int writeblock(int dev, uint32_t blk, void *buf); - -/* root device & partition */ -static struct filesys *fslist; - -int sys_mount(char *mtpt, char *devname, unsigned int flags) -{ - if(strcmp(mtpt, "/") != 0) { - printf("mount: only root can be mounted at the moment\n"); - return -EBUG; + if(!(bdev = blk_open(dev))) { + return -ENOENT; } - /* mounting root filesystem */ - if(fslist) { + /* read the superblock */ + if(!(sb = malloc(BLKSZ))) { + res = -ENOMEM; + goto done; + } + if((res = read_superblock(bdev, sb)) != 0) { + goto done; + } + + + +done: + blk_close(bdev); + free(sb); + return res; } -void init_fs(void) +static int read_superblock(struct block_device *bdev, struct superblock *sb) { - root.sb = malloc(512); - assert(root.sb); + /* read superblock and verify */ + if(blk_read(bdev, 1, 1, sb) == -1) { + printf("failed to read superblock\n"); + return -EIO; + } + if(sb->magic != MAGIC) { + printf("invalid magic\n"); + return -EINVAL; + } + if(sb->ver > FS_VER) { + printf("invalid version: %d\n", sb->ver); + return -EINVAL; + } + if(sb->blksize != BLKSZ) { + printf("invalid block size: %d\n", sb->blksize); + return -EINVAL; + } -#ifdef KERNEL - if(find_rootfs(&root) == -1) { - panic("can't find root filesystem\n"); + /* allocate and populate in-memory bitmaps */ + if(!(sb->ibm = malloc(sb->ibm_count * sb->blksize))) { + return -ENOMEM; } -#endif + if(blk_read(bdev, sb->ibm_start, sb->ibm_count, sb->ibm) == -1) { + printf("failed to read inode bitmap\n"); + free(sb->ibm); + return -EIO; + } + if(!(sb->bm = malloc(sb->bm_count * sb->blksize))) { + free(sb->ibm); + return -ENOMEM; + } + if(blk_read(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; + } + + return 0; } - - -#ifdef KERNEL -#define PART_TYPE 0xcc -static int find_rootfs(struct filesys *fs) -{ - int i, num_dev, partid; - struct partition *plist, *p; - - num_dev = ata_num_devices(); - for(i=0; istart_sect / 2 + 1, fs->sb); - - if(fs->sb->magic == MAGIC) { - printf("found root ata%dp%d\n", i, partid); - fs->dev = i; - fs->part = *p; - return 0; - } - } - p = p->next; - partid++; - } - free_part_list(plist); - } - return -1; -} - -#define NSECT (BLKSZ / 512) - -static int readblock(struct block_device *bdev, uint32_t blk, void *buf) -{ - return blk_read(bdev, blk, buf); -} - -static int writeblock(struct block_device *bdev, uint32_t blk, void *buf) -{ - return blk_write(bdev, blk, buf); -} -#else - -/* if this is compiled as part of the user-space tools instead of the kernel - * forward the call to a user read/write block function supplied by the app. - */ -int user_readblock(uint32_t, void*); -int user_writeblock(uint32_t, void*); - -static int readblock(struct block_device *bdev, uint32_t blk, void *buf) -{ - return user_readblock(blk, buf); -} - -static int writeblock(struct block_device *bdev, uint32_t blk, void *buf) -{ - return user_writeblock(blk, buf); -} -#endif /* KERNEL */ diff -r f83f50c17c3b -r 083849df660b src/fs.h --- a/src/fs.h Fri Dec 09 15:29:54 2011 +0200 +++ b/src/fs.h Sun Dec 11 10:17:58 2011 +0200 @@ -4,6 +4,7 @@ #include #define MAGIC 0xccf5ccf5 +#define FS_VER 1 #define BLKSZ 1024 #define SECT_TO_BLK(x) ((x) / (BLKSZ / 512)) @@ -29,18 +30,15 @@ /* inode table start and count */ blkid itbl_start; unsigned int itbl_count; - /* data block allocation bitmap start and count */ - blkid dbm_start; - unsigned int dbm_count; - /* data blocks start and count */ - blkid data_start; - unsigned int data_count; + /* block allocation bitmap start and count */ + blkid bm_start; + unsigned int bm_count; int root_ino; /* root direcotry inode */ /* the following are valid only at runtime, ignored on disk */ - uint32_t *ibm; /* memory inode bitmap */ - uint32_t *dbm; /* memory datablock bitmap */ + uint32_t *ibm; /* in-memory inode bitmap */ + uint32_t *bm; /* in-memory block bitmap */ } __attribute__((packed)); @@ -60,6 +58,20 @@ } __attribute__((packed)); +struct filesys { + struct block_device *bdev; + struct partition part; + + struct superblock *sb; + + struct filesys *next; +}; + +/* defined in fs.c */ +int openfs(struct filesys *fs, dev_t dev); +int find_inode(const char *path); + +/* defined in fs_sys.c */ int sys_mount(char *mntpt, char *devname, unsigned int flags); int sys_umount(char *devname); @@ -70,7 +82,5 @@ int sys_write(int fd, void *buf, int sz); long sys_lseek(int fd, long offs, int from); -int lookup_path(const char *path); - #endif /* FS_H_ */ diff -r f83f50c17c3b -r 083849df660b src/fs_sys.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/fs_sys.c Sun Dec 11 10:17:58 2011 +0200 @@ -0,0 +1,105 @@ +/* implementation of the filesystem-related syscalls */ + +#include +#include +#include +#include +#include +#include "fs.h" +#include "part.h" +#include "panic.h" +#include "bdev.h" + +static dev_t find_rootfs(void); + +/* list of mounted filesystems + * XXX currently only one, the root filesystem + */ +static struct filesys *fslist; + + +int sys_mount(char *mtpt, char *devname, unsigned int flags) +{ + dev_t dev; + int err; + struct filesys *fs; + + if(strcmp(mtpt, "/") != 0) { + printf("only root can be mounted at the moment\n"); + return -EBUG; + } + + /* mounting root filesystem */ + if(fslist) { + printf("root already mounted\n"); + return -EBUSY; + } + + if(devname) { + dev = bdev_by_name(devname); + } else { + /* try to autodetect it */ + dev = find_rootfs(); + } + if(!dev) { + err = -ENOENT; + goto rootfail; + } + + if(!(fs = malloc(sizeof *fslist))) { + err = -ENOMEM; + goto rootfail; + } + if((err = openfs(fs, dev)) != 0) { + free(fs); + goto rootfail; + } + + fslist = fs; + return 0; + +rootfail: + panic("failed to mount root filesystem: %d\n", -err); + return err; /* unreachable */ +} + +#define PART_TYPE 0xcc +static dev_t find_rootfs(void) +{ + dev_t dev = 0; + int i, num_dev, partid; + struct partition *plist, *p; + struct superblock *sb = malloc(BLKSZ); + char name[16]; + + assert(sb); + + num_dev = ata_num_devices(); + for(i=0; istart_sect / 2 + 1, BLKSZ, sb); + + if(sb->magic == MAGIC) { + sprintf(name, "ata%dp%d", i, partid); + printf("found root: %s\n", name); + dev = bdev_by_name(name); + break; + } + } + p = p->next; + partid++; + } + free_part_list(plist); + if(dev) break; + } + + free(sb); + return dev; +}