forsyth20121205-174063a80cc13 years agoHistory
335 lines · 9.4 KB · C
RawDownload
typedef struct DataBlock DataBlock;typedef struct Extent Extent;typedef struct Entry Entry;typedef struct ExtentList ExtentList;typedef struct Fid Fid;typedef struct Map Map;typedef struct GroupSet GroupSet;typedef struct Group Group;typedef struct Uname Uname;typedef struct LogMessage LogMessage;typedef struct LogSegment LogSegment;typedef struct Path Path;typedef struct DirReadState DirReadState; typedef struct Map PathMap;typedef struct Map FidMap;typedef struct Map GroupMap;typedef struct Map UnameMap;typedef struct Map Ust; #pragma incomplete Extent#pragma incomplete ExtentList#pragma incomplete Map#pragma incomplete DirReadState enum {	L2LogSweeps = 2,	L2BlockCopies = 2,	LogDataLimit = 128,	LogAddr = (1 << 31),	Replacements = 2,		/* extra space for replacements */	Transfers = 2,			/* extra space available for transfers */	LogSlack = 1,			/* extra space for data allocation */}; struct Extent {	u32int min, max;	u32int flashaddr;		/* encode block index, page number, and offset within page to min */}; char *logfsextentlistnew(ExtentList **);void logfsextentlistfree(ExtentList **);char *logfsextentlistinsert(ExtentList *, Extent *, Extent **);int logfsextentlistwalk(ExtentList *, int (*)(void *, Extent *, int),void *);Extent *logfsextentlistmatch(ExtentList *, Extent *);int logfsextentlistwalkrange(ExtentList *,	int (*)(void *, u32int, u32int, Extent *, u32int),	void *, u32int, u32int);int logfsextentlistmatchall(ExtentList *, int (*)(void *, Extent *), void *, Extent *);void logfsextentlistreset(ExtentList *); struct Entry {	int inuse;	int deadandgone;	/* removed */	Qid qid;	struct Entry *parent;	char *name;	char *uid;	char *gid;	ulong mtime;	char *muid;	u32int perm;	struct Entry *next;	struct {		struct {			ulong cvers;			ulong length;			ExtentList *extent;		} file;		struct {			struct Entry *list;		} dir;	} u;}; char *logfsentrynew(LogfsServer *, int, u32int, Entry *,	char *, char *, char *,	u32int, char *, u32int, ulong, ulong, Entry **);void logfsentryclunk(Entry *); void logfsdrsfree(DirReadState **); struct Fid {	ulong fid;	int openmode;	Entry *entry;	char *uname;	DirReadState *drs;}; typedef int LOGFSMAPWALKFN(void*, void*);char *logfsmapnew(int, int (*)(void*, int), int (*)(void*, void*), int (*)(void*), void (*)(void*), Map **);void logfsmapfree(Map **);char *logfsmapnewentry(Map*, void*, void **);void *logfsmapfindentry(Map*, void*);int logfsmapdeleteentry(Map*, void*);int logfsmapwalk(Map*, LOGFSMAPWALKFN*, void*); char *logfsfidmapnew(FidMap **);#define logfsfidmapfree(mp) logfsmapfree(mp)char *logfsfidmapnewentry(FidMap *, ulong, Fid **);#define logfsfidmapfindentry(m, fid) logfsmapfindentry(m, (void *)fid)int logfsfidmapclunk(FidMap *, ulong); struct Logfs {	int trace;}; char *logfsustnew(Ust**);#define logfsustfree(m) logfsmapfree((m))char *logfsustadd(Ust*, char*); struct Group {	char *uid;	char *uname;	Group *leader;	GroupSet *members;}; struct Uname {	char *uname;	Group *g;}; struct LogfsIdentityStore {	Ust *ids;	GroupMap *groupmap;	UnameMap *unamemap;}; char *logfsgroupmapnew(GroupMap **, UnameMap **);#define logfsgroupmapfree(mp) logfsmapfree(mp)#define logfsunamemapfree(mp) logfsmapfree(mp)char *logfsgroupmapnewentry(GroupMap *, UnameMap *, char *, char *, Group **, Uname **);#define logfsgroupmapdeleteentry(m, uid) logfsmapdeleteentry(m, (void *)uid)#define logfsgroupmapfindentry(m, uid) logfsmapfindentry(m, uid)#define logfsunamemapfindentry(m, uname) logfsmapfindentry(m, uname)char *logfsgroupmapfinduname(GroupMap *, char *);char *logfsunamemapfinduid(UnameMap *, char *);#define logfsunamemapdeleteentry(m, uname) logfsmapdeleteentry(m, (void *)uname) typedef int LOGFSGROUPSETWALKFN(void *, Group *);char *logfsgroupsetnew(GroupSet **);void logfsgroupsetfree(GroupSet **);int logfsgroupsetadd(GroupSet *, Group *);int logfsgroupsetremove(GroupSet *, Group *);int logfsgroupsetwalk(GroupSet *, LOGFSGROUPSETWALKFN *, void *);int logfsgroupsetismember(GroupSet *, Group *);char *logfsisfindidfromname(LogfsIdentityStore *, char *);char *logfsisfindnamefromid(LogfsIdentityStore *, char *);#define logfsisfindgroupfromid(is, id) logfsgroupmapfindentry((is)->groupmap, id)Group *logfsisfindgroupfromname(LogfsIdentityStore *, char *);#define logfsisustadd(is, s) logfsustadd((is)->ids, s)int logfsisgroupunameismember(LogfsIdentityStore *, Group *, char *);int logfsisgroupuidismember(LogfsIdentityStore *, Group *, char *);int logfsisgroupuidisleader(LogfsIdentityStore *, Group *, char *);extern char *logfsisgroupnonename; struct LogMessage {	uchar type;	u32int path;	union {		struct {			u32int nerase;		} start;		struct {			u32int perm;			u32int newpath;			u32int mtime;			u32int cvers;			char *name;			char *uid;			char *gid;		} create;		struct {			u32int mtime;			char *muid;		} remove;		struct {			u32int mtime;			u32int cvers;			char *muid;		} trunc;		struct {			u32int offset;			u32int count;			u32int mtime;			u32int cvers;			char *muid;			u32int flashaddr;			uchar *data;		} write;		struct {			char *name;			u32int perm;			char *uid;			char *gid;			u32int mtime;			char *muid;		} wstat;	} u;}; uint logfsconvM2S(uchar *, uint, LogMessage *);uint logfssizeS2M(LogMessage *);uint logfsconvS2M(LogMessage *, uchar *, uint);void logfsdumpS(LogMessage *); struct LogSegment {	int gen;				/* generation number of this log */	int dirty;				/* written to since last sweep */	long curblockindex;		/* index of block being filled, or -1 */	long unsweptblockindex;	/* next block to sweep */	int curpage;			/* page within block */	uchar *pagebuf;		/* page buffer */	int nbytes;			/* bytes used in page buffer */	long blockmap[1];		/* there are ll->blocks of these */}; char *logfslogsegmentnew(LogfsServer *, int, LogSegment **);void logfslogsegmentfree(LogSegment **);char *logfslogbytes(LogfsServer *, int, uchar *, uint);char *logfslog(LogfsServer *, int, LogMessage *);char *logfslogwrite(LogfsServer *, int, u32int, u32int, int, u32int,	u32int, char *, uchar *, u32int *);char *logfslogsegmentflush(LogfsServer *, int);int lognicesizeforwrite(LogfsServer *, int, u32int, int);char *logfsscan(LogfsServer *); struct DataBlock {	Pageset free;	Pageset dirty;	long path;			/* includes generation */	long block;}; Pageset logfsdatapagemask(int, int); struct Path {	ulong path;	Entry *entry;}; char *logfspathmapnew(PathMap **);#define logfspathmapfree(mp) logfsmapfree(mp)char *logfspathmapnewentry(PathMap *, ulong, Entry *, Path **);#define logfspathmapfindentry(m, path) (Path *)logfsmapfindentry(m, (void *)path)#define logfspathmapdeleteentry(m, path) logfsmapdeleteentry(m, (void *)path)Entry *logfspathmapfinde(PathMap *, ulong); enum {	LogfsTestDontFettleDataBlock = 1,}; struct LogfsServer {	LogfsLowLevel *ll;	LogfsBoot *lb;	FidMap *fidmap;	LogfsIdentityStore *is;	PathMap *pathmap;	LogSegment *activelog;	LogSegment *sweptlog;	long ndatablocks;	DataBlock *datablock;	ulong path;	Entry root;	int trace;	ulong openflags;	ulong testflags;}; int logfshashulong(void *, int); int logfsuserpermcheck(LogfsServer *, Entry *, Fid *, ulong);u32int logfsflattenentry(LogfsIdentityStore *, uchar *, u32int, Entry *);char *logfsreplay(LogfsServer *, LogSegment *, int);void logfsreplayfinddata(LogfsServer *); #define dataseqof(path) ((path) >> L2BlockCopies)#define copygenof(path) ((path) & ((1 << L2BlockCopies) -1))#define mkdatapath(seq, gen) (((seq) << L2BlockCopies) | (gen))#define gensucc(g, l2) (((g) + 1) & ((1 << (l2)) - 1))#define copygensucc(g) gensucc((g), L2BlockCopies)#define loggenof(path) ((path >> L2BlockCopies) & ((1 << L2LogSweeps) - 1))#define logseqof(path) ((path) >> (L2BlockCopies + L2LogSweeps))#define mklogpath(seq, gen, copygen) (((((seq) << L2LogSweeps) | (gen)) << L2BlockCopies) | (copygen))#define loggensucc(g) gensucc((g), L2LogSweeps) int logfsunconditionallymarkfreeanddirty(void *, Extent *, int);void logfsflashaddr2spo(LogfsServer *, u32int, long *, int *, int *);int logfsgn(uchar **, uchar *, char **);u32int logfsspo2flashaddr(LogfsServer *, long, int, int);int logfsgn(uchar **, uchar *, char **);void logfsflashaddr2o(LogfsServer *, u32int, int *);void logfsfreedatapages(LogfsServer *, long, Pageset);void logfsfreeanddirtydatablockcheck(LogfsServer *, long); typedef enum AllocReason {	AllocReasonReplace,	AllocReasonTransfer,	AllocReasonLogExtend,	AllocReasonDataExtend,} AllocReason; long logfsfindfreeblock(LogfsLowLevel *, AllocReason);char *logfsbootfettleblock(LogfsBoot *, long, uchar tag, long, int *);char *logfsserverreplacedatablock(LogfsServer *, long);char *logfsserverreplacelogblock(LogfsServer *, LogSegment *, long);char *logfsserverreplaceblock(LogfsServer *, LogSegment *, long);char *logfsservercopyactivedata(LogfsServer *, long, long, int,	LogfsLowLevelReadResult *, int *); char *logfsstrdup(char*); extern char Enomem[];extern char Eshortstat[];extern char Enonexist[];extern char Etoobig[];extern char Eexist[];extern char Eunknown[];extern char Enotdir[];extern char Eisdir[];extern char logfsebadfid[];extern char logfsefidopen[];extern char logfsefidnotopen[];extern char logfsefidinuse[];extern char logfseopen[];extern char logfseaccess[];extern char logfselogmsgtoobig[];extern char logfselogfull[];extern char logfseinternal[];extern char logfsenotempty[];extern char logfseexcl[];extern char logfsefullreplacing[];extern char logfseunknownpath[];