kern

changeset 93:083849df660b

split the system call implementations out of fs.c into fs_sys.c
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 11 Dec 2011 10:17:58 +0200
parents f83f50c17c3b
children b3351d018ac6
files fstools/mkfs/mkfs.c include/kdef.h src/bdev.c src/bdev.h src/fs.c src/fs.h src/fs_sys.c
diffstat 7 files changed, 219 insertions(+), 126 deletions(-) [+]
line diff
     1.1 --- a/fstools/mkfs/mkfs.c	Fri Dec 09 15:29:54 2011 +0200
     1.2 +++ b/fstools/mkfs/mkfs.c	Sun Dec 11 10:17:58 2011 +0200
     1.3 @@ -47,10 +47,12 @@
     1.4  {
     1.5  	struct superblock *sb;
     1.6  
     1.7 -	if(!(sb = malloc(BLKSZ))) {
     1.8 -		perror("failed to allocate memory");
     1.9 -		return -1;
    1.10 -	}
    1.11 +	sb = malloc(BLKSZ);
    1.12 +	assert(sb);
    1.13 +
    1.14 +	sb->magic = MAGIC;
    1.15 +	sb->ver = 0;
    1.16 +	sb->num_blocks = nblocks;
    1.17  }
    1.18  
    1.19  uint32_t get_block_count(int fd, int blksize)
    1.20 @@ -84,23 +86,23 @@
    1.21  	return 0;
    1.22  }
    1.23  
    1.24 -int user_readblock(int dev, uint32_t blk, void *buf)
    1.25 +int blk_read(void*, uint32_t blk, int count, void *buf)
    1.26  {
    1.27  	if(lseek(fd, blk * BLKSZ, SEEK_SET) == -1) {
    1.28  		return -1;
    1.29  	}
    1.30 -	if(read(fd, buf, BLKSZ) < BLKSZ) {
    1.31 +	if(read(fd, buf, BLKSZ * count) < BLKSZ * count) {
    1.32  		return -1;
    1.33  	}
    1.34  	return 0;
    1.35  }
    1.36  
    1.37 -int user_writeblock(int dev, uint32_t blk, void *buf)
    1.38 +int blk_write(void*, uint32_t blk, int count, void *buf)
    1.39  {
    1.40  	if(lseek(fd, blk * BLKSZ, SEEK_SET) == -1) {
    1.41  		return -1;
    1.42  	}
    1.43 -	if(write(fd, buf, BLKSZ) < BLKSZ) {
    1.44 +	if(write(fd, buf, BLKSZ * count) < BLKSZ * count) {
    1.45  		return -1;
    1.46  	}
    1.47  	return 0;
     2.1 --- a/include/kdef.h	Fri Dec 09 15:29:54 2011 +0200
     2.2 +++ b/include/kdef.h	Sun Dec 11 10:17:58 2011 +0200
     2.3 @@ -32,8 +32,11 @@
     2.4  #define EAGAIN		1
     2.5  #define EINVAL		2
     2.6  #define ECHILD		3
     2.7 +#define EBUSY		4
     2.8 +#define ENOMEM		5
     2.9 +#define EIO			6
    2.10  
    2.11 -#define EBUG		255	/* not implemented yet */
    2.12 +#define EBUG		127	/* error: feature not implemented yet */
    2.13  #endif	/* errno.h */
    2.14  
    2.15  
     3.1 --- a/src/bdev.c	Fri Dec 09 15:29:54 2011 +0200
     3.2 +++ b/src/bdev.c	Sun Dec 11 10:17:58 2011 +0200
     3.3 @@ -40,11 +40,13 @@
     3.4  
     3.5  		bdev->offset = SECT_TO_BLK(plist->start_sect);
     3.6  		bdev->size = SECT_TO_BLK(plist->size_sect);
     3.7 +		bdev->ptype = get_part_type(plist);
     3.8  
     3.9  		free_part_list(plist);
    3.10  	} else {
    3.11  		bdev->offset = 0;
    3.12  		bdev->size = SECT_TO_BLK(ata_num_sectors(devno));
    3.13 +		bdev->ptype = 0;
    3.14  	}
    3.15  
    3.16  	return bdev;
    3.17 @@ -57,13 +59,13 @@
    3.18  
    3.19  #define NSECT	(BLKSZ / 512)
    3.20  
    3.21 -int blk_read(struct block_device *bdev, uint32_t blk, void *buf)
    3.22 +int blk_read(struct block_device *bdev, uint32_t blk, int count, void *buf)
    3.23  {
    3.24  	int i;
    3.25  	char *ptr = buf;
    3.26 -	uint32_t sect = blk * NSECT;
    3.27 +	uint32_t sect = blk * NSECT + bdev->offset;
    3.28  
    3.29 -	for(i=0; i<NSECT; i++) {
    3.30 +	for(i=0; i<NSECT * count; i++) {
    3.31  		if(ata_read_pio(bdev->ata_dev, sect++, ptr) == -1) {
    3.32  			return -1;
    3.33  		}
    3.34 @@ -72,13 +74,13 @@
    3.35  	return 0;
    3.36  }
    3.37  
    3.38 -int blk_write(struct block_device *bdev, uint32_t blk, void *buf)
    3.39 +int blk_write(struct block_device *bdev, uint32_t blk, int count, void *buf)
    3.40  {
    3.41  	int i;
    3.42  	char *ptr = buf;
    3.43 -	uint32_t sect = blk * NSECT;
    3.44 +	uint32_t sect = blk * NSECT + bdev->offset;
    3.45  
    3.46 -	for(i=0; i<NSECT; i++) {
    3.47 +	for(i=0; i<NSECT * count; i++) {
    3.48  		if(ata_write_pio(bdev->ata_dev, sect++, ptr) == -1) {
    3.49  			return -1;
    3.50  		}
    3.51 @@ -116,5 +118,5 @@
    3.52  	}
    3.53  
    3.54  	minor = MKMINOR(atadev, part);
    3.55 -	return DEVNO(0, minor);
    3.56 +	return DEVNO(1, minor);
    3.57  }
     4.1 --- a/src/bdev.h	Fri Dec 09 15:29:54 2011 +0200
     4.2 +++ b/src/bdev.h	Sun Dec 11 10:17:58 2011 +0200
     4.3 @@ -8,13 +8,19 @@
     4.4  struct block_device {
     4.5  	int ata_dev;
     4.6  	uint32_t offset, size;
     4.7 +
     4.8 +	/* Partition type (if the blkdev is a partition), otherwise 0.
     4.9 +	 * Used as just an extra sanity check to make sure we don't
    4.10 +	 * try to mount the wrong filesystem.
    4.11 +	 */
    4.12 +	int ptype;
    4.13  };
    4.14  
    4.15  struct block_device *blk_open(dev_t dev);
    4.16  void blk_close(struct block_device *bdev);
    4.17  
    4.18 -int blk_read(struct block_device *bdev, uint32_t blk, void *buf);
    4.19 -int blk_write(struct block_device *bdev, uint32_t blk, void *buf);
    4.20 +int blk_read(struct block_device *bdev, uint32_t blk, int count, void *buf);
    4.21 +int blk_write(struct block_device *bdev, uint32_t blk, int count, void *buf);
    4.22  
    4.23  dev_t bdev_by_name(const char *name);
    4.24  
     5.1 --- a/src/fs.c	Fri Dec 09 15:29:54 2011 +0200
     5.2 +++ b/src/fs.c	Sun Dec 11 10:17:58 2011 +0200
     5.3 @@ -4,117 +4,82 @@
     5.4   */
     5.5  #include <stdio.h>
     5.6  #include <stdlib.h>
     5.7 -#include <assert.h>
     5.8  #include <errno.h>
     5.9  #include "fs.h"
    5.10 -#include "part.h"
    5.11 +#include "bdev.h"
    5.12  
    5.13 -#ifdef KERNEL
    5.14 -#include "ata.h"
    5.15 -#include "panic.h"
    5.16 -#endif
    5.17  
    5.18 -struct filesys {
    5.19 -	int dev;
    5.20 -	struct partition part;
    5.21 +int openfs(struct filesys *fs, dev_t dev);
    5.22 +static int read_superblock(struct block_device *bdev, struct superblock *sb);
    5.23  
    5.24 -	struct superblock *sb;
    5.25  
    5.26 -	struct filesys *next;
    5.27 -};
    5.28 +int openfs(struct filesys *fs, dev_t dev)
    5.29 +{
    5.30 +	int res;
    5.31 +	struct block_device *bdev;
    5.32 +	struct superblock *sb = 0;
    5.33  
    5.34 -static int find_rootfs(struct filesys *fs);
    5.35 -static int readblock(int dev, uint32_t blk, void *buf);
    5.36 -static int writeblock(int dev, uint32_t blk, void *buf);
    5.37 -
    5.38 -/* root device & partition */
    5.39 -static struct filesys *fslist;
    5.40 -
    5.41 -int sys_mount(char *mtpt, char *devname, unsigned int flags)
    5.42 -{
    5.43 -	if(strcmp(mtpt, "/") != 0) {
    5.44 -		printf("mount: only root can be mounted at the moment\n");
    5.45 -		return -EBUG;
    5.46 +	if(!(bdev = blk_open(dev))) {
    5.47 +		return -ENOENT;
    5.48  	}
    5.49  
    5.50 -	/* mounting root filesystem */
    5.51 -	if(fslist) {
    5.52 +	/* read the superblock */
    5.53 +	if(!(sb = malloc(BLKSZ))) {
    5.54 +		res = -ENOMEM;
    5.55 +		goto done;
    5.56 +	}
    5.57 +	if((res = read_superblock(bdev, sb)) != 0) {
    5.58 +		goto done;
    5.59 +	}
    5.60  
    5.61 +
    5.62 +
    5.63 +
    5.64 +done:
    5.65 +	blk_close(bdev);
    5.66 +	free(sb);
    5.67 +	return res;
    5.68  }
    5.69  
    5.70 -void init_fs(void)
    5.71 +static int read_superblock(struct block_device *bdev, struct superblock *sb)
    5.72  {
    5.73 -	root.sb = malloc(512);
    5.74 -	assert(root.sb);
    5.75 +	/* read superblock and verify */
    5.76 +	if(blk_read(bdev, 1, 1, sb) == -1) {
    5.77 +		printf("failed to read superblock\n");
    5.78 +		return -EIO;
    5.79 +	}
    5.80 +	if(sb->magic != MAGIC) {
    5.81 +		printf("invalid magic\n");
    5.82 +		return -EINVAL;
    5.83 +	}
    5.84 +	if(sb->ver > FS_VER) {
    5.85 +		printf("invalid version: %d\n", sb->ver);
    5.86 +		return -EINVAL;
    5.87 +	}
    5.88 +	if(sb->blksize != BLKSZ) {
    5.89 +		printf("invalid block size: %d\n", sb->blksize);
    5.90 +		return -EINVAL;
    5.91 +	}
    5.92  
    5.93 -#ifdef KERNEL
    5.94 -	if(find_rootfs(&root) == -1) {
    5.95 -		panic("can't find root filesystem\n");
    5.96 +	/* allocate and populate in-memory bitmaps */
    5.97 +	if(!(sb->ibm = malloc(sb->ibm_count * sb->blksize))) {
    5.98 +		return -ENOMEM;
    5.99  	}
   5.100 -#endif
   5.101 +	if(blk_read(bdev, sb->ibm_start, sb->ibm_count, sb->ibm) == -1) {
   5.102 +		printf("failed to read inode bitmap\n");
   5.103 +		free(sb->ibm);
   5.104 +		return -EIO;
   5.105 +	}
   5.106 +	if(!(sb->bm = malloc(sb->bm_count * sb->blksize))) {
   5.107 +		free(sb->ibm);
   5.108 +		return -ENOMEM;
   5.109 +	}
   5.110 +	if(blk_read(bdev, sb->bm_start, sb->bm_count, sb->bm) == -1) {
   5.111 +		printf("failed to read block bitmap\n");
   5.112 +		free(sb->ibm);
   5.113 +		free(sb->bm);
   5.114 +		return -EIO;
   5.115 +	}
   5.116 +
   5.117 +	return 0;
   5.118  }
   5.119 -
   5.120 -
   5.121 -#ifdef KERNEL
   5.122 -#define PART_TYPE	0xcc
   5.123 -static int find_rootfs(struct filesys *fs)
   5.124 -{
   5.125 -	int i, num_dev, partid;
   5.126 -	struct partition *plist, *p;
   5.127 -
   5.128 -	num_dev = ata_num_devices();
   5.129 -	for(i=0; i<num_dev; i++) {
   5.130 -		plist = p = get_part_list(i);
   5.131 -
   5.132 -		partid = 0;
   5.133 -		while(p) {
   5.134 -			if(get_part_type(p) == PART_TYPE) {
   5.135 -				/* found the correct partition, now read the superblock
   5.136 -				 * and make sure it's got the correct magic id
   5.137 -				 */
   5.138 -				readblock(i, p->start_sect / 2 + 1, fs->sb);
   5.139 -
   5.140 -				if(fs->sb->magic == MAGIC) {
   5.141 -					printf("found root ata%dp%d\n", i, partid);
   5.142 -					fs->dev = i;
   5.143 -					fs->part = *p;
   5.144 -					return 0;
   5.145 -				}
   5.146 -			}
   5.147 -			p = p->next;
   5.148 -			partid++;
   5.149 -		}
   5.150 -		free_part_list(plist);
   5.151 -	}
   5.152 -	return -1;
   5.153 -}
   5.154 -
   5.155 -#define NSECT	(BLKSZ / 512)
   5.156 -
   5.157 -static int readblock(struct block_device *bdev, uint32_t blk, void *buf)
   5.158 -{
   5.159 -	return blk_read(bdev, blk, buf);
   5.160 -}
   5.161 -
   5.162 -static int writeblock(struct block_device *bdev, uint32_t blk, void *buf)
   5.163 -{
   5.164 -	return blk_write(bdev, blk, buf);
   5.165 -}
   5.166 -#else
   5.167 -
   5.168 -/* if this is compiled as part of the user-space tools instead of the kernel
   5.169 - * forward the call to a user read/write block function supplied by the app.
   5.170 - */
   5.171 -int user_readblock(uint32_t, void*);
   5.172 -int user_writeblock(uint32_t, void*);
   5.173 -
   5.174 -static int readblock(struct block_device *bdev, uint32_t blk, void *buf)
   5.175 -{
   5.176 -	return user_readblock(blk, buf);
   5.177 -}
   5.178 -
   5.179 -static int writeblock(struct block_device *bdev, uint32_t blk, void *buf)
   5.180 -{
   5.181 -	return user_writeblock(blk, buf);
   5.182 -}
   5.183 -#endif	/* KERNEL */
     6.1 --- a/src/fs.h	Fri Dec 09 15:29:54 2011 +0200
     6.2 +++ b/src/fs.h	Sun Dec 11 10:17:58 2011 +0200
     6.3 @@ -4,6 +4,7 @@
     6.4  #include <inttypes.h>
     6.5  
     6.6  #define MAGIC	0xccf5ccf5
     6.7 +#define FS_VER	1
     6.8  #define BLKSZ	1024
     6.9  
    6.10  #define SECT_TO_BLK(x)	((x) / (BLKSZ / 512))
    6.11 @@ -29,18 +30,15 @@
    6.12  	/* inode table start and count */
    6.13  	blkid itbl_start;
    6.14  	unsigned int itbl_count;
    6.15 -	/* data block allocation bitmap start and count */
    6.16 -	blkid dbm_start;
    6.17 -	unsigned int dbm_count;
    6.18 -	/* data blocks start and count */
    6.19 -	blkid data_start;
    6.20 -	unsigned int data_count;
    6.21 +	/* block allocation bitmap start and count */
    6.22 +	blkid bm_start;
    6.23 +	unsigned int bm_count;
    6.24  
    6.25  	int root_ino;	/* root direcotry inode */
    6.26  
    6.27  	/* the following are valid only at runtime, ignored on disk */
    6.28 -	uint32_t *ibm;	/* memory inode bitmap */
    6.29 -	uint32_t *dbm;	/* memory datablock bitmap */
    6.30 +	uint32_t *ibm;	/* in-memory inode bitmap */
    6.31 +	uint32_t *bm;	/* in-memory block bitmap */
    6.32  
    6.33  } __attribute__((packed));
    6.34  
    6.35 @@ -60,6 +58,20 @@
    6.36  } __attribute__((packed));
    6.37  
    6.38  
    6.39 +struct filesys {
    6.40 +	struct block_device *bdev;
    6.41 +	struct partition part;
    6.42 +
    6.43 +	struct superblock *sb;
    6.44 +
    6.45 +	struct filesys *next;
    6.46 +};
    6.47 +
    6.48 +/* defined in fs.c */
    6.49 +int openfs(struct filesys *fs, dev_t dev);
    6.50 +int find_inode(const char *path);
    6.51 +
    6.52 +/* defined in fs_sys.c */
    6.53  int sys_mount(char *mntpt, char *devname, unsigned int flags);
    6.54  int sys_umount(char *devname);
    6.55  
    6.56 @@ -70,7 +82,5 @@
    6.57  int sys_write(int fd, void *buf, int sz);
    6.58  long sys_lseek(int fd, long offs, int from);
    6.59  
    6.60 -int lookup_path(const char *path);
    6.61 -
    6.62  
    6.63  #endif	/* FS_H_ */
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/fs_sys.c	Sun Dec 11 10:17:58 2011 +0200
     7.3 @@ -0,0 +1,105 @@
     7.4 +/* implementation of the filesystem-related syscalls */
     7.5 +
     7.6 +#include <stdio.h>
     7.7 +#include <stdlib.h>
     7.8 +#include <string.h>
     7.9 +#include <assert.h>
    7.10 +#include <errno.h>
    7.11 +#include "fs.h"
    7.12 +#include "part.h"
    7.13 +#include "panic.h"
    7.14 +#include "bdev.h"
    7.15 +
    7.16 +static dev_t find_rootfs(void);
    7.17 +
    7.18 +/* list of mounted filesystems
    7.19 + * XXX currently only one, the root filesystem
    7.20 + */
    7.21 +static struct filesys *fslist;
    7.22 +
    7.23 +
    7.24 +int sys_mount(char *mtpt, char *devname, unsigned int flags)
    7.25 +{
    7.26 +	dev_t dev;
    7.27 +	int err;
    7.28 +	struct filesys *fs;
    7.29 +
    7.30 +	if(strcmp(mtpt, "/") != 0) {
    7.31 +		printf("only root can be mounted at the moment\n");
    7.32 +		return -EBUG;
    7.33 +	}
    7.34 +
    7.35 +	/* mounting root filesystem */
    7.36 +	if(fslist) {
    7.37 +		printf("root already mounted\n");
    7.38 +		return -EBUSY;
    7.39 +	}
    7.40 +
    7.41 +	if(devname) {
    7.42 +		dev = bdev_by_name(devname);
    7.43 +	} else {
    7.44 +		/* try to autodetect it */
    7.45 +		dev = find_rootfs();
    7.46 +	}
    7.47 +	if(!dev) {
    7.48 +		err = -ENOENT;
    7.49 +		goto rootfail;
    7.50 +	}
    7.51 +
    7.52 +	if(!(fs = malloc(sizeof *fslist))) {
    7.53 +		err = -ENOMEM;
    7.54 +		goto rootfail;
    7.55 +	}
    7.56 +	if((err = openfs(fs, dev)) != 0) {
    7.57 +		free(fs);
    7.58 +		goto rootfail;
    7.59 +	}
    7.60 +
    7.61 +	fslist = fs;
    7.62 +	return 0;
    7.63 +
    7.64 +rootfail:
    7.65 +	panic("failed to mount root filesystem: %d\n", -err);
    7.66 +	return err;	/* unreachable */
    7.67 +}
    7.68 +
    7.69 +#define PART_TYPE	0xcc
    7.70 +static dev_t find_rootfs(void)
    7.71 +{
    7.72 +	dev_t dev = 0;
    7.73 +	int i, num_dev, partid;
    7.74 +	struct partition *plist, *p;
    7.75 +	struct superblock *sb = malloc(BLKSZ);
    7.76 +	char name[16];
    7.77 +
    7.78 +	assert(sb);
    7.79 +
    7.80 +	num_dev = ata_num_devices();
    7.81 +	for(i=0; i<num_dev; i++) {
    7.82 +		plist = p = get_part_list(i);
    7.83 +
    7.84 +		partid = 0;
    7.85 +		while(p) {
    7.86 +			if(get_part_type(p) == PART_TYPE) {
    7.87 +				/* found the correct partition, now read the superblock
    7.88 +				 * and make sure it's got the correct magic id
    7.89 +				 */
    7.90 +				blk_read(i, p->start_sect / 2 + 1, BLKSZ, sb);
    7.91 +
    7.92 +				if(sb->magic == MAGIC) {
    7.93 +					sprintf(name, "ata%dp%d", i, partid);
    7.94 +					printf("found root: %s\n", name);
    7.95 +					dev = bdev_by_name(name);
    7.96 +					break;
    7.97 +				}
    7.98 +			}
    7.99 +			p = p->next;
   7.100 +			partid++;
   7.101 +		}
   7.102 +		free_part_list(plist);
   7.103 +		if(dev) break;
   7.104 +	}
   7.105 +
   7.106 +	free(sb);
   7.107 +	return dev;
   7.108 +}