ref: b5d191e8cfa4fac05a02ea309df2541a2652ff23
dir: /dat.h/
typedef signed char s8; typedef signed short s16; typedef signed int s32; typedef signed long long s64; typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; typedef unsigned long long u64; enum { KiB = 1024ULL, /* Kibibytes */ MiB = KiB*KiB, /* Mibibytes */ GiB = KiB*MiB, /* Gibibytes */ TiB = KiB*GiB, /* Tibibytes */ Nusers = 32, /* max. number of users */ None = 0, /* user ID for "none" */ Noworld = 9999, /* conventional id for "noworld" group */ Userlen = 32, Nsec = 1000ULL*1000*1000, Usec = 1000ULL*1000, Msec = 1000ULL, MAXRPC = 8192ULL, Nbkp = 2, /* Qpnone is the Tag.path of free blocks/extents(Tfree), and zero'ed out dentry blocks */ Qpnone = 0, Qpmagic = 1, /* magic block Tag.qpath */ Qpconfig = 2, /* /adm/config block Tag.qpath */ Qpsuper = 3, /* /adm/super block Tag.qpath */ Qpadm = 5, /* /adm */ Qpusers = 6, /* /adm/users */ Qpbkp = 7, /* /adm/bkp block Tag.qpath */ Qpconfig0 = 8, /* /adm/bkp/config.0 block Tag.qpath */ Qpsuper0 = 9, /* /adm/bkp/super.0 block Tag.qpath */ Qproot0 = 10, /* /adm/bkp/root.0 block Tag.qpath */ Qpconfig1 = 11, /* /adm/bkp/config.1 block Tag.qpath */ Qpsuper1 = 12, /* /adm/bkp/super.1 block Tag.qpath */ Qproot1 = 13, /* /adm/bkp/root.1 block Tag.qpath */ Qpctl = 14, /* /adm/ctl */ Qpfrees = 15, /* /adm/frees block Tag.qpath */ Nqidgen = 64, Qproot = Nqidgen-1, /* /, so fscreate() can disallow any create's below */ /* check qpath for overflows - TODO, should be 2^64 */ Maxqpath = 72057594037927936ULL, /* 2^56 */ }; /* * fundamental constants and types of the implementation * changing any of these changes the layout on disk * The very first block (index = 0) has the magic written at offset 256. */ enum { Rawblocksize= 512ULL, /* real block size */ Ndblock = 32, /* number of direct blocks in a Dentry */ Niblock = 6, /* maximum depth of indirect blocks */ /* global block numbers. The bkp contents locations are calculated by ream() */ Bmagicb = 0, /* block number of first block. Bmagic conflicts with bio.h */ Bconfig = 1, /* block number of config contents */ Bsuper = 2, /* block number of super contents */ Broot = 3, /* block number of root directory */ Badm = 4, /* block number of /adm directory */ Bdconfig = 5, /* block number of /adm/config dentry */ Bdsuper = 6, /* block number of /adm/super dentry */ Bdusers = 7, /* block number of /adm/users file */ Busers = 8, /* block number of /adm/users file contents */ Bbkp = 9, /* block number of /adm/bkp directory */ Bdconfig0 = 10, /* block number of /adm/bkp/config.0 dentry */ Bdsuper0 = 11, /* block number of /adm/bkp/super.0 dentry */ Bdroot0 = 12, /* block number of /adm/bkp/root.0 dentry */ Bdconfig1 = 13, /* block number of /adm/bkp/config.1 dentry */ Bdsuper1 = 14, /* block number of /adm/bkp/super.1 dentry */ Bdroot1 = 15, /* block number of /adm/bkp/root.1 dentry */ Bdctl = 16, /* block number of /adm/ctl dentry, empty contents, virtual file */ Bdfrees = 17, /* block number of /adm/frees dentry, text file of free extents */ Nbused, /* blocks used up by default */ Nminblocks = Nbused+(Nbkp*3), /* number of blocks used by the above and the backup blocks */ Nthdirty = 9, /* dirty byte is the 9th byte in the Tag */ }; typedef struct Config Config; typedef struct Content Content; typedef struct Dentry1 Dentry1; typedef struct Dentry Dentry; typedef struct Fblock Fblock; typedef struct Qid9p1 Qid9p1; typedef union Rabuf Rabuf; typedef struct Super1 Super1; typedef struct Superb Superb; typedef struct Tag Tag; typedef struct User User; typedef struct Aux Aux; typedef struct Log Log; typedef struct P9call P9call; typedef struct Tlock Tlock; typedef struct Uid Uid; /* * DONT TOUCH -- data structures stored on disk */ #pragma pack on /* DONT TOUCH, this is the disk structure */ struct Tag { u8 type; /* Tmagic, Tdentry, Tdata, Tindn */ u64 path; /* Qid.path, unique identifier */ }; /* DONT TOUCH, this is the disk structure */ struct Super1 { u64 start; /* starting block */ u64 tfree; /* total number of free blocks - obsolete? */ u64 qidgen; /* generator for unique ids. starts from 1024. */ u64 frees; /* list of free extents was written here at halt */ /* make fsok a time stamp with the highest bit being the fsok flag */ u64 fsok; /* fsck status, using 64 bits to keep it all aligned */ }; /* DONT TOUCH, this is the disk structure */ struct Qid9p1 { u32 version; u64 path; /* unique identifier */ }; /* DONT TOUCH, this is the disk structure */ /* * 1 dentry per block * no access time */ struct Dentry1 { Qid9p1 qid; u64 size; /* 0 for directories. For files, size in bytes of the content */ u64 pdblkno; /* block number of the parent directory entry. Will be 0 for root. */ u64 pqpath; /* parent qid.path */ u64 mtime; /* modified time in nano seconds from epoch */ u32 mode; /* same bits as defined in /sys/include/libc.h:/Dir\.mode/ */ s16 uid; s16 gid; s16 muid; u64 dblocks[Ndblock]; /* direct blocks. */ /* List of Tdata block numbers for files and Tdentry block numbers for directories */ /* Tag.type = Tdentry for directories and Tdata for files */ u64 iblocks[Niblock]; /* indirect blocks */ }; #pragma pack off /* * derived constants * Ndentriesperblock number of Dentry's in a block * Nindperblock number of block pointers in a block */ enum { Blocksize = Rawblocksize - sizeof(Tag), Namelen = (Blocksize-sizeof(Dentry1)), /* maximum size of the name of a file or directory */ Iounit = MAXRPC, /* in bytes */ Ntogether = (Iounit/Blocksize)+1, /* max probable size for jumbo writes */ Ndentryperblock = 1, /* Blocksize/sizeof(Dentry), */ Nindperblock = Blocksize/sizeof(u64),/* number of pointers per block */ }; #pragma pack on /* DONT TOUCH, this is the disk structure */ struct Dentry { struct Dentry1; char name[Namelen]; }; struct Content /* used to unmarshall the disk contents */ { union{ u8 buf[Blocksize]; u64 bufa[Nindperblock]; Dentry d; }; Tag; }; #pragma pack off #pragma pack on /* DONT TOUCH, this is the disk structure */ struct Superb { Super1; }; #pragma pack off /* * array of qids that are locked */ struct Tlock { u64 time; u64 qpath; u64 dblkno; Tlock *prev, *next; }; struct Aux { u64 dblkno; /* dentry absolute block number */ u16 uid; u8 tlocked; /* for exclusive use files, flag to indicate lock */ u64 dri; /* directory index while reading a directory */ /* u64 lastreadahead; TODO */ }; struct User { s16 id; /* user id */ s16 lid; /* id of the leader of group */ s16 members[Nusers]; /* group table, member id's */ int nmembers; /* number of group entries */ char name[Userlen]; /* user name */ User *next; }; struct Bkp { u64 srcbno; /* source of the backup */ u64 dest[Nbkp]; /* destinations written to */ }; struct Config { u64 size; /* size from dirfstat */ u64 nblocks; /* size in blocks */ struct Bkp config; struct Bkp super; struct Bkp root; char service[Namelen]; }; enum { Nworks = 1024, /* make this a parameter? */ Nprocs = 32, /* make this a parameter? */ Nlru = 32, }; /* * error codes generated from the file server */ enum { Eaccess = 1, Ealloc, Eauth, Eauthmsg, Ebadname, Ebadspc, Ebadu, Ebroken, Echar, Econvert, Ecount, Edir1, Edir2, Edirty, Edot, Eempty, Eentry, Eexist, Efid, Efidinuse, Efull, Einval, Elocked, Emode, Ename, Enomem, Enotd, Enotdir, Enotg, Enotl, Enotm, Enotu, Enotw, Eoffset, Eopen, Eperm, Ephase, Eqid, Eqidmode, Eronly, Ersc, Eshutdown, Esystem, Etoolong, Etoou64, Ewalk, MAXERR }; /* * tags on block */ /* DONT TOUCH, this is in disk structures */ /* also, the order from Tdata to Tmaxind is exploited in indirck() & isdirty() */ enum { Tblank = 0, Tfree = 0, /* free block */ Tnone = 0, Tmagic, /* the first (zero'th) block holds the magic */ Tdentry, /* directory entry */ /* Tdata & indirect blocks are last, to allow for greater depth */ Tdata, /* actual file contents */ Tind0, /* contains a list of Tdata block numbers for files and Tdentry block numbers for directories.*/ Tind1, /* contains a list of Tind0 block numbers */ Tind2, /* contains a list of Tind1 block numbers */ Tind3, /* contains a list of Tind2 block numbers */ Tind4, /* contains a list of Tind3 block numbers */ Tind5, /* contains a list of Tind4 block numbers, maximum file size 26 TiB */ Maxtind, /* should be Tind0+Niblock */ /* gap for more indirect block depth in future */ MAXTAG, Tmaxind = Maxtind - 1, }; /* * flags to getbuf */ enum { Breadonly = 1,/* read the block, cannot write to it */ Bwritable = 0, Bfreshalloc = 1,/* newly allocated block, no contents on the disk */ Bused = 0,/* has contents on the disk */ }; #define SECOND(n) (n) #define MINUTE(n) (n*SECOND(60)) #define HOUR(n) (n*MINUTE(60)) #define DAY(n) (n*HOUR(24)) #define TLOCK MINUTE(5) extern char* errstring[MAXERR]; extern char service[Namelen]; extern char *tagnames[]; extern char *devfile; /* device file path */ extern int devfd ; /* device fd */ extern int writeallow; extern int wstatallow; extern int allownone; extern u8 readonly; extern u8 shuttingdown; extern u8 noauth; /* used by panic() */ extern char *procname; extern Config config;