code: mafs

ref: b3ccded71dc0330ba63fdb7d7a0e6fc6ded1657e
dir: /dat.h/

View raw version
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 */

	NTLOCK	= 200,	/* number of active file Tlocks */
	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;

/* from kfs, might have to be removed */
typedef	struct	Filta	Filta;
typedef	struct	Filter	Filter;
typedef	struct	P9call	P9call;
typedef	struct	Tlock	Tlock;
typedef	struct	Uid	Uid;
typedef	struct	Wpath	Wpath;
typedef struct	AuthRpc	AuthRpc;

/*
 * 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 */

	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

/*
 * for load stats
 */
struct Filter
{
	u64	count;			/* count and old count kept separate */
	u64	oldcount;		/* so interrput can read them */
	/* Float	filter[3];*/		/* filters for 1m 10m 100m */ 
};

struct Filta
{
	Filter*	f;
	int	scale;
};

/*
 * array of qids that are locked
 */
struct Tlock
{
	u64 time;
	u64 qpath;
	u64 dblockno;
};

struct Aux
{
	u64 dblkno; /* dentry absolute block number */
	u16 uid;
	Tlock *tlock;	/* for exclusive use files */
	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 numberss 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 */
};

/*
 * open modes passed into P9 open/create
 */
enum
{
	MREAD	= 0,
	MWRITE,
	MBOTH,
	MEXEC,
	MTRUNC	= (1<<4),	/* truncate on open */
	MCEXEC	= (1<<5),	/* close on exec (host) */
	MRCLOSE	= (1<<6),	/* remove on close */
};

/*
 * check flags
 */
enum
{
	Crdall	= (1<<0),	/* read all files */
	Ctag	= (1<<1),	/* rebuild tags */
	Cpfile	= (1<<2),	/* print files */
	Cpdir	= (1<<3),	/* print directories */
	Cfree	= (1<<4),	/* rebuild free list */
	Cream	= (1<<6),	/* clear all bad tags */
	Cbad	= (1<<7),	/* clear all bad blocks */
	Ctouch	= (1<<8),	/* touch old dir and indir */
	Cquiet	= (1<<9),	/* report just nasty things */
};

/*
 * console cons.flag flags
 */
enum
{
	Fchat	= (1<<0),	/* print out filesys rpc traffic */
	Fuid	= (1<<2),	/* print out uids */
				/* debugging flags for drivers */
};

struct	Cons
{
	int	flags;		/* overall flags for all channels */
	int	uid;		/* botch -- used to get uid on cons_create */
	int	gid;		/* botch -- used to get gid on cons_create */
	int	allow;		/* no-protection flag */
	u64	offset;		/* used to read files, c.f. fchar */
	char*	arg;		/* pointer to remaining line */

	Filter	work;		/* thruput in messages */
	Filter	rate;		/* thruput in bytes */
	Filter	bhit;		/* getbufs that hit */
	Filter	bread;		/* getbufs that miss and read */
	Filter	binit;		/* getbufs that miss and dont read */
	Filter	tags[MAXTAG];	/* reads of each type of block */
};

#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)

#define	CHAT(cp)	(chat)
#define	QID9P1(a,b)	(Qid9p1){a,b}

extern	char*	errstring[MAXERR];
extern	Tlock	*tlocks;
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	*progname;
extern	char	*procname;

extern Config config;