1 typedef struct DataBlock DataBlock; 2 typedef struct Extent Extent; 3 typedef struct Entry Entry; 4 typedef struct ExtentList ExtentList; 5 typedef struct Fid Fid; 6 typedef struct Map Map; 7 typedef struct GroupSet GroupSet; 8 typedef struct Group Group; 9 typedef struct Uname Uname; 10 typedef struct LogMessage LogMessage; 11 typedef struct LogSegment LogSegment; 12 typedef struct Path Path; 13 typedef struct DirReadState DirReadState; 14 15 typedef struct Map PathMap; 16 typedef struct Map FidMap; 17 typedef struct Map GroupMap; 18 typedef struct Map UnameMap; 19 typedef struct Map Ust; 20 21 #pragma incomplete Extent 22 #pragma incomplete ExtentList 23 #pragma incomplete Map 24 #pragma incomplete DirReadState 25 26 enum { 27 L2LogSweeps = 2, 28 L2BlockCopies = 2, 29 LogDataLimit = 128, 30 LogAddr = (1 << 31), 31 Replacements = 2, /* extra space for replacements */ 32 Transfers = 2, /* extra space available for transfers */ 33 LogSlack = 1, /* extra space for data allocation */ 34 }; 35 36 struct Extent { 37 u32int min, max; 38 u32int flashaddr; /* encode block index, page number, and offset within page to min */ 39 }; 40 41 char *logfsextentlistnew(ExtentList **); 42 void logfsextentlistfree(ExtentList **); 43 char *logfsextentlistinsert(ExtentList *, Extent *, Extent **); 44 int logfsextentlistwalk(ExtentList *, int (*)(void *, Extent *, int),void *); 45 Extent *logfsextentlistmatch(ExtentList *, Extent *); 46 int logfsextentlistwalkrange(ExtentList *, 47 int (*)(void *, u32int, u32int, Extent *, u32int), 48 void *, u32int, u32int); 49 int logfsextentlistmatchall(ExtentList *, int (*)(void *, Extent *), void *, Extent *); 50 void logfsextentlistreset(ExtentList *); 51 52 struct Entry { 53 int inuse; 54 int deadandgone; /* removed */ 55 Qid qid; 56 struct Entry *parent; 57 char *name; 58 char *uid; 59 char *gid; 60 ulong mtime; 61 char *muid; 62 u32int perm; 63 struct Entry *next; 64 struct { 65 struct { 66 ulong cvers; 67 ulong length; 68 ExtentList *extent; 69 } file; 70 struct { 71 struct Entry *list; 72 } dir; 73 } u; 74 }; 75 76 char *logfsentrynew(LogfsServer *, int, u32int, Entry *, 77 char *, char *, char *, 78 u32int, char *, u32int, ulong, ulong, Entry **); 79 void logfsentryclunk(Entry *); 80 81 void logfsdrsfree(DirReadState **); 82 83 struct Fid { 84 ulong fid; 85 int openmode; 86 Entry *entry; 87 char *uname; 88 DirReadState *drs; 89 }; 90 91 typedef int LOGFSMAPWALKFN(void*, void*); 92 char *logfsmapnew(int, int (*)(void*, int), int (*)(void*, void*), int (*)(void*), void (*)(void*), Map **); 93 void logfsmapfree(Map **); 94 char *logfsmapnewentry(Map*, void*, void **); 95 void *logfsmapfindentry(Map*, void*); 96 int logfsmapdeleteentry(Map*, void*); 97 int logfsmapwalk(Map*, LOGFSMAPWALKFN*, void*); 98 99 char *logfsfidmapnew(FidMap **); 100 #define logfsfidmapfree(mp) logfsmapfree(mp) 101 char *logfsfidmapnewentry(FidMap *, ulong, Fid **); 102 #define logfsfidmapfindentry(m, fid) logfsmapfindentry(m, (void *)fid) 103 int logfsfidmapclunk(FidMap *, ulong); 104 105 struct Logfs { 106 int trace; 107 }; 108 109 char *logfsustnew(Ust**); 110 #define logfsustfree(m) logfsmapfree((m)) 111 char *logfsustadd(Ust*, char*); 112 113 struct Group { 114 char *uid; 115 char *uname; 116 Group *leader; 117 GroupSet *members; 118 }; 119 120 struct Uname { 121 char *uname; 122 Group *g; 123 }; 124 125 struct LogfsIdentityStore { 126 Ust *ids; 127 GroupMap *groupmap; 128 UnameMap *unamemap; 129 }; 130 131 char *logfsgroupmapnew(GroupMap **, UnameMap **); 132 #define logfsgroupmapfree(mp) logfsmapfree(mp) 133 #define logfsunamemapfree(mp) logfsmapfree(mp) 134 char *logfsgroupmapnewentry(GroupMap *, UnameMap *, char *, char *, Group **, Uname **); 135 #define logfsgroupmapdeleteentry(m, uid) logfsmapdeleteentry(m, (void *)uid) 136 #define logfsgroupmapfindentry(m, uid) logfsmapfindentry(m, uid) 137 #define logfsunamemapfindentry(m, uname) logfsmapfindentry(m, uname) 138 char *logfsgroupmapfinduname(GroupMap *, char *); 139 char *logfsunamemapfinduid(UnameMap *, char *); 140 #define logfsunamemapdeleteentry(m, uname) logfsmapdeleteentry(m, (void *)uname) 141 142 typedef int LOGFSGROUPSETWALKFN(void *, Group *); 143 char *logfsgroupsetnew(GroupSet **); 144 void logfsgroupsetfree(GroupSet **); 145 int logfsgroupsetadd(GroupSet *, Group *); 146 int logfsgroupsetremove(GroupSet *, Group *); 147 int logfsgroupsetwalk(GroupSet *, LOGFSGROUPSETWALKFN *, void *); 148 int logfsgroupsetismember(GroupSet *, Group *); 149 char *logfsisfindidfromname(LogfsIdentityStore *, char *); 150 char *logfsisfindnamefromid(LogfsIdentityStore *, char *); 151 #define logfsisfindgroupfromid(is, id) logfsgroupmapfindentry((is)->groupmap, id) 152 Group *logfsisfindgroupfromname(LogfsIdentityStore *, char *); 153 #define logfsisustadd(is, s) logfsustadd((is)->ids, s) 154 int logfsisgroupunameismember(LogfsIdentityStore *, Group *, char *); 155 int logfsisgroupuidismember(LogfsIdentityStore *, Group *, char *); 156 int logfsisgroupuidisleader(LogfsIdentityStore *, Group *, char *); 157 extern char *logfsisgroupnonename; 158 159 struct LogMessage { 160 uchar type; 161 u32int path; 162 union { 163 struct { 164 u32int nerase; 165 } start; 166 struct { 167 u32int perm; 168 u32int newpath; 169 u32int mtime; 170 u32int cvers; 171 char *name; 172 char *uid; 173 char *gid; 174 } create; 175 struct { 176 u32int mtime; 177 char *muid; 178 } remove; 179 struct { 180 u32int mtime; 181 u32int cvers; 182 char *muid; 183 } trunc; 184 struct { 185 u32int offset; 186 u32int count; 187 u32int mtime; 188 u32int cvers; 189 char *muid; 190 u32int flashaddr; 191 uchar *data; 192 } write; 193 struct { 194 char *name; 195 u32int perm; 196 char *uid; 197 char *gid; 198 u32int mtime; 199 char *muid; 200 } wstat; 201 } u; 202 }; 203 204 uint logfsconvM2S(uchar *, uint, LogMessage *); 205 uint logfssizeS2M(LogMessage *); 206 uint logfsconvS2M(LogMessage *, uchar *, uint); 207 void logfsdumpS(LogMessage *); 208 209 struct LogSegment { 210 int gen; /* generation number of this log */ 211 int dirty; /* written to since last sweep */ 212 long curblockindex; /* index of block being filled, or -1 */ 213 long unsweptblockindex; /* next block to sweep */ 214 int curpage; /* page within block */ 215 uchar *pagebuf; /* page buffer */ 216 int nbytes; /* bytes used in page buffer */ 217 long blockmap[1]; /* there are ll->blocks of these */ 218 }; 219 220 char *logfslogsegmentnew(LogfsServer *, int, LogSegment **); 221 void logfslogsegmentfree(LogSegment **); 222 char *logfslogbytes(LogfsServer *, int, uchar *, uint); 223 char *logfslog(LogfsServer *, int, LogMessage *); 224 char *logfslogwrite(LogfsServer *, int, u32int, u32int, int, u32int, 225 u32int, char *, uchar *, u32int *); 226 char *logfslogsegmentflush(LogfsServer *, int); 227 int lognicesizeforwrite(LogfsServer *, int, u32int, int); 228 char *logfsscan(LogfsServer *); 229 230 struct DataBlock { 231 Pageset free; 232 Pageset dirty; 233 long path; /* includes generation */ 234 long block; 235 }; 236 237 Pageset logfsdatapagemask(int, int); 238 239 struct Path { 240 ulong path; 241 Entry *entry; 242 }; 243 244 char *logfspathmapnew(PathMap **); 245 #define logfspathmapfree(mp) logfsmapfree(mp) 246 char *logfspathmapnewentry(PathMap *, ulong, Entry *, Path **); 247 #define logfspathmapfindentry(m, path) (Path *)logfsmapfindentry(m, (void *)path) 248 #define logfspathmapdeleteentry(m, path) logfsmapdeleteentry(m, (void *)path) 249 Entry *logfspathmapfinde(PathMap *, ulong); 250 251 enum { 252 LogfsTestDontFettleDataBlock = 1, 253 }; 254 255 struct LogfsServer { 256 LogfsLowLevel *ll; 257 LogfsBoot *lb; 258 FidMap *fidmap; 259 LogfsIdentityStore *is; 260 PathMap *pathmap; 261 LogSegment *activelog; 262 LogSegment *sweptlog; 263 long ndatablocks; 264 DataBlock *datablock; 265 ulong path; 266 Entry root; 267 int trace; 268 ulong openflags; 269 ulong testflags; 270 }; 271 272 int logfshashulong(void *, int); 273 274 int logfsuserpermcheck(LogfsServer *, Entry *, Fid *, ulong); 275 u32int logfsflattenentry(LogfsIdentityStore *, uchar *, u32int, Entry *); 276 char *logfsreplay(LogfsServer *, LogSegment *, int); 277 void logfsreplayfinddata(LogfsServer *); 278 279 #define dataseqof(path) ((path) >> L2BlockCopies) 280 #define copygenof(path) ((path) & ((1 << L2BlockCopies) -1)) 281 #define mkdatapath(seq, gen) (((seq) << L2BlockCopies) | (gen)) 282 #define gensucc(g, l2) (((g) + 1) & ((1 << (l2)) - 1)) 283 #define copygensucc(g) gensucc((g), L2BlockCopies) 284 #define loggenof(path) ((path >> L2BlockCopies) & ((1 << L2LogSweeps) - 1)) 285 #define logseqof(path) ((path) >> (L2BlockCopies + L2LogSweeps)) 286 #define mklogpath(seq, gen, copygen) (((((seq) << L2LogSweeps) | (gen)) << L2BlockCopies) | (copygen)) 287 #define loggensucc(g) gensucc((g), L2LogSweeps) 288 289 int logfsunconditionallymarkfreeanddirty(void *, Extent *, int); 290 void logfsflashaddr2spo(LogfsServer *, u32int, long *, int *, int *); 291 int logfsgn(uchar **, uchar *, char **); 292 u32int logfsspo2flashaddr(LogfsServer *, long, int, int); 293 int logfsgn(uchar **, uchar *, char **); 294 void logfsflashaddr2o(LogfsServer *, u32int, int *); 295 void logfsfreedatapages(LogfsServer *, long, Pageset); 296 void logfsfreeanddirtydatablockcheck(LogfsServer *, long); 297 298 typedef enum AllocReason { 299 AllocReasonReplace, 300 AllocReasonTransfer, 301 AllocReasonLogExtend, 302 AllocReasonDataExtend, 303 } AllocReason; 304 305 long logfsfindfreeblock(LogfsLowLevel *, AllocReason); 306 char *logfsbootfettleblock(LogfsBoot *, long, uchar tag, long, int *); 307 char *logfsserverreplacedatablock(LogfsServer *, long); 308 char *logfsserverreplacelogblock(LogfsServer *, LogSegment *, long); 309 char *logfsserverreplaceblock(LogfsServer *, LogSegment *, long); 310 char *logfsservercopyactivedata(LogfsServer *, long, long, int, 311 LogfsLowLevelReadResult *, int *); 312 313 char *logfsstrdup(char*); 314 315 extern char Enomem[]; 316 extern char Eshortstat[]; 317 extern char Enonexist[]; 318 extern char Etoobig[]; 319 extern char Eexist[]; 320 extern char Eunknown[]; 321 extern char Enotdir[]; 322 extern char Eisdir[]; 323 extern char logfsebadfid[]; 324 extern char logfsefidopen[]; 325 extern char logfsefidnotopen[]; 326 extern char logfsefidinuse[]; 327 extern char logfseopen[]; 328 extern char logfseaccess[]; 329 extern char logfselogmsgtoobig[]; 330 extern char logfselogfull[]; 331 extern char logfseinternal[]; 332 extern char logfsenotempty[]; 333 extern char logfseexcl[]; 334 extern char logfsefullreplacing[]; 335 extern char logfseunknownpath[]; 336