os_kernel_lab/code/lab8/kern/fs/sfs/sfs.h
2012-08-22 12:32:13 +08:00

130 lines
5.8 KiB
C

#ifndef __KERN_FS_SFS_SFS_H__
#define __KERN_FS_SFS_SFS_H__
#include <defs.h>
#include <mmu.h>
#include <list.h>
#include <sem.h>
#include <unistd.h>
/*
* Simple FS (SFS) definitions visible to ucore. This covers the on-disk format
* and is used by tools that work on SFS volumes, such as mksfs.
*/
#define SFS_MAGIC 0x2f8dbe2a /* magic number for sfs */
#define SFS_BLKSIZE PGSIZE /* size of block */
#define SFS_NDIRECT 12 /* # of direct blocks in inode */
#define SFS_MAX_INFO_LEN 31 /* max length of infomation */
#define SFS_MAX_FNAME_LEN FS_MAX_FNAME_LEN /* max length of filename */
#define SFS_MAX_FILE_SIZE (1024UL * 1024 * 128) /* max file size (128M) */
#define SFS_BLKN_SUPER 0 /* block the superblock lives in */
#define SFS_BLKN_ROOT 1 /* location of the root dir inode */
#define SFS_BLKN_FREEMAP 2 /* 1st block of the freemap */
/* # of bits in a block */
#define SFS_BLKBITS (SFS_BLKSIZE * CHAR_BIT)
/* # of entries in a block */
#define SFS_BLK_NENTRY (SFS_BLKSIZE / sizeof(uint32_t))
/* file types */
#define SFS_TYPE_INVAL 0 /* Should not appear on disk */
#define SFS_TYPE_FILE 1
#define SFS_TYPE_DIR 2
#define SFS_TYPE_LINK 3
/*
* On-disk superblock
*/
struct sfs_super {
uint32_t magic; /* magic number, should be SFS_MAGIC */
uint32_t blocks; /* # of blocks in fs */
uint32_t unused_blocks; /* # of unused blocks in fs */
char info[SFS_MAX_INFO_LEN + 1]; /* infomation for sfs */
};
/* inode (on disk) */
struct sfs_disk_inode {
uint32_t size; /* size of the file (in bytes) */
uint16_t type; /* one of SYS_TYPE_* above */
uint16_t nlinks; /* # of hard links to this file */
uint32_t blocks; /* # of blocks */
uint32_t direct[SFS_NDIRECT]; /* direct blocks */
uint32_t indirect; /* indirect blocks */
// uint32_t db_indirect; /* double indirect blocks */
// unused
};
/* file entry (on disk) */
struct sfs_disk_entry {
uint32_t ino; /* inode number */
char name[SFS_MAX_FNAME_LEN + 1]; /* file name */
};
#define sfs_dentry_size \
sizeof(((struct sfs_disk_entry *)0)->name)
/* inode for sfs */
struct sfs_inode {
struct sfs_disk_inode *din; /* on-disk inode */
uint32_t ino; /* inode number */
bool dirty; /* true if inode modified */
int reclaim_count; /* kill inode if it hits zero */
semaphore_t sem; /* semaphore for din */
list_entry_t inode_link; /* entry for linked-list in sfs_fs */
list_entry_t hash_link; /* entry for hash linked-list in sfs_fs */
};
#define le2sin(le, member) \
to_struct((le), struct sfs_inode, member)
/* filesystem for sfs */
struct sfs_fs {
struct sfs_super super; /* on-disk superblock */
struct device *dev; /* device mounted on */
struct bitmap *freemap; /* blocks in use are mared 0 */
bool super_dirty; /* true if super/freemap modified */
void *sfs_buffer; /* buffer for non-block aligned io */
semaphore_t fs_sem; /* semaphore for fs */
semaphore_t io_sem; /* semaphore for io */
semaphore_t mutex_sem; /* semaphore for link/unlink and rename */
list_entry_t inode_list; /* inode linked-list */
list_entry_t *hash_list; /* inode hash linked-list */
};
/* hash for sfs */
#define SFS_HLIST_SHIFT 10
#define SFS_HLIST_SIZE (1 << SFS_HLIST_SHIFT)
#define sin_hashfn(x) (hash32(x, SFS_HLIST_SHIFT))
/* size of freemap (in bits) */
#define sfs_freemap_bits(super) ROUNDUP((super)->blocks, SFS_BLKBITS)
/* size of freemap (in blocks) */
#define sfs_freemap_blocks(super) ROUNDUP_DIV((super)->blocks, SFS_BLKBITS)
struct fs;
struct inode;
void sfs_init(void);
int sfs_mount(const char *devname);
void lock_sfs_fs(struct sfs_fs *sfs);
void lock_sfs_io(struct sfs_fs *sfs);
void unlock_sfs_fs(struct sfs_fs *sfs);
void unlock_sfs_io(struct sfs_fs *sfs);
int sfs_rblock(struct sfs_fs *sfs, void *buf, uint32_t blkno, uint32_t nblks);
int sfs_wblock(struct sfs_fs *sfs, void *buf, uint32_t blkno, uint32_t nblks);
int sfs_rbuf(struct sfs_fs *sfs, void *buf, size_t len, uint32_t blkno, off_t offset);
int sfs_wbuf(struct sfs_fs *sfs, void *buf, size_t len, uint32_t blkno, off_t offset);
int sfs_sync_super(struct sfs_fs *sfs);
int sfs_sync_freemap(struct sfs_fs *sfs);
int sfs_clear_block(struct sfs_fs *sfs, uint32_t blkno, uint32_t nblks);
int sfs_load_inode(struct sfs_fs *sfs, struct inode **node_store, uint32_t ino);
#endif /* !__KERN_FS_SFS_SFS_H__ */