// This is NEW CODE to replace old fs.h header, defining on-disk filesystem // layout used by mkfs and the kernel. #ifndef _FSFORMAT_H #define _FSFORMAT_H typedef unsigned int fsformat_uint32_t; typedef long long fsformat_int64_t; typedef unsigned short fsformat_uint16_t; typedef short fsformat_int16_t; typedef struct fsformat_superblock fsformat_superblock_t; typedef struct fsformat_inode fsformat_inode_t; typedef struct fsformat_dirent_v0 fsformat_dirent_v0_t; typedef struct fsformat_dirent_v1 fsformat_dirent_v1_t; // The "old" magic number is used to mark "version 0" or xv6-compatible // filysystems. #define FSFORMAT_MAGIC_OLD 0x10203040 // The "new" magic number is used to mark filesystems which are above // or equal to "version 1". These share the same superblock structure // except with extended fields and options. #define FSFORMAT_MAGIC_NEW 0x102030F0 struct fsformat_superblock { // The first eight fields are compatible with xv6 filesystem (provided // that the block size etc. match your fork of xv6!) fsformat_uint32_t magic; fsformat_uint32_t totalblocks; fsformat_uint32_t datablocks; fsformat_uint32_t inodelimit; fsformat_uint32_t logblocks; fsformat_uint32_t firstlogblock; fsformat_uint32_t firstinodeblock; fsformat_uint32_t firstbitmapblock; // The rest of the fields will only be usable if the "magic" field is // equal to FSFORMAT_MAGIC_NEW. These are partly used to detect or // confirm filesystem settings such as block size. // Simple version number & FLAGS. The lower 8 bits is used for // the simple version (e.g. 1 for version 1), the upper 24 bits may // be used for additional flags, minor versions etc. in later versions // but are set to zero for version 1. fsformat_uint32_t extd_versionflags; // Block size in bytes. fsformat_uint32_t extd_blocksize; // Superblock structure size in bytes (i.e. to detect which extended // fields are usable. fsformat_uint32_t extd_superblocksize; // Inode structure size. fsformat_uint32_t extd_inodestructsize; // Filename length. fsformat_uint32_t extd_filenamesize; // Inode reference size. Either set to 2 or 4, or special numbers for // other special formats in the future. fsformat_uint32_t extd_inoderefsize; // Number of direct blocks per inode for storing data in the first // few blocks of a file. fsformat_uint32_t extd_directblocks; // Number of indirect blocks per inode for storing additional data of // large files fsformat_uint32_t extd_indirectblocks; }; #define FSFORMAT_DIRECTBLOCKS 12 struct fsformat_inode { fsformat_int16_t type; fsformat_int16_t device_major; fsformat_int16_t device_minor; fsformat_int16_t linkcount; fsformat_uint32_t totalbytes; fsformat_uint32_t addrs[FSFORMAT_DIRECTBLOCKS + 1]; }; #define FSFORMAT_NAMESIZE_OLD 14 struct fsformat_dirent_v0 { fsformat_uint16_t inodenumber; char filename[FSFORMAT_NAMESIZE_OLD]; }; #define FSFORMAT_NAMESIZE_NEW 120 struct fsformat_dirent_v1 { fsformat_uint32_t datainode; fsformat_uint32_t metainode; char filename[FSFORMAT_NAMESIZE_NEW]; }; // The "big" dirent structure is used for conveying dirent information // to userland, and so allows exceptionally large name sizes and dir // info. This isn't really implemented yet but can be for consistency. #define FSFORMAT_NAMESIZE_BIG 2032 struct fsformat_dirent_big { fsformat_int64_t datainode; fsformat_int64_t metainode; char filename[FSFORMAT_NAMESIZE_BIG]; }; // From ifndef at top of file: #endif