Blob


1 #include "stdinc.h"
2 #include "vac.h"
3 #include "dat.h"
4 #include "fns.h"
6 static char EBadVacFormat[] = "bad format for vac file";
8 static VacFs *
9 vacfsalloc(VtConn *z, int bsize, int ncache, int mode)
10 {
11 VacFs *fs;
13 fs = vtmallocz(sizeof(VacFs));
14 fs->ref = 1;
15 fs->z = z;
16 fs->bsize = bsize;
17 fs->cache = vtcachealloc(z, bsize, ncache, mode);
18 return fs;
19 }
21 static int
22 readscore(int fd, uchar score[VtScoreSize])
23 {
24 char buf[45], *pref;
25 int n;
27 n = readn(fd, buf, sizeof(buf)-1);
28 if(n < sizeof(buf)-1) {
29 werrstr("short read");
30 return -1;
31 }
32 buf[n] = 0;
34 if(vtparsescore(buf, &pref, score) < 0){
35 werrstr(EBadVacFormat);
36 return -1;
37 }
38 if(pref==nil || strcmp(pref, "vac") != 0) {
39 werrstr("not a vac file");
40 return -1;
41 }
42 return 0;
43 }
45 VacFs*
46 vacfsopen(VtConn *z, char *file, int mode, int ncache)
47 {
48 int fd;
49 uchar score[VtScoreSize];
51 fd = open(file, OREAD);
52 if(fd < 0)
53 return nil;
55 if(readscore(fd, score) < 0){
56 close(fd);
57 return nil;
58 }
59 close(fd);
61 return vacfsopenscore(z, score, mode, ncache);
62 }
64 VacFs*
65 vacfsopenscore(VtConn *z, u8int *score, int mode, int ncache)
66 {
67 VacFs *fs;
68 int n;
69 VtRoot rt;
70 uchar buf[VtRootSize];
71 VacFile *root;
72 VtFile *r;
73 VtEntry e;
75 n = vtread(z, score, VtRootType, buf, VtRootSize);
76 if(n < 0)
77 return nil;
78 if(n != VtRootSize){
79 werrstr("vtread on root too short");
80 return nil;
81 }
83 if(vtrootunpack(&rt, buf) < 0)
84 return nil;
86 if(strcmp(rt.type, "vac") != 0) {
87 werrstr("not a vac root");
88 return nil;
89 }
91 fs = vacfsalloc(z, rt.blocksize, ncache, mode);
92 memmove(fs->score, score, VtScoreSize);
93 fs->mode = mode;
95 memmove(e.score, rt.score, VtScoreSize);
96 e.gen = 0;
97 e.psize = (rt.blocksize/VtEntrySize)*VtEntrySize;
98 e.dsize = rt.blocksize;
99 e.type = VtDirType;
100 e.flags = VtEntryActive;
101 e.size = 3*VtEntrySize;
103 root = nil;
104 if((r = vtfileopenroot(fs->cache, &e)) == nil)
105 goto Err;
107 root = _vacfileroot(fs, r);
108 vtfileclose(r);
109 if(root == nil)
110 goto Err;
111 fs->root = root;
113 return fs;
114 Err:
115 if(root)
116 vacfiledecref(root);
117 vacfsclose(fs);
118 return nil;
121 VacFs *
122 vacfscreate(VtConn *z, int bsize, int ncache)
124 return vacfsalloc(z, bsize, ncache, VtORDWR);
127 int
128 vacfsmode(VacFs *fs)
130 return fs->mode;
133 VacFile*
134 vacfsgetroot(VacFs *fs)
136 return vacfileincref(fs->root);
139 int
140 vacfsgetblocksize(VacFs *fs)
142 return fs->bsize;
145 int
146 vacfsgetscore(VacFs *fs, u8int *score)
148 memmove(score, fs->score, VtScoreSize);
149 return 0;
152 int
153 _vacfsnextqid(VacFs *fs, uvlong *qid)
155 ++fs->qid;
156 *qid = fs->qid;
157 return 0;
160 int
161 vacfssync(VacFs *fs)
163 return 0;
166 void
167 vacfsclose(VacFs *fs)
169 if(fs->root)
170 vacfiledecref(fs->root);
171 fs->root = nil;
172 vtcachefree(fs->cache);
173 vtfree(fs);