diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
| commit | 37da2899f40661e3e9631e497da8dc59b971cbd0 (patch) | |
| tree | cbc6d4680e347d906f5fa7fca73214418741df72 /liblogfs/local.h | |
| parent | 54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff) | |
20060303a
Diffstat (limited to 'liblogfs/local.h')
| -rw-r--r-- | liblogfs/local.h | 333 |
1 files changed, 333 insertions, 0 deletions
diff --git a/liblogfs/local.h b/liblogfs/local.h new file mode 100644 index 00000000..d614c062 --- /dev/null +++ b/liblogfs/local.h @@ -0,0 +1,333 @@ + +enum { + L2LogSweeps = 2, + L2BlockCopies = 2, + LogDataLimit = 128, + LogAddr = (1 << 31), + Replacements = 2, /* how much free space must be available for replacements */ + Transfers = 2, /* how much additional space must be available for transfers */ + LogSlack = 1, /* how much additional space must be available for data allocation */ +}; + +typedef struct Extent { + u32int min, max; + u32int flashaddr; /* encode block index, page number, and offset within page to min */ +} Extent; + +typedef struct ExtentList ExtentList; + +char *logfsextentlistnew(ExtentList **l); +void logfsextentlistfree(ExtentList **l); +char *logfsextentlistinsert(ExtentList *l, Extent *add, Extent **new); +int logfsextentlistwalk(ExtentList *l, int (*func)(void *magic, Extent *e, int hole),void *magic); +Extent *logfsextentlistmatch(ExtentList *l, Extent *e); +int logfsextentlistwalkrange(ExtentList *l, + int (*func)(void *magic, u32int baseoffset, u32int limitoffset, Extent *, u32int extentoffset), + void *magic, u32int base, u32int limit); +int logfsextentlistmatchall(ExtentList *l, int (*func)(void *magic, Extent *), void *magic, Extent *e); +void logfsextentlistreset(ExtentList *l); + +typedef 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; +} Entry; + +char *logfsentrynew(LogfsServer *server, int inuse, u32int path, Entry *parent, + char *name, char *uid, char *gid, + u32int mtime, char *muid, u32int perm, ulong cvers, ulong length, Entry **ep); +void logfsentryclunk(Entry *e); + +typedef struct DirReadState DirReadState; +void logfsdrsfree(DirReadState **drsp); + +typedef struct Fid { + ulong fid; + int openmode; + Entry *entry; + char *uname; + DirReadState *drs; +} Fid; + +typedef struct Map Map; +typedef int LOGFSMAPWALKFN(void *magic, void *entry); +char *logfsmapnew(int size, int (*hash)(void *key, int size), int (*compare)(void *entry, void *key), int (*allocsize)(void *key), void (*free)(void *), Map **mapp); +void logfsmapfree(Map **mp); +char *logfsmapnewentry(Map *m, void *key, void **entryp); +void *logfsmapfindentry(Map *m, void *key); +int logfsmapdeleteentry(Map *m, void *key); +int logfsmapwalk(Map *m, LOGFSMAPWALKFN *func, void *magic); + +typedef struct Map FidMap; + +char *logfsfidmapnew(FidMap **fidmapmapp); +#define logfsfidmapfree(mp) logfsmapfree(mp) +char *logfsfidmapnewentry(FidMap *m, ulong fid, Fid **fidmapp); +#define logfsfidmapfindentry(m, fid) logfsmapfindentry(m, (void *)fid) +int logfsfidmapclunk(FidMap *m, ulong fid); + +struct Logfs { + int trace; +}; + +typedef struct Map Ust; +char *logfsustnew(Ust **ustp); +#define logfsustfree(m) logfsmapfree(m) +char *logfsustadd(Ust *m, char *s); + +typedef struct GroupSet GroupSet; + +typedef struct Group Group; +typedef struct Map GroupMap; +typedef struct Uname Uname; +typedef struct Map UnameMap; + +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 **groupmapp, UnameMap **unamemapp); +#define logfsgroupmapfree(mp) logfsmapfree(mp) +#define logfsunamemapfree(mp) logfsmapfree(mp) +char *logfsgroupmapnewentry(GroupMap *gm, UnameMap *um, char *uid, char *uname, Group **groupp, Uname **unamep); +#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 *m, char *uid); +char *logfsunamemapfinduid(UnameMap *m, char *uid); +#define logfsunamemapdeleteentry(m, uname) logfsmapdeleteentry(m, (void *)uname) + +typedef int LOGFSGROUPSETWALKFN(void *magic, Group *g); +char *logfsgroupsetnew(GroupSet **sp); +void logfsgroupsetfree(GroupSet **sp); +int logfsgroupsetadd(GroupSet *s, Group *g); +int logfsgroupsetremove(GroupSet *s, Group *g); +int logfsgroupsetwalk(GroupSet *s, LOGFSGROUPSETWALKFN *func, void *magic); +int logfsgroupsetismember(GroupSet *gs, Group *g); +char *logfsisfindidfromname(LogfsIdentityStore *is, char *name); +char *logfsisfindnamefromid(LogfsIdentityStore *is, char *id); +#define logfsisfindgroupfromid(is, id) logfsgroupmapfindentry((is)->groupmap, id) +Group *logfsisfindgroupfromname(LogfsIdentityStore *is, char *uname); +#define logfsisustadd(is, s) logfsustadd((is)->ids, s) +int logfsisgroupunameismember(LogfsIdentityStore *is, Group *g, char *uname); +int logfsisgroupuidismember(LogfsIdentityStore *is, Group *g, char *uid); +int logfsisgroupuidisleader(LogfsIdentityStore *is, Group *g, char *uid); +extern char *logfsisgroupnonename; + +typedef 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; +} LogMessage; + +uint logfsconvM2S(uchar *ap, uint nap, LogMessage *f); +uint logfssizeS2M(LogMessage *f); +uint logfsconvS2M(LogMessage *f, uchar *ap, uint nap); +void logfsdumpS(LogMessage *s); + +typedef struct LogSegment LogSegment; + +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 *server, int gen, LogSegment **segp); +void logfslogsegmentfree(LogSegment **segp); +char *logfslogbytes(LogfsServer *server, int active, uchar *msg, uint size); +char *logfslog(LogfsServer *server, int active, LogMessage *s); +char *logfslogwrite(LogfsServer *server, int active, u32int path, u32int offset, int count, u32int mtime, + u32int cvers, char *muid, uchar *data, u32int *flashaddr); +char *logfslogsegmentflush(LogfsServer *server, int active); +int lognicesizeforwrite(LogfsServer *server, int active, u32int count, int muidlen); +char *logfsscan(LogfsServer *server); + +typedef struct DataBlock DataBlock; + +struct DataBlock { + u32int free; + u32int dirty; + long path; /* includes generation */ + long block; +}; + +u32int logfsdatapagemask(int pages, int base); + +typedef struct Path Path; + +struct Path { + ulong path; + Entry *entry; +}; + +typedef struct Map PathMap; + +char *logfspathmapnew(PathMap **pathmapmapp); +#define logfspathmapfree(mp) logfsmapfree(mp) +char *logfspathmapnewentry(PathMap *m, ulong path, Entry *e, Path **pathmapp); +#define logfspathmapfindentry(m, path) (Path *)logfsmapfindentry(m, (void *)path) +#define logfspathmapdeleteentry(m, path) logfsmapdeleteentry(m, (void *)path) +Entry *logfspathmapfinde(PathMap *m, ulong path); + +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 *v, int size); + +int logfsuserpermcheck(LogfsServer *s, Entry *e, Fid *f, ulong modemask); +u32int logfsflattenentry(LogfsIdentityStore *is, uchar *buf, u32int buflen, Entry *e); +char *logfsreplay(LogfsServer *server, LogSegment *seg, int disableerrorsforfirstblock); +void logfsreplayfinddata(LogfsServer *server); + +#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 *magic, Extent *e, int hole); +void logfsflashaddr2spo(LogfsServer *server, u32int flashaddr, long *seq, int *page, int *offset); +int logfsgn(uchar **pp, uchar *mep, char **v); +u32int logfsspo2flashaddr(LogfsServer *server, long seq, int page, int offset); +int logfsgn(uchar **pp, uchar *mep, char **v); +void logfsflashaddr2o(LogfsServer *server, u32int flashaddr, int *offset); +void logfsfreedatapages(LogfsServer *server, long seq, u32int mask); +void logfsfreeanddirtydatablockcheck(LogfsServer *server, long seq); + +typedef enum AllocReason { + AllocReasonReplace, + AllocReasonTransfer, + AllocReasonLogExtend, + AllocReasonDataExtend, +} AllocReason; + +long logfsfindfreeblock(LogfsLowLevel *ll, AllocReason reason); +char *logfsbootfettleblock(LogfsBoot *lb, long block, uchar tag, long path, int *markedbad); +char *logfsserverreplacedatablock(LogfsServer *server, long index); +char *logfsserverreplacelogblock(LogfsServer *server, LogSegment *seg, long index); +char *logfsserverreplaceblock(LogfsServer *server, LogSegment *seg, long seq); +char *logfsservercopyactivedata(LogfsServer *server, long newb, long oldblockindex, int forcepage0, + LogfsLowLevelReadResult *llrrp, int *markedbadp); + +char *logfsstrdup(char *); + +extern char Enomem[]; +extern char Emsgsize[]; +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[]; |
