#ifndef __KERN_FS_SFS_SFS_H__ #define __KERN_FS_SFS_SFS_H__ #include #include #include #include #include /* * 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__ */