Blob


1 #include "stdinc.h"
2 #include "vac.h"
3 #include "dat.h"
4 #include "fns.h"
6 #define debug 0
8 static char EBadVacFormat[] = "bad format for vac file";
10 static VacFs *
11 vacfsalloc(VtConn *z, int bsize, int ncache, int mode)
12 {
13 VacFs *fs;
15 fs = vtmallocz(sizeof(VacFs));
16 fs->ref = 1;
17 fs->z = z;
18 fs->bsize = bsize;
19 fs->cache = vtcachealloc(z, bsize, ncache);
20 return fs;
21 }
23 static int
24 readscore(int fd, uchar score[VtScoreSize])
25 {
26 char buf[45], *pref;
27 int n;
29 n = readn(fd, buf, sizeof(buf)-1);
30 if(n < sizeof(buf)-1) {
31 werrstr("short read");
32 return -1;
33 }
34 buf[n] = 0;
36 if(vtparsescore(buf, &pref, score) < 0){
37 werrstr(EBadVacFormat);
38 return -1;
39 }
40 if(pref==nil || strcmp(pref, "vac") != 0) {
41 werrstr("not a vac file");
42 return -1;
43 }
44 return 0;
45 }
47 VacFs*
48 vacfsopen(VtConn *z, char *file, int mode, int ncache)
49 {
50 int fd;
51 uchar score[VtScoreSize];
53 fd = open(file, OREAD);
54 if(fd < 0)
55 return nil;
57 if(readscore(fd, score) < 0){
58 close(fd);
59 return nil;
60 }
61 close(fd);
63 return vacfsopenscore(z, score, mode, ncache);
64 }
66 VacFs*
67 vacfsopenscore(VtConn *z, u8int *score, int mode, int ncache)
68 {
69 VacFs *fs;
70 int n;
71 VtRoot rt;
72 uchar buf[VtRootSize];
73 VacFile *root;
74 VtFile *r;
75 VtEntry e;
77 n = vtread(z, score, VtRootType, buf, VtRootSize);
78 if(n < 0)
79 return nil;
80 if(n != VtRootSize){
81 werrstr("vtread on root too short");
82 return nil;
83 }
85 if(vtrootunpack(&rt, buf) < 0)
86 return nil;
88 if(strcmp(rt.type, "vac") != 0) {
89 werrstr("not a vac root");
90 return nil;
91 }
93 fs = vacfsalloc(z, rt.blocksize, ncache, mode);
94 memmove(fs->score, score, VtScoreSize);
95 fs->mode = mode;
97 memmove(e.score, rt.score, VtScoreSize);
98 e.gen = 0;
99 e.psize = (rt.blocksize/VtEntrySize)*VtEntrySize;
100 e.dsize = rt.blocksize;
101 e.type = VtDirType;
102 e.flags = VtEntryActive;
103 e.size = 3*VtEntrySize;
105 root = nil;
106 if((r = vtfileopenroot(fs->cache, &e)) == nil)
107 goto Err;
108 if(debug)
109 fprint(2, "r %p\n", r);
110 root = _vacfileroot(fs, r);
111 if(debug)
112 fprint(2, "root %p\n", root);
113 vtfileclose(r);
114 if(root == nil)
115 goto Err;
116 fs->root = root;
117 return fs;
118 Err:
119 if(root)
120 vacfiledecref(root);
121 vacfsclose(fs);
122 return nil;
125 VacFs *
126 vacfscreate(VtConn *z, int bsize, int ncache)
128 return vacfsalloc(z, bsize, ncache, VtORDWR);
131 int
132 vacfsmode(VacFs *fs)
134 return fs->mode;
137 VacFile*
138 vacfsgetroot(VacFs *fs)
140 return vacfileincref(fs->root);
143 int
144 vacfsgetblocksize(VacFs *fs)
146 return fs->bsize;
149 int
150 vacfsgetscore(VacFs *fs, u8int *score)
152 memmove(score, fs->score, VtScoreSize);
153 return 0;
156 int
157 _vacfsnextqid(VacFs *fs, uvlong *qid)
159 ++fs->qid;
160 *qid = fs->qid;
161 return 0;
164 int
165 vacfssync(VacFs *fs)
167 return 0;
170 void
171 vacfsclose(VacFs *fs)
173 if(fs->root)
174 vacfiledecref(fs->root);
175 fs->root = nil;
176 vtcachefree(fs->cache);
177 vtfree(fs);