#pragma lib "libventi.a"#pragma src "/sys/src/libventi" /* XXX should be own library? *//* * Packets */enum{ MaxFragSize = 9*1024}; typedef struct Packet Packet;#pragma incomplete Packet Packet* packetalloc(void);void packetappend(Packet*, uchar *buf, int n);uint packetasize(Packet*);int packetcmp(Packet*, Packet*);int packetcompact(Packet*);void packetconcat(Packet*, Packet*);int packetconsume(Packet*, uchar *buf, int n);int packetcopy(Packet*, uchar *buf, int offset, int n);Packet* packetdup(Packet*, int offset, int n);Packet* packetforeign(uchar *buf, int n, void (*free)(void *a), void *a);int packetfragments(Packet*, IOchunk*, int nio, int offset);void packetfree(Packet*);uchar* packetheader(Packet*, int n);uchar* packetpeek(Packet*, uchar *buf, int offset, int n);void packetprefix(Packet*, uchar *buf, int n);void packetsha1(Packet*, uchar sha1[20]);uint packetsize(Packet*);Packet* packetsplit(Packet*, int n);void packetstats(void);uchar* packettrailer(Packet*, int n);int packettrim(Packet*, int offset, int n); /* XXX should be own library? *//* * Logging */typedef struct VtLog VtLog;typedef struct VtLogChunk VtLogChunk; struct VtLog{ VtLog *next; /* in hash table */ char *name; VtLogChunk *chunk; uint nchunk; VtLogChunk *w; QLock lk; int ref;}; struct VtLogChunk{ char *p; char *ep; char *wp;}; VtLog* vtlogopen(char *name, uint size);void vtlogprint(VtLog *log, char *fmt, ...);void vtlog(char *name, char *fmt, ...);void vtlogclose(VtLog*);void vtlogremove(char *name);char** vtlognames(int*);void vtlogdump(int fd, VtLog*); /* XXX begin actual venti.h */ typedef struct VtFcall VtFcall;typedef struct VtConn VtConn;typedef struct VtEntry VtEntry;typedef struct VtRoot VtRoot; /* * Fundamental constants. */enum{ VtScoreSize = 20, VtMaxStringSize = 1024, VtMaxLumpSize = 56*1024, VtPointerDepth = 7};#define VtMaxFileSize ((1ULL<<48)-1) /* * Strings in packets. */int vtputstring(Packet*, char*);int vtgetstring(Packet*, char**); /* * Block types. * * The initial Venti protocol had a much * less regular list of block types. * VtToDiskType converts from new to old. */enum{ VtDataType = 0<<3, /* VtDataType+1, ... */ VtDirType = 1<<3, /* VtDirType+1, ... */ VtRootType = 2<<3, VtMaxType, VtCorruptType = 0xFF, VtTypeDepthMask = 7, VtTypeBaseMask = ~VtTypeDepthMask}; /* convert to/from on-disk type numbers */uint vttodisktype(uint);uint vtfromdisktype(uint); /* * VtEntry describes a Venti stream * * The _ enums are only used on the wire. * They are not present in the VtEntry structure * and should not be used by client programs. * (The info is in the type field.) */enum{ VtEntryActive = 1<<0, /* entry is in use */ _VtEntryDir = 1<<1, /* a directory */ _VtEntryDepthShift = 2, /* shift for pointer depth */ _VtEntryDepthMask = 7<<2, /* mask for pointer depth */ VtEntryLocal = 1<<5 /* for local storage only */};enum{ VtEntrySize = 40};struct VtEntry{ ulong gen; /* generation number */ ushort psize; /* pointer block size */ ushort dsize; /* data block size */ uchar type; uchar flags; uvlong size; uchar score[VtScoreSize];}; void vtentrypack(VtEntry*, uchar*, int index);int vtentryunpack(VtEntry*, uchar*, int index); struct VtRoot{ char name[128]; char type[128]; uchar score[VtScoreSize]; /* to a Dir block */ ushort blocksize; /* maximum block size */ uchar prev[VtScoreSize]; /* last root block */}; enum{ VtRootSize = 300, VtRootVersion = 2}; void vtrootpack(VtRoot*, uchar*);int vtrootunpack(VtRoot*, uchar*); /* * score of zero length block */extern uchar vtzeroscore[VtScoreSize]; /* * zero extend and truncate blocks */void vtzeroextend(int type, uchar *buf, uint n, uint nn);uint vtzerotruncate(int type, uchar *buf, uint n); /* * parse score: mungs s */int vtparsescore(char *s, char **prefix, uchar[VtScoreSize]); /* * formatting * other than noted, these formats all ignore * the width and precision arguments, and all flags * * V a venti score */#pragma varargck type "V" uchar*#pragma varargck type "F" VtFcall*#pragma varargck type "T" void#pragma varargck type "lT" void int vtscorefmt(Fmt*); /* * error-checking malloc et al. */void vtfree(void *);void* vtmalloc(int);void* vtmallocz(int);void* vtrealloc(void *p, int);void* vtbrk(int n);char* vtstrdup(char *); /* * Venti protocol */ /* * Crypto strengths */enum{ VtCryptoStrengthNone, VtCryptoStrengthAuth, VtCryptoStrengthWeak, VtCryptoStrengthStrong}; /* * Crypto suites */enum{ VtCryptoNone, VtCryptoSSL3, VtCryptoTLS1, VtCryptoMax}; /* * Codecs */enum{ VtCodecNone, VtCodecDeflate, VtCodecThwack, VtCodecMax}; enum{ VtRerror = 1, VtTping = 2, VtRping, VtThello = 4, VtRhello, VtTgoodbye = 6, VtRgoodbye, /* not used */ VtTauth0 = 8, VtRauth0, VtTauth1 = 10, VtRauth1, VtTread = 12, VtRread, VtTwrite = 14, VtRwrite, VtTsync = 16, VtRsync, VtTmax}; struct VtFcall{ uchar msgtype; uchar tag; char *error; /* Rerror */ char *version; /* Thello */ char *uid; /* Thello */ uchar strength; /* Thello */ uchar *crypto; /* Thello */ uint ncrypto; /* Thello */ uchar *codec; /* Thello */ uint ncodec; /* Thello */ char *sid; /* Rhello */ uchar rcrypto; /* Rhello */ uchar rcodec; /* Rhello */ uchar *auth; /* TauthX, RauthX */ uint nauth; /* TauthX, RauthX */ uchar score[VtScoreSize]; /* Tread, Rwrite */ uchar blocktype; /* Tread, Twrite */ ushort count; /* Tread */ Packet *data; /* Rread, Twrite */}; Packet* vtfcallpack(VtFcall*);int vtfcallunpack(VtFcall*, Packet*);void vtfcallclear(VtFcall*);int vtfcallfmt(Fmt*); enum{ VtStateAlloc, VtStateConnected, VtStateClosed}; struct VtConn{ QLock lk; QLock inlk; QLock outlk; int debug; int infd; int outfd; int muxer; void *writeq; void *readq; int state; void *wait[256]; uint ntag; uint nsleep; Packet *part; Rendez tagrend; Rendez rpcfork; char *version; char *uid; char *sid; char addr[256]; /* address of other side */}; VtConn* vtconn(int infd, int outfd);VtConn* vtdial(char*);void vtfreeconn(VtConn*);int vtsend(VtConn*, Packet*);Packet* vtrecv(VtConn*);int vtversion(VtConn* z);void vtdebug(VtConn* z, char*, ...);void vthangup(VtConn* z);int vtgoodbye(VtConn* z); /* #pragma varargck argpos vtdebug 2 */ /* server */typedef struct VtSrv VtSrv;#pragma incomplete VtSrvtypedef struct VtReq VtReq;struct VtReq{ VtFcall tx; VtFcall rx;/* private */ VtSrv *srv; void *sc;}; int vtsrvhello(VtConn*);VtSrv* vtlisten(char *addr);VtReq* vtgetreq(VtSrv*);void vtrespond(VtReq*); /* client */Packet* vtrpc(VtConn*, Packet*);Packet* _vtrpc(VtConn*, Packet*, VtFcall*);void vtrecvproc(void*); /* VtConn */void vtsendproc(void*); /* VtConn */ int vtconnect(VtConn*);int vthello(VtConn*);int vtread(VtConn*, uchar score[VtScoreSize], uint type, uchar *buf, int n);int vtwrite(VtConn*, uchar score[VtScoreSize], uint type, uchar *buf, int n);Packet* vtreadpacket(VtConn*, uchar score[VtScoreSize], uint type, int n);int vtwritepacket(VtConn*, uchar score[VtScoreSize], uint type, Packet *p);int vtsync(VtConn*);int vtping(VtConn*); /* * Data blocks and block cache. */enum{ NilBlock = ~0}; typedef struct VtBlock VtBlock;typedef struct VtCache VtCache;#pragma incomplete VtCache struct VtBlock{ VtCache *c; QLock lk; uchar *data; uchar score[VtScoreSize]; uchar type; /* BtXXX */ /* internal to cache */ int nlock; int iostate; int ref; u32int heap; VtBlock *next; VtBlock **prev; u32int used; u32int used2; u32int addr; uintptr pc;}; u32int vtglobaltolocal(uchar[VtScoreSize]);void vtlocaltoglobal(u32int, uchar[VtScoreSize]); VtCache*vtcachealloc(VtConn*, int blocksize, ulong nblocks);void vtcachefree(VtCache*);VtBlock*vtcachelocal(VtCache*, u32int addr, int type);VtBlock*vtcacheglobal(VtCache*, uchar[VtScoreSize], int type);VtBlock*vtcacheallocblock(VtCache*, int type);void vtcachesetwrite(VtCache*, int(*)(VtConn*, uchar[VtScoreSize], uint, uchar*, int));void vtblockput(VtBlock*);u32int vtcacheblocksize(VtCache*);int vtblockwrite(VtBlock*);VtBlock*vtblockcopy(VtBlock*);void vtblockduplock(VtBlock*); extern int vtcachencopy, vtcachenread, vtcachenwrite;extern int vttracelevel; /* * Hash tree file tree. */typedef struct VtFile VtFile;struct VtFile{ QLock lk; int ref; int local; VtBlock *b; /* block containing this file */ uchar score[VtScoreSize]; /* score of block containing this file */ /* immutable */ VtCache *c; int mode; u32int gen; int dsize; int psize; int dir; VtFile *parent; int epb; /* entries per block in parent */ u32int offset; /* entry offset in parent */}; enum{ VtOREAD, VtOWRITE, VtORDWR}; VtBlock*vtfileblock(VtFile*, u32int, int mode);int vtfileblockscore(VtFile*, u32int, uchar[VtScoreSize]);void vtfileclose(VtFile*);VtFile* _vtfilecreate(VtFile*, int offset, int psize, int dsize, int dir);VtFile* vtfilecreate(VtFile*, int psize, int dsize, int dir);VtFile* vtfilecreateroot(VtCache*, int psize, int dsize, int type);int vtfileflush(VtFile*);int vtfileflushbefore(VtFile*, u64int);u32int vtfilegetdirsize(VtFile*);int vtfilegetentry(VtFile*, VtEntry*);uvlong vtfilegetsize(VtFile*);void vtfileincref(VtFile*);int vtfilelock2(VtFile*, VtFile*, int);int vtfilelock(VtFile*, int);VtFile* vtfileopen(VtFile*, u32int, int);VtFile* vtfileopenroot(VtCache*, VtEntry*);long vtfileread(VtFile*, void*, long, vlong);int vtfileremove(VtFile*);int vtfilesetdirsize(VtFile*, u32int);int vtfilesetentry(VtFile*, VtEntry*);int vtfilesetsize(VtFile*, u64int);int vtfiletruncate(VtFile*);void vtfileunlock(VtFile*);long vtfilewrite(VtFile*, void*, long, vlong); int vttimefmt(Fmt*); extern int chattyventi;extern int ventidoublechecksha1;extern int ventilogging; extern char *VtServerLog;
#pragma lib "libventi.a"
#pragma src "/sys/src/libventi"
/* XXX should be own library? */
/*
* Packets
*/
enum
{
MaxFragSize = 9*1024
};
typedef struct Packet Packet;
#pragma incomplete Packet
Packet* packetalloc(void);
void packetappend(Packet*, uchar *buf, int n);
uint packetasize(Packet*);
int packetcmp(Packet*, Packet*);
int packetcompact(Packet*);
void packetconcat(Packet*, Packet*);
int packetconsume(Packet*, uchar *buf, int n);
int packetcopy(Packet*, uchar *buf, int offset, int n);
Packet* packetdup(Packet*, int offset, int n);
Packet* packetforeign(uchar *buf, int n, void (*free)(void *a), void *a);
int packetfragments(Packet*, IOchunk*, int nio, int offset);
void packetfree(Packet*);
uchar* packetheader(Packet*, int n);
uchar* packetpeek(Packet*, uchar *buf, int offset, int n);
void packetprefix(Packet*, uchar *buf, int n);
void packetsha1(Packet*, uchar sha1[20]);
uint packetsize(Packet*);
Packet* packetsplit(Packet*, int n);
void packetstats(void);
uchar* packettrailer(Packet*, int n);
int packettrim(Packet*, int offset, int n);
/* XXX should be own library? */
/*
* Logging
*/
typedef struct VtLog VtLog;
typedef struct VtLogChunk VtLogChunk;
struct VtLog
{
VtLog *next; /* in hash table */
char *name;
VtLogChunk *chunk;
uint nchunk;
VtLogChunk *w;
QLock lk;
int ref;
};
struct VtLogChunk
{
char *p;
char *ep;
char *wp;
};
VtLog* vtlogopen(char *name, uint size);
void vtlogprint(VtLog *log, char *fmt, ...);
void vtlog(char *name, char *fmt, ...);
void vtlogclose(VtLog*);
void vtlogremove(char *name);
char** vtlognames(int*);
void vtlogdump(int fd, VtLog*);
/* XXX begin actual venti.h */
typedef struct VtFcall VtFcall;
typedef struct VtConn VtConn;
typedef struct VtEntry VtEntry;
typedef struct VtRoot VtRoot;
/*
* Fundamental constants.
*/
enum
{
VtScoreSize = 20,
VtMaxStringSize = 1024,
VtMaxLumpSize = 56*1024,
VtPointerDepth = 7
};
#define VtMaxFileSize ((1ULL<<48)-1)
/*
* Strings in packets.
*/
int vtputstring(Packet*, char*);
int vtgetstring(Packet*, char**);
/*
* Block types.
*
* The initial Venti protocol had a much
* less regular list of block types.
* VtToDiskType converts from new to old.
*/
enum
{
VtDataType = 0<<3,
/* VtDataType+1, ... */
VtDirType = 1<<3,
/* VtDirType+1, ... */
VtRootType = 2<<3,
VtMaxType,
VtCorruptType = 0xFF,
VtTypeDepthMask = 7,
VtTypeBaseMask = ~VtTypeDepthMask
};
/* convert to/from on-disk type numbers */
uint vttodisktype(uint);
uint vtfromdisktype(uint);
/*
* VtEntry describes a Venti stream
*
* The _ enums are only used on the wire.
* They are not present in the VtEntry structure
* and should not be used by client programs.
* (The info is in the type field.)
*/
enum
{
VtEntryActive = 1<<0, /* entry is in use */
_VtEntryDir = 1<<1, /* a directory */
_VtEntryDepthShift = 2, /* shift for pointer depth */
_VtEntryDepthMask = 7<<2, /* mask for pointer depth */
VtEntryLocal = 1<<5 /* for local storage only */
};
enum
{
VtEntrySize = 40
};
struct VtEntry
{
ulong gen; /* generation number */
ushort psize; /* pointer block size */
ushort dsize; /* data block size */
uchar type;
uchar flags;
uvlong size;
uchar score[VtScoreSize];
};
void vtentrypack(VtEntry*, uchar*, int index);
int vtentryunpack(VtEntry*, uchar*, int index);
struct VtRoot
{
char name[128];
char type[128];
uchar score[VtScoreSize]; /* to a Dir block */
ushort blocksize; /* maximum block size */
uchar prev[VtScoreSize]; /* last root block */
};
enum
{
VtRootSize = 300,
VtRootVersion = 2
};
void vtrootpack(VtRoot*, uchar*);
int vtrootunpack(VtRoot*, uchar*);
/*
* score of zero length block
*/
extern uchar vtzeroscore[VtScoreSize];
/*
* zero extend and truncate blocks
*/
void vtzeroextend(int type, uchar *buf, uint n, uint nn);
uint vtzerotruncate(int type, uchar *buf, uint n);
/*
* parse score: mungs s
*/
int vtparsescore(char *s, char **prefix, uchar[VtScoreSize]);
/*
* formatting
* other than noted, these formats all ignore
* the width and precision arguments, and all flags
*
* V a venti score
*/
#pragma varargck type "V" uchar*
#pragma varargck type "F" VtFcall*
#pragma varargck type "T" void
#pragma varargck type "lT" void
int vtscorefmt(Fmt*);
/*
* error-checking malloc et al.
*/
void vtfree(void *);
void* vtmalloc(int);
void* vtmallocz(int);
void* vtrealloc(void *p, int);
void* vtbrk(int n);
char* vtstrdup(char *);
/*
* Venti protocol
*/
/*
* Crypto strengths
*/
enum
{
VtCryptoStrengthNone,
VtCryptoStrengthAuth,
VtCryptoStrengthWeak,
VtCryptoStrengthStrong
};
/*
* Crypto suites
*/
enum
{
VtCryptoNone,
VtCryptoSSL3,
VtCryptoTLS1,
VtCryptoMax
};
/*
* Codecs
*/
enum
{
VtCodecNone,
VtCodecDeflate,
VtCodecThwack,
VtCodecMax
};
enum
{
VtRerror = 1,
VtTping = 2,
VtRping,
VtThello = 4,
VtRhello,
VtTgoodbye = 6,
VtRgoodbye, /* not used */
VtTauth0 = 8,
VtRauth0,
VtTauth1 = 10,
VtRauth1,
VtTread = 12,
VtRread,
VtTwrite = 14,
VtRwrite,
VtTsync = 16,
VtRsync,
VtTmax
};
struct VtFcall
{
uchar msgtype;
uchar tag;
char *error; /* Rerror */
char *version; /* Thello */
char *uid; /* Thello */
uchar strength; /* Thello */
uchar *crypto; /* Thello */
uint ncrypto; /* Thello */
uchar *codec; /* Thello */
uint ncodec; /* Thello */
char *sid; /* Rhello */
uchar rcrypto; /* Rhello */
uchar rcodec; /* Rhello */
uchar *auth; /* TauthX, RauthX */
uint nauth; /* TauthX, RauthX */
uchar score[VtScoreSize]; /* Tread, Rwrite */
uchar blocktype; /* Tread, Twrite */
ushort count; /* Tread */
Packet *data; /* Rread, Twrite */
};
Packet* vtfcallpack(VtFcall*);
int vtfcallunpack(VtFcall*, Packet*);
void vtfcallclear(VtFcall*);
int vtfcallfmt(Fmt*);
enum
{
VtStateAlloc,
VtStateConnected,
VtStateClosed
};
struct VtConn
{
QLock lk;
QLock inlk;
QLock outlk;
int debug;
int infd;
int outfd;
int muxer;
void *writeq;
void *readq;
int state;
void *wait[256];
uint ntag;
uint nsleep;
Packet *part;
Rendez tagrend;
Rendez rpcfork;
char *version;
char *uid;
char *sid;
char addr[256]; /* address of other side */
};
VtConn* vtconn(int infd, int outfd);
VtConn* vtdial(char*);
void vtfreeconn(VtConn*);
int vtsend(VtConn*, Packet*);
Packet* vtrecv(VtConn*);
int vtversion(VtConn* z);
void vtdebug(VtConn* z, char*, ...);
void vthangup(VtConn* z);
int vtgoodbye(VtConn* z);
/* #pragma varargck argpos vtdebug 2 */
/* server */
typedef struct VtSrv VtSrv;
#pragma incomplete VtSrv
typedef struct VtReq VtReq;
struct VtReq
{
VtFcall tx;
VtFcall rx;
/* private */
VtSrv *srv;
void *sc;
};
int vtsrvhello(VtConn*);
VtSrv* vtlisten(char *addr);
VtReq* vtgetreq(VtSrv*);
void vtrespond(VtReq*);
/* client */
Packet* vtrpc(VtConn*, Packet*);
Packet* _vtrpc(VtConn*, Packet*, VtFcall*);
void vtrecvproc(void*); /* VtConn */
void vtsendproc(void*); /* VtConn */
int vtconnect(VtConn*);
int vthello(VtConn*);
int vtread(VtConn*, uchar score[VtScoreSize], uint type, uchar *buf, int n);
int vtwrite(VtConn*, uchar score[VtScoreSize], uint type, uchar *buf, int n);
Packet* vtreadpacket(VtConn*, uchar score[VtScoreSize], uint type, int n);
int vtwritepacket(VtConn*, uchar score[VtScoreSize], uint type, Packet *p);
int vtsync(VtConn*);
int vtping(VtConn*);
/*
* Data blocks and block cache.
*/
enum
{
NilBlock = ~0
};
typedef struct VtBlock VtBlock;
typedef struct VtCache VtCache;
#pragma incomplete VtCache
struct VtBlock
{
VtCache *c;
QLock lk;
uchar *data;
uchar score[VtScoreSize];
uchar type; /* BtXXX */
/* internal to cache */
int nlock;
int iostate;
int ref;
u32int heap;
VtBlock *next;
VtBlock **prev;
u32int used;
u32int used2;
u32int addr;
uintptr pc;
};
u32int vtglobaltolocal(uchar[VtScoreSize]);
void vtlocaltoglobal(u32int, uchar[VtScoreSize]);
VtCache*vtcachealloc(VtConn*, int blocksize, ulong nblocks);
void vtcachefree(VtCache*);
VtBlock*vtcachelocal(VtCache*, u32int addr, int type);
VtBlock*vtcacheglobal(VtCache*, uchar[VtScoreSize], int type);
VtBlock*vtcacheallocblock(VtCache*, int type);
void vtcachesetwrite(VtCache*,
int(*)(VtConn*, uchar[VtScoreSize], uint, uchar*, int));
void vtblockput(VtBlock*);
u32int vtcacheblocksize(VtCache*);
int vtblockwrite(VtBlock*);
VtBlock*vtblockcopy(VtBlock*);
void vtblockduplock(VtBlock*);
extern int vtcachencopy, vtcachenread, vtcachenwrite;
extern int vttracelevel;
/*
* Hash tree file tree.
*/
typedef struct VtFile VtFile;
struct VtFile
{
QLock lk;
int ref;
int local;
VtBlock *b; /* block containing this file */
uchar score[VtScoreSize]; /* score of block containing this file */
/* immutable */
VtCache *c;
int mode;
u32int gen;
int dsize;
int psize;
int dir;
VtFile *parent;
int epb; /* entries per block in parent */
u32int offset; /* entry offset in parent */
};
enum
{
VtOREAD,
VtOWRITE,
VtORDWR
};
VtBlock*vtfileblock(VtFile*, u32int, int mode);
int vtfileblockscore(VtFile*, u32int, uchar[VtScoreSize]);
void vtfileclose(VtFile*);
VtFile* _vtfilecreate(VtFile*, int offset, int psize, int dsize, int dir);
VtFile* vtfilecreate(VtFile*, int psize, int dsize, int dir);
VtFile* vtfilecreateroot(VtCache*, int psize, int dsize, int type);
int vtfileflush(VtFile*);
int vtfileflushbefore(VtFile*, u64int);
u32int vtfilegetdirsize(VtFile*);
int vtfilegetentry(VtFile*, VtEntry*);
uvlong vtfilegetsize(VtFile*);
void vtfileincref(VtFile*);
int vtfilelock2(VtFile*, VtFile*, int);
int vtfilelock(VtFile*, int);
VtFile* vtfileopen(VtFile*, u32int, int);
VtFile* vtfileopenroot(VtCache*, VtEntry*);
long vtfileread(VtFile*, void*, long, vlong);
int vtfileremove(VtFile*);
int vtfilesetdirsize(VtFile*, u32int);
int vtfilesetentry(VtFile*, VtEntry*);
int vtfilesetsize(VtFile*, u64int);
int vtfiletruncate(VtFile*);
void vtfileunlock(VtFile*);
long vtfilewrite(VtFile*, void*, long, vlong);
int vttimefmt(Fmt*);
extern int chattyventi;
extern int ventidoublechecksha1;
extern int ventilogging;
extern char *VtServerLog;