1*28942eadSforsyth typedef struct DataBlock DataBlock; 2*28942eadSforsyth typedef struct Extent Extent; 3*28942eadSforsyth typedef struct Entry Entry; 4*28942eadSforsyth typedef struct ExtentList ExtentList; 5*28942eadSforsyth typedef struct Fid Fid; 6*28942eadSforsyth typedef struct Map Map; 7*28942eadSforsyth typedef struct GroupSet GroupSet; 8*28942eadSforsyth typedef struct Group Group; 9*28942eadSforsyth typedef struct Uname Uname; 10*28942eadSforsyth typedef struct LogMessage LogMessage; 11*28942eadSforsyth typedef struct LogSegment LogSegment; 12*28942eadSforsyth typedef struct Path Path; 13*28942eadSforsyth typedef struct DirReadState DirReadState; 14*28942eadSforsyth 15*28942eadSforsyth typedef struct Map PathMap; 16*28942eadSforsyth typedef struct Map FidMap; 17*28942eadSforsyth typedef struct Map GroupMap; 18*28942eadSforsyth typedef struct Map UnameMap; 19*28942eadSforsyth typedef struct Map Ust; 20*28942eadSforsyth 21*28942eadSforsyth #pragma incomplete Extent 22*28942eadSforsyth #pragma incomplete ExtentList 23*28942eadSforsyth #pragma incomplete Map 24*28942eadSforsyth #pragma incomplete DirReadState 2537da2899SCharles.Forsyth 2637da2899SCharles.Forsyth enum { 2737da2899SCharles.Forsyth L2LogSweeps = 2, 2837da2899SCharles.Forsyth L2BlockCopies = 2, 2937da2899SCharles.Forsyth LogDataLimit = 128, 3037da2899SCharles.Forsyth LogAddr = (1 << 31), 31*28942eadSforsyth Replacements = 2, /* extra space for replacements */ 32*28942eadSforsyth Transfers = 2, /* extra space available for transfers */ 33*28942eadSforsyth LogSlack = 1, /* extra space for data allocation */ 3437da2899SCharles.Forsyth }; 3537da2899SCharles.Forsyth 36*28942eadSforsyth struct Extent { 3737da2899SCharles.Forsyth u32int min, max; 3837da2899SCharles.Forsyth u32int flashaddr; /* encode block index, page number, and offset within page to min */ 39*28942eadSforsyth }; 4037da2899SCharles.Forsyth 41*28942eadSforsyth char *logfsextentlistnew(ExtentList **); 42*28942eadSforsyth void logfsextentlistfree(ExtentList **); 43*28942eadSforsyth char *logfsextentlistinsert(ExtentList *, Extent *, Extent **); 44*28942eadSforsyth int logfsextentlistwalk(ExtentList *, int (*)(void *, Extent *, int),void *); 45*28942eadSforsyth Extent *logfsextentlistmatch(ExtentList *, Extent *); 46*28942eadSforsyth int logfsextentlistwalkrange(ExtentList *, 47*28942eadSforsyth int (*)(void *, u32int, u32int, Extent *, u32int), 48*28942eadSforsyth void *, u32int, u32int); 49*28942eadSforsyth int logfsextentlistmatchall(ExtentList *, int (*)(void *, Extent *), void *, Extent *); 50*28942eadSforsyth void logfsextentlistreset(ExtentList *); 5137da2899SCharles.Forsyth 52*28942eadSforsyth struct Entry { 5337da2899SCharles.Forsyth int inuse; 5437da2899SCharles.Forsyth int deadandgone; /* removed */ 5537da2899SCharles.Forsyth Qid qid; 5637da2899SCharles.Forsyth struct Entry *parent; 5737da2899SCharles.Forsyth char *name; 5837da2899SCharles.Forsyth char *uid; 5937da2899SCharles.Forsyth char *gid; 6037da2899SCharles.Forsyth ulong mtime; 6137da2899SCharles.Forsyth char *muid; 6237da2899SCharles.Forsyth u32int perm; 6337da2899SCharles.Forsyth struct Entry *next; 6437da2899SCharles.Forsyth struct { 6537da2899SCharles.Forsyth struct { 6637da2899SCharles.Forsyth ulong cvers; 6737da2899SCharles.Forsyth ulong length; 6837da2899SCharles.Forsyth ExtentList *extent; 6937da2899SCharles.Forsyth } file; 7037da2899SCharles.Forsyth struct { 7137da2899SCharles.Forsyth struct Entry *list; 7237da2899SCharles.Forsyth } dir; 7337da2899SCharles.Forsyth } u; 74*28942eadSforsyth }; 7537da2899SCharles.Forsyth 76*28942eadSforsyth char *logfsentrynew(LogfsServer *, int, u32int, Entry *, 77*28942eadSforsyth char *, char *, char *, 78*28942eadSforsyth u32int, char *, u32int, ulong, ulong, Entry **); 79*28942eadSforsyth void logfsentryclunk(Entry *); 8037da2899SCharles.Forsyth 81*28942eadSforsyth void logfsdrsfree(DirReadState **); 8237da2899SCharles.Forsyth 83*28942eadSforsyth struct Fid { 8437da2899SCharles.Forsyth ulong fid; 8537da2899SCharles.Forsyth int openmode; 8637da2899SCharles.Forsyth Entry *entry; 8737da2899SCharles.Forsyth char *uname; 8837da2899SCharles.Forsyth DirReadState *drs; 89*28942eadSforsyth }; 9037da2899SCharles.Forsyth 91*28942eadSforsyth typedef int LOGFSMAPWALKFN(void*, void*); 92*28942eadSforsyth char *logfsmapnew(int, int (*)(void*, int), int (*)(void*, void*), int (*)(void*), void (*)(void*), Map **); 93*28942eadSforsyth void logfsmapfree(Map **); 94*28942eadSforsyth char *logfsmapnewentry(Map*, void*, void **); 95*28942eadSforsyth void *logfsmapfindentry(Map*, void*); 96*28942eadSforsyth int logfsmapdeleteentry(Map*, void*); 97*28942eadSforsyth int logfsmapwalk(Map*, LOGFSMAPWALKFN*, void*); 9837da2899SCharles.Forsyth 99*28942eadSforsyth char *logfsfidmapnew(FidMap **); 10037da2899SCharles.Forsyth #define logfsfidmapfree(mp) logfsmapfree(mp) 101*28942eadSforsyth char *logfsfidmapnewentry(FidMap *, ulong, Fid **); 10237da2899SCharles.Forsyth #define logfsfidmapfindentry(m, fid) logfsmapfindentry(m, (void *)fid) 103*28942eadSforsyth int logfsfidmapclunk(FidMap *, ulong); 10437da2899SCharles.Forsyth 10537da2899SCharles.Forsyth struct Logfs { 10637da2899SCharles.Forsyth int trace; 10737da2899SCharles.Forsyth }; 10837da2899SCharles.Forsyth 109*28942eadSforsyth char *logfsustnew(Ust**); 110*28942eadSforsyth #define logfsustfree(m) logfsmapfree((m)) 111*28942eadSforsyth char *logfsustadd(Ust*, char*); 11237da2899SCharles.Forsyth 11337da2899SCharles.Forsyth struct Group { 11437da2899SCharles.Forsyth char *uid; 11537da2899SCharles.Forsyth char *uname; 11637da2899SCharles.Forsyth Group *leader; 11737da2899SCharles.Forsyth GroupSet *members; 11837da2899SCharles.Forsyth }; 11937da2899SCharles.Forsyth 12037da2899SCharles.Forsyth struct Uname { 12137da2899SCharles.Forsyth char *uname; 12237da2899SCharles.Forsyth Group *g; 12337da2899SCharles.Forsyth }; 12437da2899SCharles.Forsyth 12537da2899SCharles.Forsyth struct LogfsIdentityStore { 12637da2899SCharles.Forsyth Ust *ids; 12737da2899SCharles.Forsyth GroupMap *groupmap; 12837da2899SCharles.Forsyth UnameMap *unamemap; 12937da2899SCharles.Forsyth }; 13037da2899SCharles.Forsyth 131*28942eadSforsyth char *logfsgroupmapnew(GroupMap **, UnameMap **); 13237da2899SCharles.Forsyth #define logfsgroupmapfree(mp) logfsmapfree(mp) 13337da2899SCharles.Forsyth #define logfsunamemapfree(mp) logfsmapfree(mp) 134*28942eadSforsyth char *logfsgroupmapnewentry(GroupMap *, UnameMap *, char *, char *, Group **, Uname **); 13537da2899SCharles.Forsyth #define logfsgroupmapdeleteentry(m, uid) logfsmapdeleteentry(m, (void *)uid) 13637da2899SCharles.Forsyth #define logfsgroupmapfindentry(m, uid) logfsmapfindentry(m, uid) 13737da2899SCharles.Forsyth #define logfsunamemapfindentry(m, uname) logfsmapfindentry(m, uname) 138*28942eadSforsyth char *logfsgroupmapfinduname(GroupMap *, char *); 139*28942eadSforsyth char *logfsunamemapfinduid(UnameMap *, char *); 14037da2899SCharles.Forsyth #define logfsunamemapdeleteentry(m, uname) logfsmapdeleteentry(m, (void *)uname) 14137da2899SCharles.Forsyth 142*28942eadSforsyth typedef int LOGFSGROUPSETWALKFN(void *, Group *); 143*28942eadSforsyth char *logfsgroupsetnew(GroupSet **); 144*28942eadSforsyth void logfsgroupsetfree(GroupSet **); 145*28942eadSforsyth int logfsgroupsetadd(GroupSet *, Group *); 146*28942eadSforsyth int logfsgroupsetremove(GroupSet *, Group *); 147*28942eadSforsyth int logfsgroupsetwalk(GroupSet *, LOGFSGROUPSETWALKFN *, void *); 148*28942eadSforsyth int logfsgroupsetismember(GroupSet *, Group *); 149*28942eadSforsyth char *logfsisfindidfromname(LogfsIdentityStore *, char *); 150*28942eadSforsyth char *logfsisfindnamefromid(LogfsIdentityStore *, char *); 15137da2899SCharles.Forsyth #define logfsisfindgroupfromid(is, id) logfsgroupmapfindentry((is)->groupmap, id) 152*28942eadSforsyth Group *logfsisfindgroupfromname(LogfsIdentityStore *, char *); 15337da2899SCharles.Forsyth #define logfsisustadd(is, s) logfsustadd((is)->ids, s) 154*28942eadSforsyth int logfsisgroupunameismember(LogfsIdentityStore *, Group *, char *); 155*28942eadSforsyth int logfsisgroupuidismember(LogfsIdentityStore *, Group *, char *); 156*28942eadSforsyth int logfsisgroupuidisleader(LogfsIdentityStore *, Group *, char *); 15737da2899SCharles.Forsyth extern char *logfsisgroupnonename; 15837da2899SCharles.Forsyth 159*28942eadSforsyth struct LogMessage { 16037da2899SCharles.Forsyth uchar type; 16137da2899SCharles.Forsyth u32int path; 16237da2899SCharles.Forsyth union { 16337da2899SCharles.Forsyth struct { 16437da2899SCharles.Forsyth u32int nerase; 16537da2899SCharles.Forsyth } start; 16637da2899SCharles.Forsyth struct { 16737da2899SCharles.Forsyth u32int perm; 16837da2899SCharles.Forsyth u32int newpath; 16937da2899SCharles.Forsyth u32int mtime; 17037da2899SCharles.Forsyth u32int cvers; 17137da2899SCharles.Forsyth char *name; 17237da2899SCharles.Forsyth char *uid; 17337da2899SCharles.Forsyth char *gid; 17437da2899SCharles.Forsyth } create; 17537da2899SCharles.Forsyth struct { 17637da2899SCharles.Forsyth u32int mtime; 17737da2899SCharles.Forsyth char *muid; 17837da2899SCharles.Forsyth } remove; 17937da2899SCharles.Forsyth struct { 18037da2899SCharles.Forsyth u32int mtime; 18137da2899SCharles.Forsyth u32int cvers; 18237da2899SCharles.Forsyth char *muid; 18337da2899SCharles.Forsyth } trunc; 18437da2899SCharles.Forsyth struct { 18537da2899SCharles.Forsyth u32int offset; 18637da2899SCharles.Forsyth u32int count; 18737da2899SCharles.Forsyth u32int mtime; 18837da2899SCharles.Forsyth u32int cvers; 18937da2899SCharles.Forsyth char *muid; 19037da2899SCharles.Forsyth u32int flashaddr; 19137da2899SCharles.Forsyth uchar *data; 19237da2899SCharles.Forsyth } write; 19337da2899SCharles.Forsyth struct { 19437da2899SCharles.Forsyth char *name; 19537da2899SCharles.Forsyth u32int perm; 19637da2899SCharles.Forsyth char *uid; 19737da2899SCharles.Forsyth char *gid; 19837da2899SCharles.Forsyth u32int mtime; 19937da2899SCharles.Forsyth char *muid; 20037da2899SCharles.Forsyth } wstat; 20137da2899SCharles.Forsyth } u; 202*28942eadSforsyth }; 20337da2899SCharles.Forsyth 204*28942eadSforsyth uint logfsconvM2S(uchar *, uint, LogMessage *); 205*28942eadSforsyth uint logfssizeS2M(LogMessage *); 206*28942eadSforsyth uint logfsconvS2M(LogMessage *, uchar *, uint); 207*28942eadSforsyth void logfsdumpS(LogMessage *); 20837da2899SCharles.Forsyth 20937da2899SCharles.Forsyth struct LogSegment { 21037da2899SCharles.Forsyth int gen; /* generation number of this log */ 21137da2899SCharles.Forsyth int dirty; /* written to since last sweep */ 21237da2899SCharles.Forsyth long curblockindex; /* index of block being filled, or -1 */ 21337da2899SCharles.Forsyth long unsweptblockindex; /* next block to sweep */ 21437da2899SCharles.Forsyth int curpage; /* page within block */ 21537da2899SCharles.Forsyth uchar *pagebuf; /* page buffer */ 21637da2899SCharles.Forsyth int nbytes; /* bytes used in page buffer */ 21737da2899SCharles.Forsyth long blockmap[1]; /* there are ll->blocks of these */ 21837da2899SCharles.Forsyth }; 21937da2899SCharles.Forsyth 220*28942eadSforsyth char *logfslogsegmentnew(LogfsServer *, int, LogSegment **); 221*28942eadSforsyth void logfslogsegmentfree(LogSegment **); 222*28942eadSforsyth char *logfslogbytes(LogfsServer *, int, uchar *, uint); 223*28942eadSforsyth char *logfslog(LogfsServer *, int, LogMessage *); 224*28942eadSforsyth char *logfslogwrite(LogfsServer *, int, u32int, u32int, int, u32int, 225*28942eadSforsyth u32int, char *, uchar *, u32int *); 226*28942eadSforsyth char *logfslogsegmentflush(LogfsServer *, int); 227*28942eadSforsyth int lognicesizeforwrite(LogfsServer *, int, u32int, int); 228*28942eadSforsyth char *logfsscan(LogfsServer *); 22937da2899SCharles.Forsyth 23037da2899SCharles.Forsyth struct DataBlock { 231*28942eadSforsyth Pageset free; 232*28942eadSforsyth Pageset dirty; 23337da2899SCharles.Forsyth long path; /* includes generation */ 23437da2899SCharles.Forsyth long block; 23537da2899SCharles.Forsyth }; 23637da2899SCharles.Forsyth 237*28942eadSforsyth Pageset logfsdatapagemask(int, int); 23837da2899SCharles.Forsyth 23937da2899SCharles.Forsyth struct Path { 24037da2899SCharles.Forsyth ulong path; 24137da2899SCharles.Forsyth Entry *entry; 24237da2899SCharles.Forsyth }; 24337da2899SCharles.Forsyth 244*28942eadSforsyth char *logfspathmapnew(PathMap **); 24537da2899SCharles.Forsyth #define logfspathmapfree(mp) logfsmapfree(mp) 246*28942eadSforsyth char *logfspathmapnewentry(PathMap *, ulong, Entry *, Path **); 24737da2899SCharles.Forsyth #define logfspathmapfindentry(m, path) (Path *)logfsmapfindentry(m, (void *)path) 24837da2899SCharles.Forsyth #define logfspathmapdeleteentry(m, path) logfsmapdeleteentry(m, (void *)path) 249*28942eadSforsyth Entry *logfspathmapfinde(PathMap *, ulong); 25037da2899SCharles.Forsyth 25137da2899SCharles.Forsyth enum { 25237da2899SCharles.Forsyth LogfsTestDontFettleDataBlock = 1, 25337da2899SCharles.Forsyth }; 25437da2899SCharles.Forsyth 25537da2899SCharles.Forsyth struct LogfsServer { 25637da2899SCharles.Forsyth LogfsLowLevel *ll; 25737da2899SCharles.Forsyth LogfsBoot *lb; 25837da2899SCharles.Forsyth FidMap *fidmap; 25937da2899SCharles.Forsyth LogfsIdentityStore *is; 26037da2899SCharles.Forsyth PathMap *pathmap; 26137da2899SCharles.Forsyth LogSegment *activelog; 26237da2899SCharles.Forsyth LogSegment *sweptlog; 26337da2899SCharles.Forsyth long ndatablocks; 26437da2899SCharles.Forsyth DataBlock *datablock; 26537da2899SCharles.Forsyth ulong path; 26637da2899SCharles.Forsyth Entry root; 26737da2899SCharles.Forsyth int trace; 26837da2899SCharles.Forsyth ulong openflags; 26937da2899SCharles.Forsyth ulong testflags; 27037da2899SCharles.Forsyth }; 27137da2899SCharles.Forsyth 272*28942eadSforsyth int logfshashulong(void *, int); 27337da2899SCharles.Forsyth 274*28942eadSforsyth int logfsuserpermcheck(LogfsServer *, Entry *, Fid *, ulong); 275*28942eadSforsyth u32int logfsflattenentry(LogfsIdentityStore *, uchar *, u32int, Entry *); 276*28942eadSforsyth char *logfsreplay(LogfsServer *, LogSegment *, int); 277*28942eadSforsyth void logfsreplayfinddata(LogfsServer *); 27837da2899SCharles.Forsyth 27937da2899SCharles.Forsyth #define dataseqof(path) ((path) >> L2BlockCopies) 28037da2899SCharles.Forsyth #define copygenof(path) ((path) & ((1 << L2BlockCopies) -1)) 28137da2899SCharles.Forsyth #define mkdatapath(seq, gen) (((seq) << L2BlockCopies) | (gen)) 28237da2899SCharles.Forsyth #define gensucc(g, l2) (((g) + 1) & ((1 << (l2)) - 1)) 283*28942eadSforsyth #define copygensucc(g) gensucc((g), L2BlockCopies) 28437da2899SCharles.Forsyth #define loggenof(path) ((path >> L2BlockCopies) & ((1 << L2LogSweeps) - 1)) 28537da2899SCharles.Forsyth #define logseqof(path) ((path) >> (L2BlockCopies + L2LogSweeps)) 28637da2899SCharles.Forsyth #define mklogpath(seq, gen, copygen) (((((seq) << L2LogSweeps) | (gen)) << L2BlockCopies) | (copygen)) 287*28942eadSforsyth #define loggensucc(g) gensucc((g), L2LogSweeps) 28837da2899SCharles.Forsyth 289*28942eadSforsyth int logfsunconditionallymarkfreeanddirty(void *, Extent *, int); 290*28942eadSforsyth void logfsflashaddr2spo(LogfsServer *, u32int, long *, int *, int *); 291*28942eadSforsyth int logfsgn(uchar **, uchar *, char **); 292*28942eadSforsyth u32int logfsspo2flashaddr(LogfsServer *, long, int, int); 293*28942eadSforsyth int logfsgn(uchar **, uchar *, char **); 294*28942eadSforsyth void logfsflashaddr2o(LogfsServer *, u32int, int *); 295*28942eadSforsyth void logfsfreedatapages(LogfsServer *, long, Pageset); 296*28942eadSforsyth void logfsfreeanddirtydatablockcheck(LogfsServer *, long); 29737da2899SCharles.Forsyth 29837da2899SCharles.Forsyth typedef enum AllocReason { 29937da2899SCharles.Forsyth AllocReasonReplace, 30037da2899SCharles.Forsyth AllocReasonTransfer, 30137da2899SCharles.Forsyth AllocReasonLogExtend, 30237da2899SCharles.Forsyth AllocReasonDataExtend, 30337da2899SCharles.Forsyth } AllocReason; 30437da2899SCharles.Forsyth 305*28942eadSforsyth long logfsfindfreeblock(LogfsLowLevel *, AllocReason); 306*28942eadSforsyth char *logfsbootfettleblock(LogfsBoot *, long, uchar tag, long, int *); 307*28942eadSforsyth char *logfsserverreplacedatablock(LogfsServer *, long); 308*28942eadSforsyth char *logfsserverreplacelogblock(LogfsServer *, LogSegment *, long); 309*28942eadSforsyth char *logfsserverreplaceblock(LogfsServer *, LogSegment *, long); 310*28942eadSforsyth char *logfsservercopyactivedata(LogfsServer *, long, long, int, 311*28942eadSforsyth LogfsLowLevelReadResult *, int *); 31237da2899SCharles.Forsyth 31337da2899SCharles.Forsyth char *logfsstrdup(char*); 31437da2899SCharles.Forsyth 31537da2899SCharles.Forsyth extern char Enomem[]; 316*28942eadSforsyth extern char Eshortstat[]; 31737da2899SCharles.Forsyth extern char Enonexist[]; 31837da2899SCharles.Forsyth extern char Etoobig[]; 31937da2899SCharles.Forsyth extern char Eexist[]; 32037da2899SCharles.Forsyth extern char Eunknown[]; 32137da2899SCharles.Forsyth extern char Enotdir[]; 32237da2899SCharles.Forsyth extern char Eisdir[]; 32337da2899SCharles.Forsyth extern char logfsebadfid[]; 32437da2899SCharles.Forsyth extern char logfsefidopen[]; 32537da2899SCharles.Forsyth extern char logfsefidnotopen[]; 32637da2899SCharles.Forsyth extern char logfsefidinuse[]; 32737da2899SCharles.Forsyth extern char logfseopen[]; 32837da2899SCharles.Forsyth extern char logfseaccess[]; 32937da2899SCharles.Forsyth extern char logfselogmsgtoobig[]; 33037da2899SCharles.Forsyth extern char logfselogfull[]; 33137da2899SCharles.Forsyth extern char logfseinternal[]; 33237da2899SCharles.Forsyth extern char logfsenotempty[]; 33337da2899SCharles.Forsyth extern char logfseexcl[]; 33437da2899SCharles.Forsyth extern char logfsefullreplacing[]; 33537da2899SCharles.Forsyth extern char logfseunknownpath[]; 336