Blame


1 7763a61a 2003-11-23 devnull #include "stdinc.h"
2 7763a61a 2003-11-23 devnull #include "vac.h"
3 7763a61a 2003-11-23 devnull #include "dat.h"
4 7763a61a 2003-11-23 devnull #include "fns.h"
5 7763a61a 2003-11-23 devnull #include "error.h"
6 7763a61a 2003-11-23 devnull
7 23fb2edb 2005-07-24 devnull #define debug 0
8 23fb2edb 2005-07-24 devnull
9 7763a61a 2003-11-23 devnull /*
10 7763a61a 2003-11-23 devnull * locking order is upwards. A thread can hold the lock for a VacFile
11 7763a61a 2003-11-23 devnull * and then acquire the lock of its parent
12 7763a61a 2003-11-23 devnull */
13 3d77c87e 2004-03-15 devnull struct VacFile
14 3d77c87e 2004-03-15 devnull {
15 3d77c87e 2004-03-15 devnull VacFs *fs; /* immutable */
16 7763a61a 2003-11-23 devnull
17 7763a61a 2003-11-23 devnull /* meta data for file: protected by the lk in the parent */
18 3d77c87e 2004-03-15 devnull int ref; /* holds this data structure up */
19 7763a61a 2003-11-23 devnull
20 3d77c87e 2004-03-15 devnull int partial; /* file was never really open */
21 3d77c87e 2004-03-15 devnull int removed; /* file has been removed */
22 3d77c87e 2004-03-15 devnull int dirty; /* dir is dirty with respect to meta data in block */
23 3d77c87e 2004-03-15 devnull u32int boff; /* block offset within msource for this file's metadata */
24 3d77c87e 2004-03-15 devnull VacDir dir; /* metadata for this file */
25 3d77c87e 2004-03-15 devnull VacFile *up; /* parent file */
26 3d77c87e 2004-03-15 devnull VacFile *next; /* sibling */
27 7763a61a 2003-11-23 devnull
28 3d77c87e 2004-03-15 devnull RWLock lk; /* lock for the following */
29 3d77c87e 2004-03-15 devnull VtFile *source; /* actual data */
30 3d77c87e 2004-03-15 devnull VtFile *msource; /* metadata for children in a directory */
31 3d77c87e 2004-03-15 devnull VacFile *down; /* children */
32 3d77c87e 2004-03-15 devnull int mode;
33 7763a61a 2003-11-23 devnull };
34 7763a61a 2003-11-23 devnull
35 3d77c87e 2004-03-15 devnull static int filelock(VacFile*);
36 3d77c87e 2004-03-15 devnull static u32int filemetaalloc(VacFile*, VacDir*, u32int);
37 3d77c87e 2004-03-15 devnull static int filemetaflush2(VacFile*, char*);
38 3d77c87e 2004-03-15 devnull static void filemetalock(VacFile*);
39 3d77c87e 2004-03-15 devnull static void filemetaunlock(VacFile*);
40 3d77c87e 2004-03-15 devnull static void fileraccess(VacFile*);
41 3d77c87e 2004-03-15 devnull static int filerlock(VacFile*);
42 3d77c87e 2004-03-15 devnull static void filerunlock(VacFile*);
43 3d77c87e 2004-03-15 devnull static void fileunlock(VacFile*);
44 3d77c87e 2004-03-15 devnull static void filewaccess(VacFile*, char*);
45 7763a61a 2003-11-23 devnull
46 3d77c87e 2004-03-15 devnull void mbinit(MetaBlock*, u8int*, uint, uint);
47 3d77c87e 2004-03-15 devnull int mbsearch(MetaBlock*, char*, int*, MetaEntry*);
48 3d77c87e 2004-03-15 devnull int mbresize(MetaBlock*, MetaEntry*, int);
49 3d77c87e 2004-03-15 devnull VacFile *vdlookup(VacFile*, char*);
50 7763a61a 2003-11-23 devnull
51 3d77c87e 2004-03-15 devnull static VacFile*
52 3d77c87e 2004-03-15 devnull filealloc(VacFs *fs)
53 7763a61a 2003-11-23 devnull {
54 3d77c87e 2004-03-15 devnull VacFile *f;
55 7763a61a 2003-11-23 devnull
56 3d77c87e 2004-03-15 devnull f = vtmallocz(sizeof(VacFile));
57 3d77c87e 2004-03-15 devnull f->ref = 1;
58 3d77c87e 2004-03-15 devnull f->fs = fs;
59 3d77c87e 2004-03-15 devnull f->boff = NilBlock;
60 3d77c87e 2004-03-15 devnull f->mode = fs->mode;
61 3d77c87e 2004-03-15 devnull return f;
62 7763a61a 2003-11-23 devnull }
63 7763a61a 2003-11-23 devnull
64 7763a61a 2003-11-23 devnull static void
65 3d77c87e 2004-03-15 devnull filefree(VacFile *f)
66 7763a61a 2003-11-23 devnull {
67 3d77c87e 2004-03-15 devnull vtfileclose(f->source);
68 3d77c87e 2004-03-15 devnull vtfileclose(f->msource);
69 3d77c87e 2004-03-15 devnull vdcleanup(&f->dir);
70 3d77c87e 2004-03-15 devnull memset(f, ~0, sizeof *f); /* paranoia */
71 3d77c87e 2004-03-15 devnull vtfree(f);
72 7763a61a 2003-11-23 devnull }
73 7763a61a 2003-11-23 devnull
74 3d77c87e 2004-03-15 devnull /*
75 3d77c87e 2004-03-15 devnull * the file is locked already
76 3d77c87e 2004-03-15 devnull * f->msource is unlocked
77 3d77c87e 2004-03-15 devnull */
78 3d77c87e 2004-03-15 devnull static VacFile*
79 3d77c87e 2004-03-15 devnull dirlookup(VacFile *f, char *elem)
80 7763a61a 2003-11-23 devnull {
81 7763a61a 2003-11-23 devnull int i;
82 7763a61a 2003-11-23 devnull MetaBlock mb;
83 3d77c87e 2004-03-15 devnull MetaEntry me;
84 3d77c87e 2004-03-15 devnull VtBlock *b;
85 3d77c87e 2004-03-15 devnull VtFile *meta;
86 3d77c87e 2004-03-15 devnull VacFile *ff;
87 3d77c87e 2004-03-15 devnull u32int bo, nb;
88 7763a61a 2003-11-23 devnull
89 3d77c87e 2004-03-15 devnull meta = f->msource;
90 3d77c87e 2004-03-15 devnull b = nil;
91 3d77c87e 2004-03-15 devnull if(vtfilelock(meta, -1) < 0)
92 3d77c87e 2004-03-15 devnull return nil;
93 3d77c87e 2004-03-15 devnull nb = (vtfilegetsize(meta)+meta->dsize-1)/meta->dsize;
94 3d77c87e 2004-03-15 devnull for(bo=0; bo<nb; bo++){
95 3d77c87e 2004-03-15 devnull b = vtfileblock(meta, bo, VtOREAD);
96 3d77c87e 2004-03-15 devnull if(b == nil)
97 3d77c87e 2004-03-15 devnull goto Err;
98 3d77c87e 2004-03-15 devnull if(mbunpack(&mb, b->data, meta->dsize) < 0)
99 3d77c87e 2004-03-15 devnull goto Err;
100 a20a1468 2005-01-16 devnull if(mbsearch(&mb, elem, &i, &me) >= 0){
101 3d77c87e 2004-03-15 devnull ff = filealloc(f->fs);
102 3d77c87e 2004-03-15 devnull if(vdunpack(&ff->dir, &me) < 0){
103 3d77c87e 2004-03-15 devnull filefree(ff);
104 3d77c87e 2004-03-15 devnull goto Err;
105 3d77c87e 2004-03-15 devnull }
106 3d77c87e 2004-03-15 devnull vtfileunlock(meta);
107 3d77c87e 2004-03-15 devnull vtblockput(b);
108 3d77c87e 2004-03-15 devnull ff->boff = bo;
109 3d77c87e 2004-03-15 devnull ff->mode = f->mode;
110 3d77c87e 2004-03-15 devnull return ff;
111 7763a61a 2003-11-23 devnull }
112 7763a61a 2003-11-23 devnull
113 3d77c87e 2004-03-15 devnull vtblockput(b);
114 3d77c87e 2004-03-15 devnull b = nil;
115 7763a61a 2003-11-23 devnull }
116 3d77c87e 2004-03-15 devnull werrstr(ENoFile);
117 7763a61a 2003-11-23 devnull /* fall through */
118 7763a61a 2003-11-23 devnull Err:
119 3d77c87e 2004-03-15 devnull vtfileunlock(meta);
120 3d77c87e 2004-03-15 devnull vtblockput(b);
121 7763a61a 2003-11-23 devnull return nil;
122 7763a61a 2003-11-23 devnull }
123 7763a61a 2003-11-23 devnull
124 3d77c87e 2004-03-15 devnull VacFile*
125 3d77c87e 2004-03-15 devnull _vacfileroot(VacFs *fs, VtFile *r)
126 7763a61a 2003-11-23 devnull {
127 23fb2edb 2005-07-24 devnull int redirected;
128 23fb2edb 2005-07-24 devnull char err[ERRMAX];
129 3d77c87e 2004-03-15 devnull VtBlock *b;
130 3d77c87e 2004-03-15 devnull VtFile *r0, *r1, *r2;
131 7763a61a 2003-11-23 devnull MetaBlock mb;
132 7763a61a 2003-11-23 devnull MetaEntry me;
133 7763a61a 2003-11-23 devnull VacFile *root, *mr;
134 7763a61a 2003-11-23 devnull
135 23fb2edb 2005-07-24 devnull redirected = 0;
136 23fb2edb 2005-07-24 devnull Top:
137 3d77c87e 2004-03-15 devnull b = nil;
138 7763a61a 2003-11-23 devnull root = nil;
139 7763a61a 2003-11-23 devnull mr = nil;
140 7763a61a 2003-11-23 devnull r1 = nil;
141 7763a61a 2003-11-23 devnull r2 = nil;
142 7763a61a 2003-11-23 devnull
143 3d77c87e 2004-03-15 devnull if(vtfilelock(r, -1) < 0)
144 3d77c87e 2004-03-15 devnull return nil;
145 3d77c87e 2004-03-15 devnull r0 = vtfileopen(r, 0, fs->mode);
146 23fb2edb 2005-07-24 devnull if(debug)
147 23fb2edb 2005-07-24 devnull fprint(2, "r0 %p\n", r0);
148 3d77c87e 2004-03-15 devnull if(r0 == nil)
149 7763a61a 2003-11-23 devnull goto Err;
150 23fb2edb 2005-07-24 devnull r2 = vtfileopen(r, 2, fs->mode);
151 23fb2edb 2005-07-24 devnull if(debug)
152 23fb2edb 2005-07-24 devnull fprint(2, "r2 %p\n", r2);
153 23fb2edb 2005-07-24 devnull if(r2 == nil){
154 23fb2edb 2005-07-24 devnull /*
155 23fb2edb 2005-07-24 devnull * some vac files (e.g., from fossil)
156 23fb2edb 2005-07-24 devnull * have an extra layer of indirection.
157 23fb2edb 2005-07-24 devnull */
158 23fb2edb 2005-07-24 devnull rerrstr(err, sizeof err);
159 23fb2edb 2005-07-24 devnull if(!redirected && strstr(err, "not active")){
160 caf12d8c 2005-07-25 devnull redirected = 1;
161 23fb2edb 2005-07-24 devnull vtfileunlock(r);
162 23fb2edb 2005-07-24 devnull r = r0;
163 23fb2edb 2005-07-24 devnull goto Top;
164 23fb2edb 2005-07-24 devnull }
165 23fb2edb 2005-07-24 devnull goto Err;
166 23fb2edb 2005-07-24 devnull }
167 3d77c87e 2004-03-15 devnull r1 = vtfileopen(r, 1, fs->mode);
168 23fb2edb 2005-07-24 devnull if(debug)
169 23fb2edb 2005-07-24 devnull fprint(2, "r1 %p\n", r1);
170 3d77c87e 2004-03-15 devnull if(r1 == nil)
171 7763a61a 2003-11-23 devnull goto Err;
172 7763a61a 2003-11-23 devnull
173 3d77c87e 2004-03-15 devnull mr = filealloc(fs);
174 7763a61a 2003-11-23 devnull mr->msource = r2;
175 7763a61a 2003-11-23 devnull r2 = nil;
176 7763a61a 2003-11-23 devnull
177 3d77c87e 2004-03-15 devnull root = filealloc(fs);
178 3d77c87e 2004-03-15 devnull root->boff = 0;
179 7763a61a 2003-11-23 devnull root->up = mr;
180 7763a61a 2003-11-23 devnull root->source = r0;
181 7763a61a 2003-11-23 devnull r0 = nil;
182 7763a61a 2003-11-23 devnull root->msource = r1;
183 7763a61a 2003-11-23 devnull r1 = nil;
184 7763a61a 2003-11-23 devnull
185 7763a61a 2003-11-23 devnull mr->down = root;
186 7763a61a 2003-11-23 devnull
187 3d77c87e 2004-03-15 devnull if(vtfilelock(mr->msource, -1) < 0)
188 7763a61a 2003-11-23 devnull goto Err;
189 3d77c87e 2004-03-15 devnull b = vtfileblock(mr->msource, 0, VtOREAD);
190 3d77c87e 2004-03-15 devnull vtfileunlock(mr->msource);
191 3d77c87e 2004-03-15 devnull if(b == nil)
192 3d77c87e 2004-03-15 devnull goto Err;
193 7763a61a 2003-11-23 devnull
194 3d77c87e 2004-03-15 devnull if(mbunpack(&mb, b->data, mr->msource->dsize) < 0)
195 7763a61a 2003-11-23 devnull goto Err;
196 3d77c87e 2004-03-15 devnull
197 3d77c87e 2004-03-15 devnull meunpack(&me, &mb, 0);
198 3d77c87e 2004-03-15 devnull if(vdunpack(&root->dir, &me) < 0)
199 7763a61a 2003-11-23 devnull goto Err;
200 3d77c87e 2004-03-15 devnull vtblockput(b);
201 3d77c87e 2004-03-15 devnull vtfileunlock(r);
202 3d77c87e 2004-03-15 devnull fileraccess(root);
203 7763a61a 2003-11-23 devnull
204 7763a61a 2003-11-23 devnull return root;
205 7763a61a 2003-11-23 devnull Err:
206 3d77c87e 2004-03-15 devnull vtblockput(b);
207 7763a61a 2003-11-23 devnull if(r0)
208 3d77c87e 2004-03-15 devnull vtfileclose(r0);
209 7763a61a 2003-11-23 devnull if(r1)
210 3d77c87e 2004-03-15 devnull vtfileclose(r1);
211 7763a61a 2003-11-23 devnull if(r2)
212 3d77c87e 2004-03-15 devnull vtfileclose(r2);
213 7763a61a 2003-11-23 devnull if(mr)
214 3d77c87e 2004-03-15 devnull filefree(mr);
215 7763a61a 2003-11-23 devnull if(root)
216 3d77c87e 2004-03-15 devnull filefree(root);
217 3d77c87e 2004-03-15 devnull vtfileunlock(r);
218 7763a61a 2003-11-23 devnull
219 7763a61a 2003-11-23 devnull return nil;
220 7763a61a 2003-11-23 devnull }
221 7763a61a 2003-11-23 devnull
222 3d77c87e 2004-03-15 devnull static VtFile *
223 3d77c87e 2004-03-15 devnull fileopensource(VacFile *f, u32int offset, u32int gen, int dir, uint mode)
224 7763a61a 2003-11-23 devnull {
225 3d77c87e 2004-03-15 devnull VtFile *r;
226 7763a61a 2003-11-23 devnull
227 3d77c87e 2004-03-15 devnull if(vtfilelock(f->source, mode) < 0)
228 3d77c87e 2004-03-15 devnull return nil;
229 3d77c87e 2004-03-15 devnull r = vtfileopen(f->source, offset, mode);
230 3d77c87e 2004-03-15 devnull vtfileunlock(f->source);
231 3d77c87e 2004-03-15 devnull if(r == nil)
232 3d77c87e 2004-03-15 devnull return nil;
233 3d77c87e 2004-03-15 devnull if(r->gen != gen){
234 3d77c87e 2004-03-15 devnull werrstr(ERemoved);
235 3d77c87e 2004-03-15 devnull goto Err;
236 3d77c87e 2004-03-15 devnull }
237 3d77c87e 2004-03-15 devnull if(r->dir != dir && r->mode != -1){
238 3d77c87e 2004-03-15 devnull fprint(2, "fileopensource: dir mismatch %d %d\n", r->dir, dir);
239 3d77c87e 2004-03-15 devnull werrstr(EBadMeta);
240 3d77c87e 2004-03-15 devnull goto Err;
241 3d77c87e 2004-03-15 devnull }
242 3d77c87e 2004-03-15 devnull return r;
243 3d77c87e 2004-03-15 devnull Err:
244 3d77c87e 2004-03-15 devnull vtfileclose(r);
245 3d77c87e 2004-03-15 devnull return nil;
246 3d77c87e 2004-03-15 devnull }
247 7763a61a 2003-11-23 devnull
248 3d77c87e 2004-03-15 devnull VacFile*
249 3d77c87e 2004-03-15 devnull _filewalk(VacFile *f, char *elem, int partial)
250 3d77c87e 2004-03-15 devnull {
251 3d77c87e 2004-03-15 devnull VacFile *ff;
252 3d77c87e 2004-03-15 devnull
253 3d77c87e 2004-03-15 devnull fileraccess(f);
254 3d77c87e 2004-03-15 devnull
255 3d77c87e 2004-03-15 devnull if(elem[0] == 0){
256 3d77c87e 2004-03-15 devnull werrstr(EBadPath);
257 7763a61a 2003-11-23 devnull return nil;
258 7763a61a 2003-11-23 devnull }
259 3d77c87e 2004-03-15 devnull
260 3d77c87e 2004-03-15 devnull if(!vacfileisdir(f)){
261 3d77c87e 2004-03-15 devnull werrstr(ENotDir);
262 7763a61a 2003-11-23 devnull return nil;
263 7763a61a 2003-11-23 devnull }
264 7763a61a 2003-11-23 devnull
265 3d77c87e 2004-03-15 devnull if(strcmp(elem, ".") == 0){
266 3d77c87e 2004-03-15 devnull return vacfileincref(f);
267 7763a61a 2003-11-23 devnull }
268 7763a61a 2003-11-23 devnull
269 3d77c87e 2004-03-15 devnull if(strcmp(elem, "..") == 0){
270 3d77c87e 2004-03-15 devnull if(vacfileisroot(f))
271 3d77c87e 2004-03-15 devnull return vacfileincref(f);
272 3d77c87e 2004-03-15 devnull return vacfileincref(f->up);
273 7763a61a 2003-11-23 devnull }
274 7763a61a 2003-11-23 devnull
275 3d77c87e 2004-03-15 devnull if(filelock(f) < 0)
276 7763a61a 2003-11-23 devnull return nil;
277 7763a61a 2003-11-23 devnull
278 3d77c87e 2004-03-15 devnull for(ff = f->down; ff; ff=ff->next){
279 3d77c87e 2004-03-15 devnull if(strcmp(elem, ff->dir.elem) == 0 && !ff->removed){
280 3d77c87e 2004-03-15 devnull ff->ref++;
281 7763a61a 2003-11-23 devnull goto Exit;
282 7763a61a 2003-11-23 devnull }
283 7763a61a 2003-11-23 devnull }
284 7763a61a 2003-11-23 devnull
285 3d77c87e 2004-03-15 devnull ff = dirlookup(f, elem);
286 3d77c87e 2004-03-15 devnull if(ff == nil)
287 7763a61a 2003-11-23 devnull goto Err;
288 3d77c87e 2004-03-15 devnull
289 3d77c87e 2004-03-15 devnull if(ff->dir.mode & ModeSnapshot)
290 3d77c87e 2004-03-15 devnull ff->mode = VtOREAD;
291 3d77c87e 2004-03-15 devnull
292 3d77c87e 2004-03-15 devnull if(partial){
293 3d77c87e 2004-03-15 devnull /*
294 3d77c87e 2004-03-15 devnull * Do nothing. We're opening this file only so we can clri it.
295 3d77c87e 2004-03-15 devnull * Usually the sources can't be opened, hence we won't even bother.
296 3d77c87e 2004-03-15 devnull * Be VERY careful with the returned file. If you hand it to a routine
297 3d77c87e 2004-03-15 devnull * expecting ff->source and/or ff->msource to be non-nil, we're
298 3d77c87e 2004-03-15 devnull * likely to dereference nil. FileClri should be the only routine
299 3d77c87e 2004-03-15 devnull * setting partial.
300 3d77c87e 2004-03-15 devnull */
301 3d77c87e 2004-03-15 devnull ff->partial = 1;
302 3d77c87e 2004-03-15 devnull }else if(ff->dir.mode & ModeDir){
303 3d77c87e 2004-03-15 devnull ff->source = fileopensource(f, ff->dir.entry, ff->dir.gen, 1, ff->mode);
304 3d77c87e 2004-03-15 devnull ff->msource = fileopensource(f, ff->dir.mentry, ff->dir.mgen, 0, ff->mode);
305 3d77c87e 2004-03-15 devnull if(ff->source == nil || ff->msource == nil)
306 7763a61a 2003-11-23 devnull goto Err;
307 3d77c87e 2004-03-15 devnull }else{
308 3d77c87e 2004-03-15 devnull ff->source = fileopensource(f, ff->dir.entry, ff->dir.gen, 0, ff->mode);
309 3d77c87e 2004-03-15 devnull if(ff->source == nil)
310 3d77c87e 2004-03-15 devnull goto Err;
311 7763a61a 2003-11-23 devnull }
312 7763a61a 2003-11-23 devnull
313 7763a61a 2003-11-23 devnull /* link in and up parent ref count */
314 3d77c87e 2004-03-15 devnull ff->next = f->down;
315 3d77c87e 2004-03-15 devnull f->down = ff;
316 3d77c87e 2004-03-15 devnull ff->up = f;
317 3d77c87e 2004-03-15 devnull vacfileincref(f);
318 7763a61a 2003-11-23 devnull Exit:
319 3d77c87e 2004-03-15 devnull fileunlock(f);
320 3d77c87e 2004-03-15 devnull return ff;
321 7763a61a 2003-11-23 devnull Err:
322 3d77c87e 2004-03-15 devnull fileunlock(f);
323 3d77c87e 2004-03-15 devnull if(ff != nil)
324 3d77c87e 2004-03-15 devnull vacfiledecref(ff);
325 7763a61a 2003-11-23 devnull return nil;
326 7763a61a 2003-11-23 devnull }
327 7763a61a 2003-11-23 devnull
328 3d77c87e 2004-03-15 devnull VacFile*
329 3d77c87e 2004-03-15 devnull vacfilewalk(VacFile *f, char *elem)
330 7763a61a 2003-11-23 devnull {
331 3d77c87e 2004-03-15 devnull return _filewalk(f, elem, 0);
332 3d77c87e 2004-03-15 devnull }
333 3d77c87e 2004-03-15 devnull
334 3d77c87e 2004-03-15 devnull VacFile*
335 3d77c87e 2004-03-15 devnull _fileopen(VacFs *fs, char *path, int partial)
336 3d77c87e 2004-03-15 devnull {
337 3d77c87e 2004-03-15 devnull VacFile *f, *ff;
338 3d77c87e 2004-03-15 devnull char *p, elem[VtMaxStringSize], *opath;
339 7763a61a 2003-11-23 devnull int n;
340 7763a61a 2003-11-23 devnull
341 3d77c87e 2004-03-15 devnull f = fs->root;
342 3d77c87e 2004-03-15 devnull vacfileincref(f);
343 3d77c87e 2004-03-15 devnull opath = path;
344 3d77c87e 2004-03-15 devnull while(*path != 0){
345 7763a61a 2003-11-23 devnull for(p = path; *p && *p != '/'; p++)
346 7763a61a 2003-11-23 devnull ;
347 7763a61a 2003-11-23 devnull n = p - path;
348 3d77c87e 2004-03-15 devnull if(n > 0){
349 3d77c87e 2004-03-15 devnull if(n > VtMaxStringSize){
350 3d77c87e 2004-03-15 devnull werrstr("%s: element too long", EBadPath);
351 7763a61a 2003-11-23 devnull goto Err;
352 7763a61a 2003-11-23 devnull }
353 7763a61a 2003-11-23 devnull memmove(elem, path, n);
354 7763a61a 2003-11-23 devnull elem[n] = 0;
355 3d77c87e 2004-03-15 devnull ff = _filewalk(f, elem, partial && *p=='\0');
356 3d77c87e 2004-03-15 devnull if(ff == nil){
357 3d77c87e 2004-03-15 devnull werrstr("%.*s: %R", utfnlen(opath, p-opath), opath);
358 7763a61a 2003-11-23 devnull goto Err;
359 3d77c87e 2004-03-15 devnull }
360 3d77c87e 2004-03-15 devnull vacfiledecref(f);
361 3d77c87e 2004-03-15 devnull f = ff;
362 7763a61a 2003-11-23 devnull }
363 7763a61a 2003-11-23 devnull if(*p == '/')
364 7763a61a 2003-11-23 devnull p++;
365 7763a61a 2003-11-23 devnull path = p;
366 7763a61a 2003-11-23 devnull }
367 3d77c87e 2004-03-15 devnull return f;
368 7763a61a 2003-11-23 devnull Err:
369 3d77c87e 2004-03-15 devnull vacfiledecref(f);
370 7763a61a 2003-11-23 devnull return nil;
371 7763a61a 2003-11-23 devnull }
372 7763a61a 2003-11-23 devnull
373 3d77c87e 2004-03-15 devnull VacFile*
374 3d77c87e 2004-03-15 devnull vacfileopen(VacFs *fs, char *path)
375 7763a61a 2003-11-23 devnull {
376 3d77c87e 2004-03-15 devnull return _fileopen(fs, path, 0);
377 3d77c87e 2004-03-15 devnull }
378 3d77c87e 2004-03-15 devnull
379 3d77c87e 2004-03-15 devnull #if 0
380 3d77c87e 2004-03-15 devnull static void
381 3d77c87e 2004-03-15 devnull filesettmp(VacFile *f, int istmp)
382 3d77c87e 2004-03-15 devnull {
383 3d77c87e 2004-03-15 devnull int i;
384 3d77c87e 2004-03-15 devnull VtEntry e;
385 3d77c87e 2004-03-15 devnull VtFile *r;
386 3d77c87e 2004-03-15 devnull
387 3d77c87e 2004-03-15 devnull for(i=0; i<2; i++){
388 3d77c87e 2004-03-15 devnull if(i==0)
389 3d77c87e 2004-03-15 devnull r = f->source;
390 3d77c87e 2004-03-15 devnull else
391 3d77c87e 2004-03-15 devnull r = f->msource;
392 3d77c87e 2004-03-15 devnull if(r == nil)
393 3d77c87e 2004-03-15 devnull continue;
394 3d77c87e 2004-03-15 devnull if(vtfilegetentry(r, &e) < 0){
395 3d77c87e 2004-03-15 devnull fprint(2, "vtfilegetentry failed (cannot happen): %r\n");
396 3d77c87e 2004-03-15 devnull continue;
397 3d77c87e 2004-03-15 devnull }
398 3d77c87e 2004-03-15 devnull if(istmp)
399 3d77c87e 2004-03-15 devnull e.flags |= VtEntryNoArchive;
400 3d77c87e 2004-03-15 devnull else
401 3d77c87e 2004-03-15 devnull e.flags &= ~VtEntryNoArchive;
402 3d77c87e 2004-03-15 devnull if(vtfilesetentry(r, &e) < 0){
403 3d77c87e 2004-03-15 devnull fprint(2, "vtfilesetentry failed (cannot happen): %r\n");
404 3d77c87e 2004-03-15 devnull continue;
405 3d77c87e 2004-03-15 devnull }
406 3d77c87e 2004-03-15 devnull }
407 3d77c87e 2004-03-15 devnull }
408 3d77c87e 2004-03-15 devnull #endif
409 3d77c87e 2004-03-15 devnull
410 3d77c87e 2004-03-15 devnull VacFile*
411 3d77c87e 2004-03-15 devnull vacfilecreate(VacFile *f, char *elem, ulong mode, char *uid)
412 3d77c87e 2004-03-15 devnull {
413 3d77c87e 2004-03-15 devnull VacFile *ff;
414 7763a61a 2003-11-23 devnull VacDir *dir;
415 3d77c87e 2004-03-15 devnull VtFile *pr, *r, *mr;
416 7763a61a 2003-11-23 devnull int isdir;
417 7763a61a 2003-11-23 devnull
418 3d77c87e 2004-03-15 devnull if(filelock(f) < 0)
419 7763a61a 2003-11-23 devnull return nil;
420 7763a61a 2003-11-23 devnull
421 7763a61a 2003-11-23 devnull r = nil;
422 7763a61a 2003-11-23 devnull mr = nil;
423 3d77c87e 2004-03-15 devnull for(ff = f->down; ff; ff=ff->next){
424 3d77c87e 2004-03-15 devnull if(strcmp(elem, ff->dir.elem) == 0 && !ff->removed){
425 3d77c87e 2004-03-15 devnull ff = nil;
426 3d77c87e 2004-03-15 devnull werrstr(EExists);
427 3d77c87e 2004-03-15 devnull goto Err1;
428 7763a61a 2003-11-23 devnull }
429 7763a61a 2003-11-23 devnull }
430 7763a61a 2003-11-23 devnull
431 3d77c87e 2004-03-15 devnull ff = dirlookup(f, elem);
432 3d77c87e 2004-03-15 devnull if(ff != nil){
433 3d77c87e 2004-03-15 devnull werrstr(EExists);
434 3d77c87e 2004-03-15 devnull goto Err1;
435 7763a61a 2003-11-23 devnull }
436 7763a61a 2003-11-23 devnull
437 3d77c87e 2004-03-15 devnull pr = f->source;
438 3d77c87e 2004-03-15 devnull if(pr->mode != VtORDWR){
439 3d77c87e 2004-03-15 devnull werrstr(EReadOnly);
440 3d77c87e 2004-03-15 devnull goto Err1;
441 3d77c87e 2004-03-15 devnull }
442 3d77c87e 2004-03-15 devnull
443 3d77c87e 2004-03-15 devnull if(vtfilelock2(f->source, f->msource, -1) < 0)
444 3d77c87e 2004-03-15 devnull goto Err1;
445 3d77c87e 2004-03-15 devnull
446 3d77c87e 2004-03-15 devnull ff = filealloc(f->fs);
447 7763a61a 2003-11-23 devnull isdir = mode & ModeDir;
448 7763a61a 2003-11-23 devnull
449 7b99eb27 2005-07-13 devnull r = vtfilecreate(pr, pr->psize, pr->dsize, isdir ? VtDirType : VtDataType);
450 7763a61a 2003-11-23 devnull if(r == nil)
451 7763a61a 2003-11-23 devnull goto Err;
452 3d77c87e 2004-03-15 devnull if(isdir){
453 7b99eb27 2005-07-13 devnull mr = vtfilecreate(pr, pr->psize, pr->dsize, VtDataType);
454 7763a61a 2003-11-23 devnull if(mr == nil)
455 7763a61a 2003-11-23 devnull goto Err;
456 7763a61a 2003-11-23 devnull }
457 3d77c87e 2004-03-15 devnull
458 3d77c87e 2004-03-15 devnull dir = &ff->dir;
459 3d77c87e 2004-03-15 devnull dir->elem = vtstrdup(elem);
460 3d77c87e 2004-03-15 devnull dir->entry = r->offset;
461 7763a61a 2003-11-23 devnull dir->gen = r->gen;
462 3d77c87e 2004-03-15 devnull if(isdir){
463 3d77c87e 2004-03-15 devnull dir->mentry = mr->offset;
464 7763a61a 2003-11-23 devnull dir->mgen = mr->gen;
465 7763a61a 2003-11-23 devnull }
466 7763a61a 2003-11-23 devnull dir->size = 0;
467 3d77c87e 2004-03-15 devnull if(_vacfsnextqid(f->fs, &dir->qid) < 0)
468 3d77c87e 2004-03-15 devnull goto Err;
469 3d77c87e 2004-03-15 devnull dir->uid = vtstrdup(uid);
470 3d77c87e 2004-03-15 devnull dir->gid = vtstrdup(f->dir.gid);
471 3d77c87e 2004-03-15 devnull dir->mid = vtstrdup(uid);
472 7763a61a 2003-11-23 devnull dir->mtime = time(0L);
473 7763a61a 2003-11-23 devnull dir->mcount = 0;
474 7763a61a 2003-11-23 devnull dir->ctime = dir->mtime;
475 7763a61a 2003-11-23 devnull dir->atime = dir->mtime;
476 7763a61a 2003-11-23 devnull dir->mode = mode;
477 7763a61a 2003-11-23 devnull
478 3d77c87e 2004-03-15 devnull ff->boff = filemetaalloc(f, dir, 0);
479 3d77c87e 2004-03-15 devnull if(ff->boff == NilBlock)
480 7763a61a 2003-11-23 devnull goto Err;
481 7763a61a 2003-11-23 devnull
482 3d77c87e 2004-03-15 devnull vtfileunlock(f->source);
483 3d77c87e 2004-03-15 devnull vtfileunlock(f->msource);
484 7763a61a 2003-11-23 devnull
485 3d77c87e 2004-03-15 devnull ff->source = r;
486 3d77c87e 2004-03-15 devnull ff->msource = mr;
487 7763a61a 2003-11-23 devnull
488 3d77c87e 2004-03-15 devnull #if 0
489 3d77c87e 2004-03-15 devnull if(mode&ModeTemporary){
490 3d77c87e 2004-03-15 devnull if(vtfilelock2(r, mr, -1) < 0)
491 3d77c87e 2004-03-15 devnull goto Err1;
492 3d77c87e 2004-03-15 devnull filesettmp(ff, 1);
493 3d77c87e 2004-03-15 devnull vtfileunlock(r);
494 3d77c87e 2004-03-15 devnull if(mr)
495 3d77c87e 2004-03-15 devnull vtfileunlock(mr);
496 3d77c87e 2004-03-15 devnull }
497 3d77c87e 2004-03-15 devnull #endif
498 3d77c87e 2004-03-15 devnull
499 3d77c87e 2004-03-15 devnull /* committed */
500 3d77c87e 2004-03-15 devnull
501 7763a61a 2003-11-23 devnull /* link in and up parent ref count */
502 3d77c87e 2004-03-15 devnull ff->next = f->down;
503 3d77c87e 2004-03-15 devnull f->down = ff;
504 3d77c87e 2004-03-15 devnull ff->up = f;
505 3d77c87e 2004-03-15 devnull vacfileincref(f);
506 7763a61a 2003-11-23 devnull
507 3d77c87e 2004-03-15 devnull filewaccess(f, uid);
508 7763a61a 2003-11-23 devnull
509 3d77c87e 2004-03-15 devnull fileunlock(f);
510 3d77c87e 2004-03-15 devnull return ff;
511 7763a61a 2003-11-23 devnull
512 7763a61a 2003-11-23 devnull Err:
513 3d77c87e 2004-03-15 devnull vtfileunlock(f->source);
514 3d77c87e 2004-03-15 devnull vtfileunlock(f->msource);
515 3d77c87e 2004-03-15 devnull Err1:
516 3d77c87e 2004-03-15 devnull if(r){
517 3d77c87e 2004-03-15 devnull vtfilelock(r, -1);
518 3d77c87e 2004-03-15 devnull vtfileremove(r);
519 3d77c87e 2004-03-15 devnull }
520 3d77c87e 2004-03-15 devnull if(mr){
521 3d77c87e 2004-03-15 devnull vtfilelock(mr, -1);
522 3d77c87e 2004-03-15 devnull vtfileremove(mr);
523 3d77c87e 2004-03-15 devnull }
524 3d77c87e 2004-03-15 devnull if(ff)
525 3d77c87e 2004-03-15 devnull vacfiledecref(ff);
526 3d77c87e 2004-03-15 devnull fileunlock(f);
527 3d77c87e 2004-03-15 devnull return nil;
528 7763a61a 2003-11-23 devnull }
529 7763a61a 2003-11-23 devnull
530 7763a61a 2003-11-23 devnull int
531 3d77c87e 2004-03-15 devnull vacfileblockscore(VacFile *f, u32int bn, u8int *score)
532 7763a61a 2003-11-23 devnull {
533 3d77c87e 2004-03-15 devnull VtFile *s;
534 7763a61a 2003-11-23 devnull uvlong size;
535 3d77c87e 2004-03-15 devnull int dsize, ret;
536 3d77c87e 2004-03-15 devnull
537 3d77c87e 2004-03-15 devnull ret = -1;
538 3d77c87e 2004-03-15 devnull if(filerlock(f) < 0)
539 3d77c87e 2004-03-15 devnull return -1;
540 3d77c87e 2004-03-15 devnull fileraccess(f);
541 3d77c87e 2004-03-15 devnull if(vtfilelock(f->source, VtOREAD) < 0)
542 3d77c87e 2004-03-15 devnull goto out;
543 3d77c87e 2004-03-15 devnull
544 3d77c87e 2004-03-15 devnull s = f->source;
545 3d77c87e 2004-03-15 devnull dsize = s->dsize;
546 3d77c87e 2004-03-15 devnull size = vtfilegetsize(s);
547 3d77c87e 2004-03-15 devnull if((uvlong)bn*dsize >= size)
548 3d77c87e 2004-03-15 devnull goto out;
549 3d77c87e 2004-03-15 devnull ret = vtfileblockscore(f->source, bn, score);
550 3d77c87e 2004-03-15 devnull
551 3d77c87e 2004-03-15 devnull out:
552 3d77c87e 2004-03-15 devnull vtfileunlock(f->source);
553 3d77c87e 2004-03-15 devnull filerunlock(f);
554 3d77c87e 2004-03-15 devnull return ret;
555 3d77c87e 2004-03-15 devnull }
556 3d77c87e 2004-03-15 devnull
557 3d77c87e 2004-03-15 devnull int
558 3d77c87e 2004-03-15 devnull vacfileread(VacFile *f, void *buf, int cnt, vlong offset)
559 3d77c87e 2004-03-15 devnull {
560 3d77c87e 2004-03-15 devnull VtFile *s;
561 3d77c87e 2004-03-15 devnull uvlong size;
562 3d77c87e 2004-03-15 devnull u32int bn;
563 7763a61a 2003-11-23 devnull int off, dsize, n, nn;
564 3d77c87e 2004-03-15 devnull VtBlock *b;
565 3d77c87e 2004-03-15 devnull uchar *p;
566 7763a61a 2003-11-23 devnull
567 3d77c87e 2004-03-15 devnull if(0)fprint(2, "fileRead: %s %d, %lld\n", f->dir.elem, cnt, offset);
568 7763a61a 2003-11-23 devnull
569 3d77c87e 2004-03-15 devnull if(filerlock(f) < 0)
570 7763a61a 2003-11-23 devnull return -1;
571 7763a61a 2003-11-23 devnull
572 3d77c87e 2004-03-15 devnull if(offset < 0){
573 3d77c87e 2004-03-15 devnull werrstr(EBadOffset);
574 3d77c87e 2004-03-15 devnull goto Err1;
575 3d77c87e 2004-03-15 devnull }
576 7763a61a 2003-11-23 devnull
577 3d77c87e 2004-03-15 devnull fileraccess(f);
578 7763a61a 2003-11-23 devnull
579 3d77c87e 2004-03-15 devnull if(vtfilelock(f->source, VtOREAD) < 0)
580 3d77c87e 2004-03-15 devnull goto Err1;
581 7763a61a 2003-11-23 devnull
582 3d77c87e 2004-03-15 devnull s = f->source;
583 3d77c87e 2004-03-15 devnull dsize = s->dsize;
584 3d77c87e 2004-03-15 devnull size = vtfilegetsize(s);
585 7763a61a 2003-11-23 devnull
586 7763a61a 2003-11-23 devnull if(offset >= size)
587 7763a61a 2003-11-23 devnull offset = size;
588 7763a61a 2003-11-23 devnull
589 7763a61a 2003-11-23 devnull if(cnt > size-offset)
590 7763a61a 2003-11-23 devnull cnt = size-offset;
591 7763a61a 2003-11-23 devnull bn = offset/dsize;
592 7763a61a 2003-11-23 devnull off = offset%dsize;
593 3d77c87e 2004-03-15 devnull p = buf;
594 3d77c87e 2004-03-15 devnull while(cnt > 0){
595 3d77c87e 2004-03-15 devnull b = vtfileblock(s, bn, OREAD);
596 3d77c87e 2004-03-15 devnull if(b == nil)
597 7763a61a 2003-11-23 devnull goto Err;
598 7763a61a 2003-11-23 devnull n = cnt;
599 7763a61a 2003-11-23 devnull if(n > dsize-off)
600 7763a61a 2003-11-23 devnull n = dsize-off;
601 3d77c87e 2004-03-15 devnull nn = dsize-off;
602 7763a61a 2003-11-23 devnull if(nn > n)
603 7763a61a 2003-11-23 devnull nn = n;
604 3d77c87e 2004-03-15 devnull memmove(p, b->data+off, nn);
605 3d77c87e 2004-03-15 devnull memset(p+nn, 0, nn-n);
606 7763a61a 2003-11-23 devnull off = 0;
607 7763a61a 2003-11-23 devnull bn++;
608 7763a61a 2003-11-23 devnull cnt -= n;
609 3d77c87e 2004-03-15 devnull p += n;
610 3d77c87e 2004-03-15 devnull vtblockput(b);
611 7763a61a 2003-11-23 devnull }
612 3d77c87e 2004-03-15 devnull vtfileunlock(s);
613 3d77c87e 2004-03-15 devnull filerunlock(f);
614 3d77c87e 2004-03-15 devnull return p-(uchar*)buf;
615 3d77c87e 2004-03-15 devnull
616 7763a61a 2003-11-23 devnull Err:
617 3d77c87e 2004-03-15 devnull vtfileunlock(s);
618 3d77c87e 2004-03-15 devnull Err1:
619 3d77c87e 2004-03-15 devnull filerunlock(f);
620 7763a61a 2003-11-23 devnull return -1;
621 7763a61a 2003-11-23 devnull }
622 7763a61a 2003-11-23 devnull
623 3d77c87e 2004-03-15 devnull #if 0
624 3d77c87e 2004-03-15 devnull /*
625 3d77c87e 2004-03-15 devnull * Changes the file block bn to be the given block score.
626 3d77c87e 2004-03-15 devnull * Very sneaky. Only used by flfmt.
627 3d77c87e 2004-03-15 devnull */
628 7763a61a 2003-11-23 devnull int
629 3d77c87e 2004-03-15 devnull filemapblock(VacFile *f, ulong bn, uchar score[VtScoreSize], ulong tag)
630 7763a61a 2003-11-23 devnull {
631 3d77c87e 2004-03-15 devnull VtBlock *b;
632 3d77c87e 2004-03-15 devnull VtEntry e;
633 3d77c87e 2004-03-15 devnull VtFile *s;
634 7763a61a 2003-11-23 devnull
635 3d77c87e 2004-03-15 devnull if(filelock(f) < 0)
636 7763a61a 2003-11-23 devnull return -1;
637 7763a61a 2003-11-23 devnull
638 3d77c87e 2004-03-15 devnull s = nil;
639 3d77c87e 2004-03-15 devnull if(f->dir.mode & ModeDir){
640 3d77c87e 2004-03-15 devnull werrstr(ENotFile);
641 7763a61a 2003-11-23 devnull goto Err;
642 7763a61a 2003-11-23 devnull }
643 7763a61a 2003-11-23 devnull
644 3d77c87e 2004-03-15 devnull if(f->source->mode != VtORDWR){
645 3d77c87e 2004-03-15 devnull werrstr(EReadOnly);
646 7763a61a 2003-11-23 devnull goto Err;
647 7763a61a 2003-11-23 devnull }
648 7763a61a 2003-11-23 devnull
649 3d77c87e 2004-03-15 devnull if(vtfilelock(f->source, -1) < 0)
650 3d77c87e 2004-03-15 devnull goto Err;
651 7763a61a 2003-11-23 devnull
652 3d77c87e 2004-03-15 devnull s = f->source;
653 3d77c87e 2004-03-15 devnull b = _vtfileblock(s, bn, VtORDWR, 1, tag);
654 3d77c87e 2004-03-15 devnull if(b == nil)
655 7763a61a 2003-11-23 devnull goto Err;
656 7763a61a 2003-11-23 devnull
657 3d77c87e 2004-03-15 devnull if(vtfilegetentry(s, &e) < 0)
658 3d77c87e 2004-03-15 devnull goto Err;
659 3d77c87e 2004-03-15 devnull if(b->l.type == BtDir){
660 3d77c87e 2004-03-15 devnull memmove(e.score, score, VtScoreSize);
661 3d77c87e 2004-03-15 devnull assert(e.tag == tag || e.tag == 0);
662 3d77c87e 2004-03-15 devnull e.tag = tag;
663 3d77c87e 2004-03-15 devnull e.flags |= VtEntryLocal;
664 3d77c87e 2004-03-15 devnull vtentrypack(&e, b->data, f->source->offset % f->source->epb);
665 3d77c87e 2004-03-15 devnull }else
666 3d77c87e 2004-03-15 devnull memmove(b->data + (bn%(e.psize/VtScoreSize))*VtScoreSize, score, VtScoreSize);
667 c1e6f642 2005-07-13 devnull /* vtblockdirty(b); */
668 3d77c87e 2004-03-15 devnull vtblockput(b);
669 3d77c87e 2004-03-15 devnull vtfileunlock(s);
670 3d77c87e 2004-03-15 devnull fileunlock(f);
671 3d77c87e 2004-03-15 devnull return 0;
672 7763a61a 2003-11-23 devnull
673 7763a61a 2003-11-23 devnull Err:
674 3d77c87e 2004-03-15 devnull if(s)
675 3d77c87e 2004-03-15 devnull vtfileunlock(s);
676 3d77c87e 2004-03-15 devnull fileunlock(f);
677 7763a61a 2003-11-23 devnull return -1;
678 7763a61a 2003-11-23 devnull }
679 3d77c87e 2004-03-15 devnull #endif
680 7763a61a 2003-11-23 devnull
681 7763a61a 2003-11-23 devnull int
682 3d77c87e 2004-03-15 devnull vacfilesetsize(VacFile *f, uvlong size)
683 7763a61a 2003-11-23 devnull {
684 3d77c87e 2004-03-15 devnull int r;
685 7763a61a 2003-11-23 devnull
686 3d77c87e 2004-03-15 devnull if(filelock(f) < 0)
687 3d77c87e 2004-03-15 devnull return -1;
688 3d77c87e 2004-03-15 devnull r = 0;
689 3d77c87e 2004-03-15 devnull if(f->dir.mode & ModeDir){
690 3d77c87e 2004-03-15 devnull werrstr(ENotFile);
691 3d77c87e 2004-03-15 devnull goto Err;
692 3d77c87e 2004-03-15 devnull }
693 3d77c87e 2004-03-15 devnull if(f->source->mode != VtORDWR){
694 3d77c87e 2004-03-15 devnull werrstr(EReadOnly);
695 3d77c87e 2004-03-15 devnull goto Err;
696 3d77c87e 2004-03-15 devnull }
697 3d77c87e 2004-03-15 devnull if(vtfilelock(f->source, -1) < 0)
698 3d77c87e 2004-03-15 devnull goto Err;
699 3d77c87e 2004-03-15 devnull r = vtfilesetsize(f->source, size);
700 3d77c87e 2004-03-15 devnull vtfileunlock(f->source);
701 3d77c87e 2004-03-15 devnull Err:
702 3d77c87e 2004-03-15 devnull fileunlock(f);
703 3d77c87e 2004-03-15 devnull return r;
704 7763a61a 2003-11-23 devnull }
705 7763a61a 2003-11-23 devnull
706 3d77c87e 2004-03-15 devnull int
707 3d77c87e 2004-03-15 devnull filewrite(VacFile *f, void *buf, int cnt, vlong offset, char *uid)
708 7763a61a 2003-11-23 devnull {
709 3d77c87e 2004-03-15 devnull VtFile *s;
710 3d77c87e 2004-03-15 devnull ulong bn;
711 3d77c87e 2004-03-15 devnull int off, dsize, n;
712 3d77c87e 2004-03-15 devnull VtBlock *b;
713 3d77c87e 2004-03-15 devnull uchar *p;
714 3d77c87e 2004-03-15 devnull vlong eof;
715 7763a61a 2003-11-23 devnull
716 3d77c87e 2004-03-15 devnull if(0)fprint(2, "fileWrite: %s %d, %lld\n", f->dir.elem, cnt, offset);
717 7763a61a 2003-11-23 devnull
718 3d77c87e 2004-03-15 devnull if(filelock(f) < 0)
719 3d77c87e 2004-03-15 devnull return -1;
720 3d77c87e 2004-03-15 devnull
721 3d77c87e 2004-03-15 devnull s = nil;
722 3d77c87e 2004-03-15 devnull if(f->dir.mode & ModeDir){
723 3d77c87e 2004-03-15 devnull werrstr(ENotFile);
724 3d77c87e 2004-03-15 devnull goto Err;
725 3d77c87e 2004-03-15 devnull }
726 3d77c87e 2004-03-15 devnull
727 3d77c87e 2004-03-15 devnull if(f->source->mode != VtORDWR){
728 3d77c87e 2004-03-15 devnull werrstr(EReadOnly);
729 3d77c87e 2004-03-15 devnull goto Err;
730 3d77c87e 2004-03-15 devnull }
731 3d77c87e 2004-03-15 devnull if(offset < 0){
732 3d77c87e 2004-03-15 devnull werrstr(EBadOffset);
733 3d77c87e 2004-03-15 devnull goto Err;
734 3d77c87e 2004-03-15 devnull }
735 3d77c87e 2004-03-15 devnull
736 3d77c87e 2004-03-15 devnull filewaccess(f, uid);
737 3d77c87e 2004-03-15 devnull
738 3d77c87e 2004-03-15 devnull if(vtfilelock(f->source, -1) < 0)
739 3d77c87e 2004-03-15 devnull goto Err;
740 3d77c87e 2004-03-15 devnull s = f->source;
741 3d77c87e 2004-03-15 devnull dsize = s->dsize;
742 3d77c87e 2004-03-15 devnull
743 3d77c87e 2004-03-15 devnull eof = vtfilegetsize(s);
744 3d77c87e 2004-03-15 devnull if(f->dir.mode & ModeAppend)
745 3d77c87e 2004-03-15 devnull offset = eof;
746 3d77c87e 2004-03-15 devnull bn = offset/dsize;
747 3d77c87e 2004-03-15 devnull off = offset%dsize;
748 3d77c87e 2004-03-15 devnull p = buf;
749 3d77c87e 2004-03-15 devnull while(cnt > 0){
750 3d77c87e 2004-03-15 devnull n = cnt;
751 3d77c87e 2004-03-15 devnull if(n > dsize-off)
752 3d77c87e 2004-03-15 devnull n = dsize-off;
753 3d77c87e 2004-03-15 devnull b = vtfileblock(s, bn, n<dsize?VtORDWR:VtOWRITE);
754 3d77c87e 2004-03-15 devnull if(b == nil){
755 3d77c87e 2004-03-15 devnull if(offset > eof)
756 3d77c87e 2004-03-15 devnull vtfilesetsize(s, offset);
757 3d77c87e 2004-03-15 devnull goto Err;
758 3d77c87e 2004-03-15 devnull }
759 3d77c87e 2004-03-15 devnull memmove(b->data+off, p, n);
760 3d77c87e 2004-03-15 devnull off = 0;
761 3d77c87e 2004-03-15 devnull cnt -= n;
762 3d77c87e 2004-03-15 devnull p += n;
763 3d77c87e 2004-03-15 devnull offset += n;
764 3d77c87e 2004-03-15 devnull bn++;
765 c1e6f642 2005-07-13 devnull /* vtblockdirty(b); */
766 3d77c87e 2004-03-15 devnull vtblockput(b);
767 3d77c87e 2004-03-15 devnull }
768 3d77c87e 2004-03-15 devnull if(offset > eof && vtfilesetsize(s, offset) < 0)
769 3d77c87e 2004-03-15 devnull goto Err;
770 3d77c87e 2004-03-15 devnull vtfileunlock(s);
771 3d77c87e 2004-03-15 devnull fileunlock(f);
772 3d77c87e 2004-03-15 devnull return p-(uchar*)buf;
773 3d77c87e 2004-03-15 devnull Err:
774 3d77c87e 2004-03-15 devnull if(s)
775 3d77c87e 2004-03-15 devnull vtfileunlock(s);
776 3d77c87e 2004-03-15 devnull fileunlock(f);
777 3d77c87e 2004-03-15 devnull return -1;
778 7763a61a 2003-11-23 devnull }
779 7763a61a 2003-11-23 devnull
780 7763a61a 2003-11-23 devnull int
781 3d77c87e 2004-03-15 devnull vacfilegetdir(VacFile *f, VacDir *dir)
782 7763a61a 2003-11-23 devnull {
783 3d77c87e 2004-03-15 devnull if(filerlock(f) < 0)
784 3d77c87e 2004-03-15 devnull return -1;
785 3d77c87e 2004-03-15 devnull
786 3d77c87e 2004-03-15 devnull filemetalock(f);
787 3d77c87e 2004-03-15 devnull vdcopy(dir, &f->dir);
788 3d77c87e 2004-03-15 devnull filemetaunlock(f);
789 3d77c87e 2004-03-15 devnull
790 3d77c87e 2004-03-15 devnull if(vacfileisdir(f) < 0){
791 3d77c87e 2004-03-15 devnull if(vtfilelock(f->source, VtOREAD) < 0){
792 3d77c87e 2004-03-15 devnull filerunlock(f);
793 3d77c87e 2004-03-15 devnull return -1;
794 3d77c87e 2004-03-15 devnull }
795 3d77c87e 2004-03-15 devnull dir->size = vtfilegetsize(f->source);
796 3d77c87e 2004-03-15 devnull vtfileunlock(f->source);
797 3d77c87e 2004-03-15 devnull }
798 3d77c87e 2004-03-15 devnull filerunlock(f);
799 3d77c87e 2004-03-15 devnull
800 3d77c87e 2004-03-15 devnull return 0;
801 7763a61a 2003-11-23 devnull }
802 7763a61a 2003-11-23 devnull
803 7763a61a 2003-11-23 devnull int
804 3d77c87e 2004-03-15 devnull vacfiletruncate(VacFile *f, char *uid)
805 7763a61a 2003-11-23 devnull {
806 3d77c87e 2004-03-15 devnull if(vacfileisdir(f)){
807 3d77c87e 2004-03-15 devnull werrstr(ENotFile);
808 3d77c87e 2004-03-15 devnull return -1;
809 3d77c87e 2004-03-15 devnull }
810 7763a61a 2003-11-23 devnull
811 3d77c87e 2004-03-15 devnull if(filelock(f) < 0)
812 3d77c87e 2004-03-15 devnull return -1;
813 3d77c87e 2004-03-15 devnull
814 3d77c87e 2004-03-15 devnull if(f->source->mode != VtORDWR){
815 3d77c87e 2004-03-15 devnull werrstr(EReadOnly);
816 3d77c87e 2004-03-15 devnull fileunlock(f);
817 3d77c87e 2004-03-15 devnull return -1;
818 3d77c87e 2004-03-15 devnull }
819 3d77c87e 2004-03-15 devnull if(vtfilelock(f->source, -1) < 0){
820 3d77c87e 2004-03-15 devnull fileunlock(f);
821 3d77c87e 2004-03-15 devnull return -1;
822 3d77c87e 2004-03-15 devnull }
823 3d77c87e 2004-03-15 devnull if(vtfiletruncate(f->source) < 0){
824 3d77c87e 2004-03-15 devnull vtfileunlock(f->source);
825 3d77c87e 2004-03-15 devnull fileunlock(f);
826 3d77c87e 2004-03-15 devnull return -1;
827 3d77c87e 2004-03-15 devnull }
828 3d77c87e 2004-03-15 devnull vtfileunlock(f->source);
829 3d77c87e 2004-03-15 devnull fileunlock(f);
830 3d77c87e 2004-03-15 devnull
831 3d77c87e 2004-03-15 devnull filewaccess(f, uid);
832 3d77c87e 2004-03-15 devnull
833 3d77c87e 2004-03-15 devnull return 0;
834 7763a61a 2003-11-23 devnull }
835 7763a61a 2003-11-23 devnull
836 3d77c87e 2004-03-15 devnull int
837 3d77c87e 2004-03-15 devnull vacfilesetdir(VacFile *f, VacDir *dir, char *uid)
838 7763a61a 2003-11-23 devnull {
839 3d77c87e 2004-03-15 devnull VacFile *ff;
840 3d77c87e 2004-03-15 devnull char *oelem;
841 3d77c87e 2004-03-15 devnull u32int mask;
842 3d77c87e 2004-03-15 devnull u64int size;
843 7763a61a 2003-11-23 devnull
844 3d77c87e 2004-03-15 devnull /* can not set permissions for the root */
845 3d77c87e 2004-03-15 devnull if(vacfileisroot(f)){
846 3d77c87e 2004-03-15 devnull werrstr(ERoot);
847 3d77c87e 2004-03-15 devnull return -1;
848 3d77c87e 2004-03-15 devnull }
849 7763a61a 2003-11-23 devnull
850 3d77c87e 2004-03-15 devnull if(filelock(f) < 0)
851 3d77c87e 2004-03-15 devnull return -1;
852 7763a61a 2003-11-23 devnull
853 3d77c87e 2004-03-15 devnull if(f->source->mode != VtORDWR){
854 3d77c87e 2004-03-15 devnull werrstr(EReadOnly);
855 3d77c87e 2004-03-15 devnull fileunlock(f);
856 3d77c87e 2004-03-15 devnull return -1;
857 3d77c87e 2004-03-15 devnull }
858 7763a61a 2003-11-23 devnull
859 3d77c87e 2004-03-15 devnull filemetalock(f);
860 7763a61a 2003-11-23 devnull
861 3d77c87e 2004-03-15 devnull /* check new name does not already exist */
862 3d77c87e 2004-03-15 devnull if(strcmp(f->dir.elem, dir->elem) != 0){
863 3d77c87e 2004-03-15 devnull for(ff = f->up->down; ff; ff=ff->next){
864 3d77c87e 2004-03-15 devnull if(strcmp(dir->elem, ff->dir.elem) == 0 && !ff->removed){
865 3d77c87e 2004-03-15 devnull werrstr(EExists);
866 3d77c87e 2004-03-15 devnull goto Err;
867 3d77c87e 2004-03-15 devnull }
868 3d77c87e 2004-03-15 devnull }
869 3d77c87e 2004-03-15 devnull
870 3d77c87e 2004-03-15 devnull ff = dirlookup(f->up, dir->elem);
871 3d77c87e 2004-03-15 devnull if(ff != nil){
872 3d77c87e 2004-03-15 devnull vacfiledecref(ff);
873 3d77c87e 2004-03-15 devnull werrstr(EExists);
874 3d77c87e 2004-03-15 devnull goto Err;
875 3d77c87e 2004-03-15 devnull }
876 3d77c87e 2004-03-15 devnull }
877 3d77c87e 2004-03-15 devnull
878 3d77c87e 2004-03-15 devnull if(vtfilelock2(f->source, f->msource, -1) < 0)
879 7763a61a 2003-11-23 devnull goto Err;
880 3d77c87e 2004-03-15 devnull if(!vacfileisdir(f)){
881 3d77c87e 2004-03-15 devnull size = vtfilegetsize(f->source);
882 3d77c87e 2004-03-15 devnull if(size != dir->size){
883 3d77c87e 2004-03-15 devnull if(vtfilesetsize(f->source, dir->size) < 0){
884 3d77c87e 2004-03-15 devnull vtfileunlock(f->source);
885 3d77c87e 2004-03-15 devnull if(f->msource)
886 3d77c87e 2004-03-15 devnull vtfileunlock(f->msource);
887 3d77c87e 2004-03-15 devnull goto Err;
888 3d77c87e 2004-03-15 devnull }
889 3d77c87e 2004-03-15 devnull /* commited to changing it now */
890 3d77c87e 2004-03-15 devnull }
891 3d77c87e 2004-03-15 devnull }
892 3d77c87e 2004-03-15 devnull /* commited to changing it now */
893 3d77c87e 2004-03-15 devnull #if 0
894 3d77c87e 2004-03-15 devnull if((f->dir.mode&ModeTemporary) != (dir->mode&ModeTemporary))
895 3d77c87e 2004-03-15 devnull filesettmp(f, dir->mode&ModeTemporary);
896 3d77c87e 2004-03-15 devnull #endif
897 3d77c87e 2004-03-15 devnull vtfileunlock(f->source);
898 3d77c87e 2004-03-15 devnull if(f->msource)
899 3d77c87e 2004-03-15 devnull vtfileunlock(f->msource);
900 7763a61a 2003-11-23 devnull
901 3d77c87e 2004-03-15 devnull oelem = nil;
902 3d77c87e 2004-03-15 devnull if(strcmp(f->dir.elem, dir->elem) != 0){
903 3d77c87e 2004-03-15 devnull oelem = f->dir.elem;
904 3d77c87e 2004-03-15 devnull f->dir.elem = vtstrdup(dir->elem);
905 3d77c87e 2004-03-15 devnull }
906 7763a61a 2003-11-23 devnull
907 3d77c87e 2004-03-15 devnull if(strcmp(f->dir.uid, dir->uid) != 0){
908 3d77c87e 2004-03-15 devnull vtfree(f->dir.uid);
909 3d77c87e 2004-03-15 devnull f->dir.uid = vtstrdup(dir->uid);
910 3d77c87e 2004-03-15 devnull }
911 3d77c87e 2004-03-15 devnull
912 3d77c87e 2004-03-15 devnull if(strcmp(f->dir.gid, dir->gid) != 0){
913 3d77c87e 2004-03-15 devnull vtfree(f->dir.gid);
914 3d77c87e 2004-03-15 devnull f->dir.gid = vtstrdup(dir->gid);
915 3d77c87e 2004-03-15 devnull }
916 3d77c87e 2004-03-15 devnull
917 3d77c87e 2004-03-15 devnull f->dir.mtime = dir->mtime;
918 3d77c87e 2004-03-15 devnull f->dir.atime = dir->atime;
919 3d77c87e 2004-03-15 devnull
920 cbeb0b26 2006-04-01 devnull /*fprint(2, "mode %x %x ", f->dir.mode, dir->mode); */
921 3d77c87e 2004-03-15 devnull mask = ~(ModeDir|ModeSnapshot);
922 3d77c87e 2004-03-15 devnull f->dir.mode &= ~mask;
923 3d77c87e 2004-03-15 devnull f->dir.mode |= mask & dir->mode;
924 3d77c87e 2004-03-15 devnull f->dirty = 1;
925 cbeb0b26 2006-04-01 devnull /*fprint(2, "->%x\n", f->dir.mode); */
926 3d77c87e 2004-03-15 devnull
927 3d77c87e 2004-03-15 devnull filemetaflush2(f, oelem);
928 3d77c87e 2004-03-15 devnull vtfree(oelem);
929 3d77c87e 2004-03-15 devnull
930 3d77c87e 2004-03-15 devnull filemetaunlock(f);
931 3d77c87e 2004-03-15 devnull fileunlock(f);
932 3d77c87e 2004-03-15 devnull
933 3d77c87e 2004-03-15 devnull filewaccess(f->up, uid);
934 3d77c87e 2004-03-15 devnull
935 7763a61a 2003-11-23 devnull return 0;
936 3d77c87e 2004-03-15 devnull Err:
937 3d77c87e 2004-03-15 devnull filemetaunlock(f);
938 3d77c87e 2004-03-15 devnull fileunlock(f);
939 3d77c87e 2004-03-15 devnull return -1;
940 7763a61a 2003-11-23 devnull }
941 7763a61a 2003-11-23 devnull
942 3d77c87e 2004-03-15 devnull int
943 3d77c87e 2004-03-15 devnull vacfilesetqidspace(VacFile *f, u64int offset, u64int max)
944 3d77c87e 2004-03-15 devnull {
945 3d77c87e 2004-03-15 devnull int ret;
946 7763a61a 2003-11-23 devnull
947 3d77c87e 2004-03-15 devnull if(filelock(f) < 0)
948 3d77c87e 2004-03-15 devnull return -1;
949 3d77c87e 2004-03-15 devnull filemetalock(f);
950 3d77c87e 2004-03-15 devnull f->dir.qidspace = 1;
951 3d77c87e 2004-03-15 devnull f->dir.qidoffset = offset;
952 3d77c87e 2004-03-15 devnull f->dir.qidmax = max;
953 3d77c87e 2004-03-15 devnull ret = filemetaflush2(f, nil);
954 3d77c87e 2004-03-15 devnull filemetaunlock(f);
955 3d77c87e 2004-03-15 devnull fileunlock(f);
956 3d77c87e 2004-03-15 devnull return ret;
957 3d77c87e 2004-03-15 devnull }
958 3d77c87e 2004-03-15 devnull
959 3d77c87e 2004-03-15 devnull uvlong
960 3d77c87e 2004-03-15 devnull vacfilegetid(VacFile *f)
961 7763a61a 2003-11-23 devnull {
962 3d77c87e 2004-03-15 devnull /* immutable */
963 3d77c87e 2004-03-15 devnull return f->dir.qid;
964 3d77c87e 2004-03-15 devnull }
965 7763a61a 2003-11-23 devnull
966 3d77c87e 2004-03-15 devnull ulong
967 3d77c87e 2004-03-15 devnull vacfilegetmcount(VacFile *f)
968 3d77c87e 2004-03-15 devnull {
969 3d77c87e 2004-03-15 devnull ulong mcount;
970 3d77c87e 2004-03-15 devnull
971 3d77c87e 2004-03-15 devnull filemetalock(f);
972 3d77c87e 2004-03-15 devnull mcount = f->dir.mcount;
973 3d77c87e 2004-03-15 devnull filemetaunlock(f);
974 3d77c87e 2004-03-15 devnull return mcount;
975 3d77c87e 2004-03-15 devnull }
976 3d77c87e 2004-03-15 devnull
977 3d77c87e 2004-03-15 devnull ulong
978 3d77c87e 2004-03-15 devnull vacfilegetmode(VacFile *f)
979 3d77c87e 2004-03-15 devnull {
980 3d77c87e 2004-03-15 devnull ulong mode;
981 3d77c87e 2004-03-15 devnull
982 3d77c87e 2004-03-15 devnull filemetalock(f);
983 3d77c87e 2004-03-15 devnull mode = f->dir.mode;
984 3d77c87e 2004-03-15 devnull filemetaunlock(f);
985 3d77c87e 2004-03-15 devnull return mode;
986 3d77c87e 2004-03-15 devnull }
987 3d77c87e 2004-03-15 devnull
988 3d77c87e 2004-03-15 devnull int
989 3d77c87e 2004-03-15 devnull vacfileisdir(VacFile *f)
990 3d77c87e 2004-03-15 devnull {
991 3d77c87e 2004-03-15 devnull /* immutable */
992 3d77c87e 2004-03-15 devnull return (f->dir.mode & ModeDir) != 0;
993 3d77c87e 2004-03-15 devnull }
994 3d77c87e 2004-03-15 devnull
995 3d77c87e 2004-03-15 devnull int
996 3d77c87e 2004-03-15 devnull vacfileisroot(VacFile *f)
997 3d77c87e 2004-03-15 devnull {
998 3d77c87e 2004-03-15 devnull return f == f->fs->root;
999 3d77c87e 2004-03-15 devnull }
1000 3d77c87e 2004-03-15 devnull
1001 3d77c87e 2004-03-15 devnull int
1002 3d77c87e 2004-03-15 devnull vacfilegetsize(VacFile *f, uvlong *size)
1003 3d77c87e 2004-03-15 devnull {
1004 3d77c87e 2004-03-15 devnull if(filerlock(f) < 0)
1005 3d77c87e 2004-03-15 devnull return 0;
1006 3d77c87e 2004-03-15 devnull if(vtfilelock(f->source, VtOREAD) < 0){
1007 3d77c87e 2004-03-15 devnull filerunlock(f);
1008 3d77c87e 2004-03-15 devnull return -1;
1009 7763a61a 2003-11-23 devnull }
1010 3d77c87e 2004-03-15 devnull *size = vtfilegetsize(f->source);
1011 3d77c87e 2004-03-15 devnull vtfileunlock(f->source);
1012 3d77c87e 2004-03-15 devnull filerunlock(f);
1013 3d77c87e 2004-03-15 devnull
1014 7763a61a 2003-11-23 devnull return 0;
1015 7763a61a 2003-11-23 devnull }
1016 7763a61a 2003-11-23 devnull
1017 7763a61a 2003-11-23 devnull int
1018 3d77c87e 2004-03-15 devnull vacfilegetvtentry(VacFile *f, VtEntry *e)
1019 3d77c87e 2004-03-15 devnull {
1020 3d77c87e 2004-03-15 devnull if(filerlock(f) < 0)
1021 7763a61a 2003-11-23 devnull return 0;
1022 3d77c87e 2004-03-15 devnull if(vtfilelock(f->source, VtOREAD) < 0){
1023 3d77c87e 2004-03-15 devnull filerunlock(f);
1024 3d77c87e 2004-03-15 devnull return -1;
1025 7763a61a 2003-11-23 devnull }
1026 3d77c87e 2004-03-15 devnull vtfilegetentry(f->source, e);
1027 3d77c87e 2004-03-15 devnull vtfileunlock(f->source);
1028 3d77c87e 2004-03-15 devnull filerunlock(f);
1029 7763a61a 2003-11-23 devnull
1030 3d77c87e 2004-03-15 devnull return 0;
1031 3d77c87e 2004-03-15 devnull }
1032 3d77c87e 2004-03-15 devnull
1033 3d77c87e 2004-03-15 devnull void
1034 3d77c87e 2004-03-15 devnull vacfilemetaflush(VacFile *f, int rec)
1035 3d77c87e 2004-03-15 devnull {
1036 3d77c87e 2004-03-15 devnull VacFile **kids, *p;
1037 3d77c87e 2004-03-15 devnull int nkids;
1038 3d77c87e 2004-03-15 devnull int i;
1039 3d77c87e 2004-03-15 devnull
1040 3d77c87e 2004-03-15 devnull filemetalock(f);
1041 3d77c87e 2004-03-15 devnull filemetaflush2(f, nil);
1042 3d77c87e 2004-03-15 devnull filemetaunlock(f);
1043 3d77c87e 2004-03-15 devnull
1044 3d77c87e 2004-03-15 devnull if(!rec || !vacfileisdir(f))
1045 3d77c87e 2004-03-15 devnull return;
1046 3d77c87e 2004-03-15 devnull
1047 3d77c87e 2004-03-15 devnull if(filelock(f) < 0)
1048 3d77c87e 2004-03-15 devnull return;
1049 3d77c87e 2004-03-15 devnull nkids = 0;
1050 3d77c87e 2004-03-15 devnull for(p=f->down; p; p=p->next)
1051 3d77c87e 2004-03-15 devnull nkids++;
1052 3d77c87e 2004-03-15 devnull kids = vtmalloc(nkids*sizeof(VacFile*));
1053 3d77c87e 2004-03-15 devnull i = 0;
1054 3d77c87e 2004-03-15 devnull for(p=f->down; p; p=p->next){
1055 3d77c87e 2004-03-15 devnull kids[i++] = p;
1056 3d77c87e 2004-03-15 devnull p->ref++;
1057 3d77c87e 2004-03-15 devnull }
1058 3d77c87e 2004-03-15 devnull fileunlock(f);
1059 3d77c87e 2004-03-15 devnull
1060 3d77c87e 2004-03-15 devnull for(i=0; i<nkids; i++){
1061 3d77c87e 2004-03-15 devnull vacfilemetaflush(kids[i], 1);
1062 3d77c87e 2004-03-15 devnull vacfiledecref(kids[i]);
1063 3d77c87e 2004-03-15 devnull }
1064 3d77c87e 2004-03-15 devnull vtfree(kids);
1065 3d77c87e 2004-03-15 devnull }
1066 3d77c87e 2004-03-15 devnull
1067 3d77c87e 2004-03-15 devnull /* assumes metaLock is held */
1068 3d77c87e 2004-03-15 devnull static int
1069 3d77c87e 2004-03-15 devnull filemetaflush2(VacFile *f, char *oelem)
1070 3d77c87e 2004-03-15 devnull {
1071 3d77c87e 2004-03-15 devnull VacFile *fp;
1072 3d77c87e 2004-03-15 devnull VtBlock *b, *bb;
1073 3d77c87e 2004-03-15 devnull MetaBlock mb;
1074 3d77c87e 2004-03-15 devnull MetaEntry me, me2;
1075 3d77c87e 2004-03-15 devnull int i, n;
1076 3d77c87e 2004-03-15 devnull u32int boff;
1077 3d77c87e 2004-03-15 devnull
1078 3d77c87e 2004-03-15 devnull if(!f->dirty)
1079 7763a61a 2003-11-23 devnull return 0;
1080 7763a61a 2003-11-23 devnull
1081 3d77c87e 2004-03-15 devnull if(oelem == nil)
1082 3d77c87e 2004-03-15 devnull oelem = f->dir.elem;
1083 3d77c87e 2004-03-15 devnull
1084 3d77c87e 2004-03-15 devnull fp = f->up;
1085 3d77c87e 2004-03-15 devnull
1086 3d77c87e 2004-03-15 devnull if(vtfilelock(fp->msource, -1) < 0)
1087 3d77c87e 2004-03-15 devnull return 0;
1088 3d77c87e 2004-03-15 devnull /* can happen if source is clri'ed out from under us */
1089 3d77c87e 2004-03-15 devnull if(f->boff == NilBlock)
1090 3d77c87e 2004-03-15 devnull goto Err1;
1091 3d77c87e 2004-03-15 devnull b = vtfileblock(fp->msource, f->boff, VtORDWR);
1092 3d77c87e 2004-03-15 devnull if(b == nil)
1093 3d77c87e 2004-03-15 devnull goto Err1;
1094 3d77c87e 2004-03-15 devnull
1095 3d77c87e 2004-03-15 devnull if(mbunpack(&mb, b->data, fp->msource->dsize) < 0)
1096 7763a61a 2003-11-23 devnull goto Err;
1097 3d77c87e 2004-03-15 devnull if(mbsearch(&mb, oelem, &i, &me) < 0)
1098 3d77c87e 2004-03-15 devnull goto Err;
1099 7763a61a 2003-11-23 devnull
1100 3d77c87e 2004-03-15 devnull n = vdsize(&f->dir);
1101 3d77c87e 2004-03-15 devnull if(0)fprint(2, "old size %d new size %d\n", me.size, n);
1102 3d77c87e 2004-03-15 devnull
1103 3d77c87e 2004-03-15 devnull if(mbresize(&mb, &me, n) >= 0){
1104 3d77c87e 2004-03-15 devnull /* fits in the block */
1105 3d77c87e 2004-03-15 devnull mbdelete(&mb, i, &me);
1106 3d77c87e 2004-03-15 devnull if(strcmp(f->dir.elem, oelem) != 0)
1107 3d77c87e 2004-03-15 devnull mbsearch(&mb, f->dir.elem, &i, &me2);
1108 3d77c87e 2004-03-15 devnull vdpack(&f->dir, &me);
1109 3d77c87e 2004-03-15 devnull mbinsert(&mb, i, &me);
1110 3d77c87e 2004-03-15 devnull mbpack(&mb);
1111 c1e6f642 2005-07-13 devnull /* vtblockdirty(b); */
1112 3d77c87e 2004-03-15 devnull vtblockput(b);
1113 3d77c87e 2004-03-15 devnull vtfileunlock(fp->msource);
1114 3d77c87e 2004-03-15 devnull f->dirty = 0;
1115 3d77c87e 2004-03-15 devnull return -1;
1116 7763a61a 2003-11-23 devnull }
1117 3d77c87e 2004-03-15 devnull
1118 3d77c87e 2004-03-15 devnull /*
1119 3d77c87e 2004-03-15 devnull * moving entry to another block
1120 3d77c87e 2004-03-15 devnull * it is feasible for the fs to crash leaving two copies
1121 3d77c87e 2004-03-15 devnull * of the directory entry. This is just too much work to
1122 3d77c87e 2004-03-15 devnull * fix. Given that entries are only allocated in a block that
1123 3d77c87e 2004-03-15 devnull * is less than PercentageFull, most modifications of meta data
1124 3d77c87e 2004-03-15 devnull * will fit within the block. i.e. this code should almost
1125 3d77c87e 2004-03-15 devnull * never be executed.
1126 3d77c87e 2004-03-15 devnull */
1127 3d77c87e 2004-03-15 devnull boff = filemetaalloc(fp, &f->dir, f->boff+1);
1128 3d77c87e 2004-03-15 devnull if(boff == NilBlock){
1129 3d77c87e 2004-03-15 devnull /* mbResize might have modified block */
1130 3d77c87e 2004-03-15 devnull mbpack(&mb);
1131 c1e6f642 2005-07-13 devnull /* vtblockdirty(b); */
1132 3d77c87e 2004-03-15 devnull goto Err;
1133 3d77c87e 2004-03-15 devnull }
1134 3d77c87e 2004-03-15 devnull fprint(2, "fileMetaFlush moving entry from %ud -> %ud\n", f->boff, boff);
1135 3d77c87e 2004-03-15 devnull f->boff = boff;
1136 3d77c87e 2004-03-15 devnull
1137 3d77c87e 2004-03-15 devnull /* make sure deletion goes to disk after new entry */
1138 3d77c87e 2004-03-15 devnull bb = vtfileblock(fp->msource, f->boff, VtORDWR);
1139 3d77c87e 2004-03-15 devnull mbdelete(&mb, i, &me);
1140 3d77c87e 2004-03-15 devnull mbpack(&mb);
1141 cbeb0b26 2006-04-01 devnull /* blockDependency(b, bb, -1, nil, nil); */
1142 3d77c87e 2004-03-15 devnull vtblockput(bb);
1143 c1e6f642 2005-07-13 devnull /* vtblockdirty(b); */
1144 3d77c87e 2004-03-15 devnull vtblockput(b);
1145 3d77c87e 2004-03-15 devnull vtfileunlock(fp->msource);
1146 3d77c87e 2004-03-15 devnull
1147 3d77c87e 2004-03-15 devnull f->dirty = 0;
1148 3d77c87e 2004-03-15 devnull
1149 3d77c87e 2004-03-15 devnull return 0;
1150 3d77c87e 2004-03-15 devnull
1151 7763a61a 2003-11-23 devnull Err:
1152 3d77c87e 2004-03-15 devnull vtblockput(b);
1153 3d77c87e 2004-03-15 devnull Err1:
1154 3d77c87e 2004-03-15 devnull vtfileunlock(fp->msource);
1155 3d77c87e 2004-03-15 devnull return -1;
1156 3d77c87e 2004-03-15 devnull }
1157 3d77c87e 2004-03-15 devnull
1158 3d77c87e 2004-03-15 devnull static int
1159 3d77c87e 2004-03-15 devnull filemetaremove(VacFile *f, char *uid)
1160 3d77c87e 2004-03-15 devnull {
1161 3d77c87e 2004-03-15 devnull VtBlock *b;
1162 3d77c87e 2004-03-15 devnull MetaBlock mb;
1163 3d77c87e 2004-03-15 devnull MetaEntry me;
1164 3d77c87e 2004-03-15 devnull int i;
1165 3d77c87e 2004-03-15 devnull VacFile *up;
1166 3d77c87e 2004-03-15 devnull
1167 3d77c87e 2004-03-15 devnull b = nil;
1168 3d77c87e 2004-03-15 devnull up = f->up;
1169 3d77c87e 2004-03-15 devnull filewaccess(up, uid);
1170 3d77c87e 2004-03-15 devnull filemetalock(f);
1171 3d77c87e 2004-03-15 devnull
1172 3d77c87e 2004-03-15 devnull if(vtfilelock(up->msource, VtORDWR) < 0)
1173 3d77c87e 2004-03-15 devnull goto Err;
1174 3d77c87e 2004-03-15 devnull b = vtfileblock(up->msource, f->boff, VtORDWR);
1175 3d77c87e 2004-03-15 devnull if(b == nil)
1176 3d77c87e 2004-03-15 devnull goto Err;
1177 3d77c87e 2004-03-15 devnull
1178 3d77c87e 2004-03-15 devnull if(mbunpack(&mb, b->data, up->msource->dsize) < 0)
1179 3d77c87e 2004-03-15 devnull goto Err;
1180 3d77c87e 2004-03-15 devnull if(mbsearch(&mb, f->dir.elem, &i, &me) < 0)
1181 3d77c87e 2004-03-15 devnull goto Err;
1182 3d77c87e 2004-03-15 devnull mbdelete(&mb, i, &me);
1183 3d77c87e 2004-03-15 devnull mbpack(&mb);
1184 3d77c87e 2004-03-15 devnull vtfileunlock(up->msource);
1185 3d77c87e 2004-03-15 devnull
1186 c1e6f642 2005-07-13 devnull /* vtblockdirty(b); */
1187 3d77c87e 2004-03-15 devnull vtblockput(b);
1188 3d77c87e 2004-03-15 devnull
1189 3d77c87e 2004-03-15 devnull f->removed = 1;
1190 3d77c87e 2004-03-15 devnull f->boff = NilBlock;
1191 3d77c87e 2004-03-15 devnull f->dirty = 0;
1192 3d77c87e 2004-03-15 devnull
1193 3d77c87e 2004-03-15 devnull filemetaunlock(f);
1194 7763a61a 2003-11-23 devnull return 0;
1195 3d77c87e 2004-03-15 devnull
1196 3d77c87e 2004-03-15 devnull Err:
1197 3d77c87e 2004-03-15 devnull vtfileunlock(up->msource);
1198 3d77c87e 2004-03-15 devnull vtblockput(b);
1199 3d77c87e 2004-03-15 devnull filemetaunlock(f);
1200 3d77c87e 2004-03-15 devnull return -1;
1201 7763a61a 2003-11-23 devnull }
1202 7763a61a 2003-11-23 devnull
1203 3d77c87e 2004-03-15 devnull /* assume file is locked, assume f->msource is locked */
1204 3d77c87e 2004-03-15 devnull static int
1205 3d77c87e 2004-03-15 devnull filecheckempty(VacFile *f)
1206 7763a61a 2003-11-23 devnull {
1207 3d77c87e 2004-03-15 devnull u32int i, n;
1208 3d77c87e 2004-03-15 devnull VtBlock *b;
1209 3d77c87e 2004-03-15 devnull MetaBlock mb;
1210 3d77c87e 2004-03-15 devnull VtFile *r;
1211 3d77c87e 2004-03-15 devnull
1212 3d77c87e 2004-03-15 devnull r = f->msource;
1213 3d77c87e 2004-03-15 devnull n = (vtfilegetsize(r)+r->dsize-1)/r->dsize;
1214 3d77c87e 2004-03-15 devnull for(i=0; i<n; i++){
1215 3d77c87e 2004-03-15 devnull b = vtfileblock(r, i, VtORDWR);
1216 3d77c87e 2004-03-15 devnull if(b == nil)
1217 3d77c87e 2004-03-15 devnull goto Err;
1218 3d77c87e 2004-03-15 devnull if(mbunpack(&mb, b->data, r->dsize) < 0)
1219 3d77c87e 2004-03-15 devnull goto Err;
1220 3d77c87e 2004-03-15 devnull if(mb.nindex > 0){
1221 3d77c87e 2004-03-15 devnull werrstr(ENotEmpty);
1222 3d77c87e 2004-03-15 devnull goto Err;
1223 3d77c87e 2004-03-15 devnull }
1224 3d77c87e 2004-03-15 devnull vtblockput(b);
1225 3d77c87e 2004-03-15 devnull }
1226 3d77c87e 2004-03-15 devnull return 0;
1227 3d77c87e 2004-03-15 devnull Err:
1228 3d77c87e 2004-03-15 devnull vtblockput(b);
1229 3d77c87e 2004-03-15 devnull return -1;
1230 7763a61a 2003-11-23 devnull }
1231 7763a61a 2003-11-23 devnull
1232 3d77c87e 2004-03-15 devnull int
1233 3d77c87e 2004-03-15 devnull vacfileremove(VacFile *f, char *muid)
1234 7763a61a 2003-11-23 devnull {
1235 3d77c87e 2004-03-15 devnull VacFile *ff;
1236 7763a61a 2003-11-23 devnull
1237 3d77c87e 2004-03-15 devnull /* can not remove the root */
1238 3d77c87e 2004-03-15 devnull if(vacfileisroot(f)){
1239 3d77c87e 2004-03-15 devnull werrstr(ERoot);
1240 3d77c87e 2004-03-15 devnull return -1;
1241 7763a61a 2003-11-23 devnull }
1242 7763a61a 2003-11-23 devnull
1243 3d77c87e 2004-03-15 devnull if(filelock(f) < 0)
1244 3d77c87e 2004-03-15 devnull return -1;
1245 3d77c87e 2004-03-15 devnull
1246 3d77c87e 2004-03-15 devnull if(f->source->mode != VtORDWR){
1247 3d77c87e 2004-03-15 devnull werrstr(EReadOnly);
1248 3d77c87e 2004-03-15 devnull goto Err1;
1249 7763a61a 2003-11-23 devnull }
1250 3d77c87e 2004-03-15 devnull if(vtfilelock2(f->source, f->msource, -1) < 0)
1251 3d77c87e 2004-03-15 devnull goto Err1;
1252 3d77c87e 2004-03-15 devnull if(vacfileisdir(f) && filecheckempty(f)<0)
1253 3d77c87e 2004-03-15 devnull goto Err;
1254 7763a61a 2003-11-23 devnull
1255 3d77c87e 2004-03-15 devnull for(ff=f->down; ff; ff=ff->next)
1256 3d77c87e 2004-03-15 devnull assert(ff->removed);
1257 7763a61a 2003-11-23 devnull
1258 3d77c87e 2004-03-15 devnull vtfileremove(f->source);
1259 3d77c87e 2004-03-15 devnull f->source = nil;
1260 3d77c87e 2004-03-15 devnull if(f->msource){
1261 3d77c87e 2004-03-15 devnull vtfileremove(f->msource);
1262 3d77c87e 2004-03-15 devnull f->msource = nil;
1263 3d77c87e 2004-03-15 devnull }
1264 7763a61a 2003-11-23 devnull
1265 3d77c87e 2004-03-15 devnull fileunlock(f);
1266 3d77c87e 2004-03-15 devnull
1267 3d77c87e 2004-03-15 devnull if(filemetaremove(f, muid) < 0)
1268 3d77c87e 2004-03-15 devnull return -1;
1269 3d77c87e 2004-03-15 devnull
1270 3d77c87e 2004-03-15 devnull return 0;
1271 3d77c87e 2004-03-15 devnull
1272 3d77c87e 2004-03-15 devnull Err:
1273 3d77c87e 2004-03-15 devnull vtfileunlock(f->source);
1274 3d77c87e 2004-03-15 devnull if(f->msource)
1275 3d77c87e 2004-03-15 devnull vtfileunlock(f->msource);
1276 3d77c87e 2004-03-15 devnull Err1:
1277 3d77c87e 2004-03-15 devnull fileunlock(f);
1278 3d77c87e 2004-03-15 devnull return -1;
1279 7763a61a 2003-11-23 devnull }
1280 7763a61a 2003-11-23 devnull
1281 3d77c87e 2004-03-15 devnull static int
1282 3d77c87e 2004-03-15 devnull clri(VacFile *f, char *uid)
1283 3d77c87e 2004-03-15 devnull {
1284 3d77c87e 2004-03-15 devnull int r;
1285 3d77c87e 2004-03-15 devnull
1286 3d77c87e 2004-03-15 devnull if(f == nil)
1287 3d77c87e 2004-03-15 devnull return -1;
1288 3d77c87e 2004-03-15 devnull if(f->up->source->mode != VtORDWR){
1289 3d77c87e 2004-03-15 devnull werrstr(EReadOnly);
1290 3d77c87e 2004-03-15 devnull vacfiledecref(f);
1291 3d77c87e 2004-03-15 devnull return -1;
1292 3d77c87e 2004-03-15 devnull }
1293 3d77c87e 2004-03-15 devnull r = filemetaremove(f, uid);
1294 3d77c87e 2004-03-15 devnull vacfiledecref(f);
1295 3d77c87e 2004-03-15 devnull return r;
1296 3d77c87e 2004-03-15 devnull }
1297 3d77c87e 2004-03-15 devnull
1298 7763a61a 2003-11-23 devnull int
1299 3d77c87e 2004-03-15 devnull vacfileclripath(VacFs *fs, char *path, char *uid)
1300 7763a61a 2003-11-23 devnull {
1301 3d77c87e 2004-03-15 devnull return clri(_fileopen(fs, path, 1), uid);
1302 3d77c87e 2004-03-15 devnull }
1303 7763a61a 2003-11-23 devnull
1304 3d77c87e 2004-03-15 devnull int
1305 3d77c87e 2004-03-15 devnull vacfileclri(VacFile *dir, char *elem, char *uid)
1306 3d77c87e 2004-03-15 devnull {
1307 3d77c87e 2004-03-15 devnull return clri(_filewalk(dir, elem, 1), uid);
1308 7763a61a 2003-11-23 devnull }
1309 7763a61a 2003-11-23 devnull
1310 3d77c87e 2004-03-15 devnull VacFile*
1311 3d77c87e 2004-03-15 devnull vacfileincref(VacFile *vf)
1312 3d77c87e 2004-03-15 devnull {
1313 3d77c87e 2004-03-15 devnull filemetalock(vf);
1314 3d77c87e 2004-03-15 devnull assert(vf->ref > 0);
1315 3d77c87e 2004-03-15 devnull vf->ref++;
1316 3d77c87e 2004-03-15 devnull filemetaunlock(vf);
1317 3d77c87e 2004-03-15 devnull return vf;
1318 3d77c87e 2004-03-15 devnull }
1319 3d77c87e 2004-03-15 devnull
1320 7763a61a 2003-11-23 devnull int
1321 3d77c87e 2004-03-15 devnull vacfiledecref(VacFile *f)
1322 7763a61a 2003-11-23 devnull {
1323 3d77c87e 2004-03-15 devnull VacFile *p, *q, **qq;
1324 7763a61a 2003-11-23 devnull
1325 3d77c87e 2004-03-15 devnull if(f->up == nil){
1326 3d77c87e 2004-03-15 devnull /* never linked in */
1327 3d77c87e 2004-03-15 devnull assert(f->ref == 1);
1328 3d77c87e 2004-03-15 devnull filefree(f);
1329 7763a61a 2003-11-23 devnull return 0;
1330 3d77c87e 2004-03-15 devnull }
1331 7763a61a 2003-11-23 devnull
1332 3d77c87e 2004-03-15 devnull filemetalock(f);
1333 3d77c87e 2004-03-15 devnull f->ref--;
1334 3d77c87e 2004-03-15 devnull if(f->ref > 0){
1335 3d77c87e 2004-03-15 devnull filemetaunlock(f);
1336 3d77c87e 2004-03-15 devnull return -1;
1337 7763a61a 2003-11-23 devnull }
1338 3d77c87e 2004-03-15 devnull assert(f->ref == 0);
1339 3d77c87e 2004-03-15 devnull assert(f->down == nil);
1340 7763a61a 2003-11-23 devnull
1341 3d77c87e 2004-03-15 devnull filemetaflush2(f, nil);
1342 7763a61a 2003-11-23 devnull
1343 3d77c87e 2004-03-15 devnull p = f->up;
1344 3d77c87e 2004-03-15 devnull qq = &p->down;
1345 3d77c87e 2004-03-15 devnull for(q = *qq; q; q = *qq){
1346 3d77c87e 2004-03-15 devnull if(q == f)
1347 3d77c87e 2004-03-15 devnull break;
1348 3d77c87e 2004-03-15 devnull qq = &q->next;
1349 3d77c87e 2004-03-15 devnull }
1350 3d77c87e 2004-03-15 devnull assert(q != nil);
1351 3d77c87e 2004-03-15 devnull *qq = f->next;
1352 3d77c87e 2004-03-15 devnull
1353 3d77c87e 2004-03-15 devnull filemetaunlock(f);
1354 3d77c87e 2004-03-15 devnull filefree(f);
1355 3d77c87e 2004-03-15 devnull vacfiledecref(p);
1356 3d77c87e 2004-03-15 devnull return 0;
1357 7763a61a 2003-11-23 devnull }
1358 7763a61a 2003-11-23 devnull
1359 3d77c87e 2004-03-15 devnull VacFile*
1360 a20a1468 2005-01-16 devnull vacfilegetparent(VacFile *f)
1361 7763a61a 2003-11-23 devnull {
1362 3d77c87e 2004-03-15 devnull if(vacfileisroot(f))
1363 3d77c87e 2004-03-15 devnull return vacfileincref(f);
1364 3d77c87e 2004-03-15 devnull return vacfileincref(f->up);
1365 7763a61a 2003-11-23 devnull }
1366 7763a61a 2003-11-23 devnull
1367 a20a1468 2005-01-16 devnull int
1368 a20a1468 2005-01-16 devnull vacfilewrite(VacFile *file, void *buf, int n, vlong offset, char *muid)
1369 a20a1468 2005-01-16 devnull {
1370 a20a1468 2005-01-16 devnull werrstr("read only file system");
1371 a20a1468 2005-01-16 devnull return -1;
1372 a20a1468 2005-01-16 devnull }
1373 a20a1468 2005-01-16 devnull
1374 3d77c87e 2004-03-15 devnull VacDirEnum*
1375 3d77c87e 2004-03-15 devnull vdeopen(VacFile *f)
1376 7763a61a 2003-11-23 devnull {
1377 3d77c87e 2004-03-15 devnull VacDirEnum *vde;
1378 3d77c87e 2004-03-15 devnull VacFile *p;
1379 7763a61a 2003-11-23 devnull
1380 3d77c87e 2004-03-15 devnull if(!vacfileisdir(f)){
1381 3d77c87e 2004-03-15 devnull werrstr(ENotDir);
1382 7763a61a 2003-11-23 devnull return nil;
1383 7763a61a 2003-11-23 devnull }
1384 7763a61a 2003-11-23 devnull
1385 3d77c87e 2004-03-15 devnull /* flush out meta data */
1386 3d77c87e 2004-03-15 devnull if(filelock(f) < 0)
1387 7763a61a 2003-11-23 devnull return nil;
1388 3d77c87e 2004-03-15 devnull for(p=f->down; p; p=p->next)
1389 3d77c87e 2004-03-15 devnull filemetaflush2(p, nil);
1390 3d77c87e 2004-03-15 devnull fileunlock(f);
1391 7763a61a 2003-11-23 devnull
1392 3d77c87e 2004-03-15 devnull vde = vtmallocz(sizeof(VacDirEnum));
1393 3d77c87e 2004-03-15 devnull vde->file = vacfileincref(f);
1394 7763a61a 2003-11-23 devnull
1395 3d77c87e 2004-03-15 devnull return vde;
1396 7763a61a 2003-11-23 devnull }
1397 7763a61a 2003-11-23 devnull
1398 7763a61a 2003-11-23 devnull static int
1399 3d77c87e 2004-03-15 devnull direntrysize(VtFile *s, ulong elem, ulong gen, uvlong *size)
1400 7763a61a 2003-11-23 devnull {
1401 3d77c87e 2004-03-15 devnull VtBlock *b;
1402 7763a61a 2003-11-23 devnull ulong bn;
1403 7763a61a 2003-11-23 devnull VtEntry e;
1404 3d77c87e 2004-03-15 devnull int epb;
1405 7763a61a 2003-11-23 devnull
1406 3d77c87e 2004-03-15 devnull epb = s->dsize/VtEntrySize;
1407 3d77c87e 2004-03-15 devnull bn = elem/epb;
1408 3d77c87e 2004-03-15 devnull elem -= bn*epb;
1409 7763a61a 2003-11-23 devnull
1410 3d77c87e 2004-03-15 devnull b = vtfileblock(s, bn, VtOREAD);
1411 3d77c87e 2004-03-15 devnull if(b == nil)
1412 7763a61a 2003-11-23 devnull goto Err;
1413 3d77c87e 2004-03-15 devnull if(vtentryunpack(&e, b->data, elem) < 0)
1414 7763a61a 2003-11-23 devnull goto Err;
1415 7763a61a 2003-11-23 devnull
1416 3d77c87e 2004-03-15 devnull /* hanging entries are returned as zero size */
1417 3d77c87e 2004-03-15 devnull if(!(e.flags & VtEntryActive) || e.gen != gen)
1418 3d77c87e 2004-03-15 devnull *size = 0;
1419 3d77c87e 2004-03-15 devnull else
1420 3d77c87e 2004-03-15 devnull *size = e.size;
1421 3d77c87e 2004-03-15 devnull vtblockput(b);
1422 3d77c87e 2004-03-15 devnull return 0;
1423 7763a61a 2003-11-23 devnull
1424 7763a61a 2003-11-23 devnull Err:
1425 3d77c87e 2004-03-15 devnull vtblockput(b);
1426 3d77c87e 2004-03-15 devnull return -1;
1427 7763a61a 2003-11-23 devnull }
1428 7763a61a 2003-11-23 devnull
1429 3d77c87e 2004-03-15 devnull static int
1430 3d77c87e 2004-03-15 devnull vdefill(VacDirEnum *vde)
1431 7763a61a 2003-11-23 devnull {
1432 3d77c87e 2004-03-15 devnull int i, n;
1433 3d77c87e 2004-03-15 devnull VtFile *meta, *source;
1434 7763a61a 2003-11-23 devnull MetaBlock mb;
1435 7763a61a 2003-11-23 devnull MetaEntry me;
1436 3d77c87e 2004-03-15 devnull VacFile *f;
1437 3d77c87e 2004-03-15 devnull VtBlock *b;
1438 3d77c87e 2004-03-15 devnull VacDir *de;
1439 7763a61a 2003-11-23 devnull
1440 3d77c87e 2004-03-15 devnull /* clean up first */
1441 3d77c87e 2004-03-15 devnull for(i=vde->i; i<vde->n; i++)
1442 3d77c87e 2004-03-15 devnull vdcleanup(vde->buf+i);
1443 3d77c87e 2004-03-15 devnull vtfree(vde->buf);
1444 3d77c87e 2004-03-15 devnull vde->buf = nil;
1445 3d77c87e 2004-03-15 devnull vde->i = 0;
1446 3d77c87e 2004-03-15 devnull vde->n = 0;
1447 7763a61a 2003-11-23 devnull
1448 3d77c87e 2004-03-15 devnull f = vde->file;
1449 7763a61a 2003-11-23 devnull
1450 3d77c87e 2004-03-15 devnull source = f->source;
1451 3d77c87e 2004-03-15 devnull meta = f->msource;
1452 7763a61a 2003-11-23 devnull
1453 3d77c87e 2004-03-15 devnull b = vtfileblock(meta, vde->boff, VtOREAD);
1454 3d77c87e 2004-03-15 devnull if(b == nil)
1455 7763a61a 2003-11-23 devnull goto Err;
1456 3d77c87e 2004-03-15 devnull if(mbunpack(&mb, b->data, meta->dsize) < 0)
1457 7763a61a 2003-11-23 devnull goto Err;
1458 7763a61a 2003-11-23 devnull
1459 3d77c87e 2004-03-15 devnull n = mb.nindex;
1460 3d77c87e 2004-03-15 devnull vde->buf = vtmalloc(n * sizeof(VacDir));
1461 3d77c87e 2004-03-15 devnull
1462 3d77c87e 2004-03-15 devnull for(i=0; i<n; i++){
1463 3d77c87e 2004-03-15 devnull de = vde->buf + i;
1464 3d77c87e 2004-03-15 devnull meunpack(&me, &mb, i);
1465 3d77c87e 2004-03-15 devnull if(vdunpack(de, &me) < 0)
1466 7763a61a 2003-11-23 devnull goto Err;
1467 3d77c87e 2004-03-15 devnull vde->n++;
1468 3d77c87e 2004-03-15 devnull if(!(de->mode & ModeDir))
1469 3d77c87e 2004-03-15 devnull if(direntrysize(source, de->entry, de->gen, &de->size) < 0)
1470 3d77c87e 2004-03-15 devnull goto Err;
1471 7763a61a 2003-11-23 devnull }
1472 3d77c87e 2004-03-15 devnull vde->boff++;
1473 3d77c87e 2004-03-15 devnull vtblockput(b);
1474 3d77c87e 2004-03-15 devnull return 0;
1475 7763a61a 2003-11-23 devnull Err:
1476 3d77c87e 2004-03-15 devnull vtblockput(b);
1477 7763a61a 2003-11-23 devnull return -1;
1478 7763a61a 2003-11-23 devnull }
1479 7763a61a 2003-11-23 devnull
1480 3d77c87e 2004-03-15 devnull int
1481 3d77c87e 2004-03-15 devnull vderead(VacDirEnum *vde, VacDir *de)
1482 3d77c87e 2004-03-15 devnull {
1483 3d77c87e 2004-03-15 devnull int ret, didread;
1484 3d77c87e 2004-03-15 devnull VacFile *f;
1485 3d77c87e 2004-03-15 devnull u32int nb;
1486 3d77c87e 2004-03-15 devnull
1487 3d77c87e 2004-03-15 devnull f = vde->file;
1488 3d77c87e 2004-03-15 devnull if(filerlock(f) < 0)
1489 3d77c87e 2004-03-15 devnull return -1;
1490 3d77c87e 2004-03-15 devnull
1491 3d77c87e 2004-03-15 devnull if(vtfilelock2(f->source, f->msource, VtOREAD) < 0){
1492 3d77c87e 2004-03-15 devnull filerunlock(f);
1493 3d77c87e 2004-03-15 devnull return -1;
1494 3d77c87e 2004-03-15 devnull }
1495 3d77c87e 2004-03-15 devnull
1496 3d77c87e 2004-03-15 devnull nb = (vtfilegetsize(f->msource)+f->msource->dsize-1)/f->msource->dsize;
1497 3d77c87e 2004-03-15 devnull
1498 3d77c87e 2004-03-15 devnull didread = 0;
1499 3d77c87e 2004-03-15 devnull while(vde->i >= vde->n){
1500 3d77c87e 2004-03-15 devnull if(vde->boff >= nb){
1501 3d77c87e 2004-03-15 devnull ret = 0;
1502 3d77c87e 2004-03-15 devnull goto Return;
1503 3d77c87e 2004-03-15 devnull }
1504 3d77c87e 2004-03-15 devnull didread = 1;
1505 3d77c87e 2004-03-15 devnull if(vdefill(vde) < 0){
1506 3d77c87e 2004-03-15 devnull ret = -1;
1507 3d77c87e 2004-03-15 devnull goto Return;
1508 3d77c87e 2004-03-15 devnull }
1509 3d77c87e 2004-03-15 devnull }
1510 3d77c87e 2004-03-15 devnull
1511 3d77c87e 2004-03-15 devnull memmove(de, vde->buf + vde->i, sizeof(VacDir));
1512 3d77c87e 2004-03-15 devnull vde->i++;
1513 3d77c87e 2004-03-15 devnull ret = 1;
1514 3d77c87e 2004-03-15 devnull
1515 3d77c87e 2004-03-15 devnull Return:
1516 3d77c87e 2004-03-15 devnull vtfileunlock(f->source);
1517 3d77c87e 2004-03-15 devnull vtfileunlock(f->msource);
1518 3d77c87e 2004-03-15 devnull filerunlock(f);
1519 3d77c87e 2004-03-15 devnull
1520 3d77c87e 2004-03-15 devnull if(didread)
1521 3d77c87e 2004-03-15 devnull fileraccess(f);
1522 3d77c87e 2004-03-15 devnull return ret;
1523 3d77c87e 2004-03-15 devnull }
1524 3d77c87e 2004-03-15 devnull
1525 7763a61a 2003-11-23 devnull void
1526 3d77c87e 2004-03-15 devnull vdeclose(VacDirEnum *vde)
1527 7763a61a 2003-11-23 devnull {
1528 3d77c87e 2004-03-15 devnull int i;
1529 3d77c87e 2004-03-15 devnull if(vde == nil)
1530 7763a61a 2003-11-23 devnull return;
1531 3d77c87e 2004-03-15 devnull for(i=vde->i; i<vde->n; i++)
1532 3d77c87e 2004-03-15 devnull vdcleanup(vde->buf+i);
1533 3d77c87e 2004-03-15 devnull vtfree(vde->buf);
1534 3d77c87e 2004-03-15 devnull vacfiledecref(vde->file);
1535 3d77c87e 2004-03-15 devnull vtfree(vde);
1536 7763a61a 2003-11-23 devnull }
1537 7763a61a 2003-11-23 devnull
1538 3d77c87e 2004-03-15 devnull /*
1539 3d77c87e 2004-03-15 devnull * caller must lock f->source and f->msource
1540 3d77c87e 2004-03-15 devnull * caller must NOT lock the source and msource
1541 3d77c87e 2004-03-15 devnull * referenced by dir.
1542 3d77c87e 2004-03-15 devnull */
1543 3d77c87e 2004-03-15 devnull static u32int
1544 3d77c87e 2004-03-15 devnull filemetaalloc(VacFile *f, VacDir *dir, u32int start)
1545 7763a61a 2003-11-23 devnull {
1546 3d77c87e 2004-03-15 devnull u32int nb, bo;
1547 a6662a36 2005-01-04 devnull VtBlock *b;
1548 7763a61a 2003-11-23 devnull MetaBlock mb;
1549 3d77c87e 2004-03-15 devnull int nn;
1550 3d77c87e 2004-03-15 devnull uchar *p;
1551 a6662a36 2005-01-04 devnull int i, n;
1552 3d77c87e 2004-03-15 devnull MetaEntry me;
1553 3d77c87e 2004-03-15 devnull VtFile *s, *ms;
1554 7763a61a 2003-11-23 devnull
1555 3d77c87e 2004-03-15 devnull s = f->source;
1556 3d77c87e 2004-03-15 devnull ms = f->msource;
1557 3d77c87e 2004-03-15 devnull
1558 3d77c87e 2004-03-15 devnull n = vdsize(dir);
1559 3d77c87e 2004-03-15 devnull nb = (vtfilegetsize(ms)+ms->dsize-1)/ms->dsize;
1560 3d77c87e 2004-03-15 devnull b = nil;
1561 7763a61a 2003-11-23 devnull if(start > nb)
1562 7763a61a 2003-11-23 devnull start = nb;
1563 3d77c87e 2004-03-15 devnull for(bo=start; bo<nb; bo++){
1564 3d77c87e 2004-03-15 devnull b = vtfileblock(ms, bo, VtORDWR);
1565 3d77c87e 2004-03-15 devnull if(b == nil)
1566 7763a61a 2003-11-23 devnull goto Err;
1567 3d77c87e 2004-03-15 devnull if(mbunpack(&mb, b->data, ms->dsize) < 0)
1568 7763a61a 2003-11-23 devnull goto Err;
1569 3d77c87e 2004-03-15 devnull nn = (mb.maxsize*FullPercentage/100) - mb.size + mb.free;
1570 3d77c87e 2004-03-15 devnull if(n <= nn && mb.nindex < mb.maxindex)
1571 7763a61a 2003-11-23 devnull break;
1572 3d77c87e 2004-03-15 devnull vtblockput(b);
1573 3d77c87e 2004-03-15 devnull b = nil;
1574 7763a61a 2003-11-23 devnull }
1575 3d77c87e 2004-03-15 devnull
1576 7763a61a 2003-11-23 devnull /* add block to meta file */
1577 3d77c87e 2004-03-15 devnull if(b == nil){
1578 3d77c87e 2004-03-15 devnull b = vtfileblock(ms, bo, VtORDWR);
1579 3d77c87e 2004-03-15 devnull if(b == nil)
1580 7763a61a 2003-11-23 devnull goto Err;
1581 3d77c87e 2004-03-15 devnull vtfilesetsize(ms, (nb+1)*ms->dsize);
1582 3d77c87e 2004-03-15 devnull mbinit(&mb, b->data, ms->dsize, ms->dsize/BytesPerEntry);
1583 7763a61a 2003-11-23 devnull }
1584 3d77c87e 2004-03-15 devnull
1585 3d77c87e 2004-03-15 devnull p = mballoc(&mb, n);
1586 3d77c87e 2004-03-15 devnull if(p == nil){
1587 3d77c87e 2004-03-15 devnull /* mbAlloc might have changed block */
1588 3d77c87e 2004-03-15 devnull mbpack(&mb);
1589 c1e6f642 2005-07-13 devnull /* vtblockdirty(b); */
1590 3d77c87e 2004-03-15 devnull werrstr(EBadMeta);
1591 3d77c87e 2004-03-15 devnull goto Err;
1592 3d77c87e 2004-03-15 devnull }
1593 3d77c87e 2004-03-15 devnull
1594 3d77c87e 2004-03-15 devnull mbsearch(&mb, dir->elem, &i, &me);
1595 3d77c87e 2004-03-15 devnull assert(me.p == nil);
1596 3d77c87e 2004-03-15 devnull me.p = p;
1597 3d77c87e 2004-03-15 devnull me.size = n;
1598 3d77c87e 2004-03-15 devnull vdpack(dir, &me);
1599 3d77c87e 2004-03-15 devnull mbinsert(&mb, i, &me);
1600 3d77c87e 2004-03-15 devnull mbpack(&mb);
1601 3d77c87e 2004-03-15 devnull
1602 3d77c87e 2004-03-15 devnull #ifdef notdef /* XXX */
1603 3d77c87e 2004-03-15 devnull /* meta block depends on super block for qid ... */
1604 3d77c87e 2004-03-15 devnull bb = cacheLocal(b->c, PartSuper, 0, VtOREAD);
1605 3d77c87e 2004-03-15 devnull blockDependency(b, bb, -1, nil, nil);
1606 3d77c87e 2004-03-15 devnull vtblockput(bb);
1607 3d77c87e 2004-03-15 devnull
1608 3d77c87e 2004-03-15 devnull /* ... and one or two dir entries */
1609 3d77c87e 2004-03-15 devnull epb = s->dsize/VtEntrySize;
1610 3d77c87e 2004-03-15 devnull bb = vtfileblock(s, dir->entry/epb, VtOREAD);
1611 3d77c87e 2004-03-15 devnull blockDependency(b, bb, -1, nil, nil);
1612 3d77c87e 2004-03-15 devnull vtblockput(bb);
1613 3d77c87e 2004-03-15 devnull if(dir->mode & ModeDir){
1614 3d77c87e 2004-03-15 devnull bb = sourceBlock(s, dir->mentry/epb, VtOREAD);
1615 3d77c87e 2004-03-15 devnull blockDependency(b, bb, -1, nil, nil);
1616 3d77c87e 2004-03-15 devnull vtblockput(bb);
1617 3d77c87e 2004-03-15 devnull }
1618 3d77c87e 2004-03-15 devnull #endif
1619 3d77c87e 2004-03-15 devnull
1620 c1e6f642 2005-07-13 devnull /* vtblockdirty(b); */
1621 3d77c87e 2004-03-15 devnull vtblockput(b);
1622 3d77c87e 2004-03-15 devnull return bo;
1623 7763a61a 2003-11-23 devnull Err:
1624 3d77c87e 2004-03-15 devnull vtblockput(b);
1625 7763a61a 2003-11-23 devnull return NilBlock;
1626 7763a61a 2003-11-23 devnull }
1627 7763a61a 2003-11-23 devnull
1628 3d77c87e 2004-03-15 devnull static int
1629 3d77c87e 2004-03-15 devnull chksource(VacFile *f)
1630 3d77c87e 2004-03-15 devnull {
1631 3d77c87e 2004-03-15 devnull if(f->partial)
1632 3d77c87e 2004-03-15 devnull return 0;
1633 3d77c87e 2004-03-15 devnull
1634 3d77c87e 2004-03-15 devnull if(f->source == nil || (f->dir.mode & ModeDir) && f->msource == nil){
1635 3d77c87e 2004-03-15 devnull werrstr(ERemoved);
1636 3d77c87e 2004-03-15 devnull return -1;
1637 3d77c87e 2004-03-15 devnull }
1638 3d77c87e 2004-03-15 devnull return 0;
1639 3d77c87e 2004-03-15 devnull }
1640 3d77c87e 2004-03-15 devnull
1641 3d77c87e 2004-03-15 devnull static int
1642 3d77c87e 2004-03-15 devnull filerlock(VacFile *f)
1643 3d77c87e 2004-03-15 devnull {
1644 cbeb0b26 2006-04-01 devnull /* assert(!canwlock(&f->fs->elk)); */
1645 3d77c87e 2004-03-15 devnull rlock(&f->lk);
1646 3d77c87e 2004-03-15 devnull if(chksource(f) < 0){
1647 3d77c87e 2004-03-15 devnull runlock(&f->lk);
1648 3d77c87e 2004-03-15 devnull return -1;
1649 3d77c87e 2004-03-15 devnull }
1650 3d77c87e 2004-03-15 devnull return 0;
1651 3d77c87e 2004-03-15 devnull }
1652 3d77c87e 2004-03-15 devnull
1653 3d77c87e 2004-03-15 devnull static void
1654 3d77c87e 2004-03-15 devnull filerunlock(VacFile *f)
1655 3d77c87e 2004-03-15 devnull {
1656 3d77c87e 2004-03-15 devnull runlock(&f->lk);
1657 3d77c87e 2004-03-15 devnull }
1658 3d77c87e 2004-03-15 devnull
1659 3d77c87e 2004-03-15 devnull static int
1660 3d77c87e 2004-03-15 devnull filelock(VacFile *f)
1661 3d77c87e 2004-03-15 devnull {
1662 cbeb0b26 2006-04-01 devnull /* assert(!canwlock(&f->fs->elk)); */
1663 3d77c87e 2004-03-15 devnull wlock(&f->lk);
1664 3d77c87e 2004-03-15 devnull if(chksource(f) < 0){
1665 3d77c87e 2004-03-15 devnull wunlock(&f->lk);
1666 3d77c87e 2004-03-15 devnull return -1;
1667 3d77c87e 2004-03-15 devnull }
1668 3d77c87e 2004-03-15 devnull return 0;
1669 3d77c87e 2004-03-15 devnull }
1670 3d77c87e 2004-03-15 devnull
1671 3d77c87e 2004-03-15 devnull static void
1672 3d77c87e 2004-03-15 devnull fileunlock(VacFile *f)
1673 3d77c87e 2004-03-15 devnull {
1674 3d77c87e 2004-03-15 devnull wunlock(&f->lk);
1675 3d77c87e 2004-03-15 devnull }
1676 3d77c87e 2004-03-15 devnull
1677 3d77c87e 2004-03-15 devnull /*
1678 3d77c87e 2004-03-15 devnull * f->source and f->msource must NOT be locked.
1679 3d77c87e 2004-03-15 devnull * fileMetaFlush locks the fileMeta and then the source (in fileMetaFlush2).
1680 3d77c87e 2004-03-15 devnull * We have to respect that ordering.
1681 3d77c87e 2004-03-15 devnull */
1682 3d77c87e 2004-03-15 devnull static void
1683 3d77c87e 2004-03-15 devnull filemetalock(VacFile *f)
1684 3d77c87e 2004-03-15 devnull {
1685 3d77c87e 2004-03-15 devnull assert(f->up != nil);
1686 cbeb0b26 2006-04-01 devnull /* assert(!canwlock(&f->fs->elk)); */
1687 3d77c87e 2004-03-15 devnull wlock(&f->up->lk);
1688 3d77c87e 2004-03-15 devnull }
1689 3d77c87e 2004-03-15 devnull
1690 3d77c87e 2004-03-15 devnull static void
1691 3d77c87e 2004-03-15 devnull filemetaunlock(VacFile *f)
1692 3d77c87e 2004-03-15 devnull {
1693 3d77c87e 2004-03-15 devnull wunlock(&f->up->lk);
1694 3d77c87e 2004-03-15 devnull }
1695 3d77c87e 2004-03-15 devnull
1696 3d77c87e 2004-03-15 devnull /*
1697 3d77c87e 2004-03-15 devnull * f->source and f->msource must NOT be locked.
1698 3d77c87e 2004-03-15 devnull * see filemetalock.
1699 3d77c87e 2004-03-15 devnull */
1700 3d77c87e 2004-03-15 devnull static void
1701 3d77c87e 2004-03-15 devnull fileraccess(VacFile* f)
1702 3d77c87e 2004-03-15 devnull {
1703 3d77c87e 2004-03-15 devnull if(f->mode == VtOREAD)
1704 3d77c87e 2004-03-15 devnull return;
1705 3d77c87e 2004-03-15 devnull
1706 3d77c87e 2004-03-15 devnull filemetalock(f);
1707 3d77c87e 2004-03-15 devnull f->dir.atime = time(0L);
1708 3d77c87e 2004-03-15 devnull f->dirty = 1;
1709 3d77c87e 2004-03-15 devnull filemetaunlock(f);
1710 3d77c87e 2004-03-15 devnull }
1711 3d77c87e 2004-03-15 devnull
1712 3d77c87e 2004-03-15 devnull /*
1713 3d77c87e 2004-03-15 devnull * f->source and f->msource must NOT be locked.
1714 3d77c87e 2004-03-15 devnull * see filemetalock.
1715 3d77c87e 2004-03-15 devnull */
1716 3d77c87e 2004-03-15 devnull static void
1717 3d77c87e 2004-03-15 devnull filewaccess(VacFile* f, char *mid)
1718 3d77c87e 2004-03-15 devnull {
1719 3d77c87e 2004-03-15 devnull if(f->mode == VtOREAD)
1720 3d77c87e 2004-03-15 devnull return;
1721 3d77c87e 2004-03-15 devnull
1722 3d77c87e 2004-03-15 devnull filemetalock(f);
1723 3d77c87e 2004-03-15 devnull f->dir.atime = f->dir.mtime = time(0L);
1724 3d77c87e 2004-03-15 devnull if(strcmp(f->dir.mid, mid) != 0){
1725 3d77c87e 2004-03-15 devnull vtfree(f->dir.mid);
1726 3d77c87e 2004-03-15 devnull f->dir.mid = vtstrdup(mid);
1727 3d77c87e 2004-03-15 devnull }
1728 3d77c87e 2004-03-15 devnull f->dir.mcount++;
1729 3d77c87e 2004-03-15 devnull f->dirty = 1;
1730 3d77c87e 2004-03-15 devnull filemetaunlock(f);
1731 3d77c87e 2004-03-15 devnull
1732 3d77c87e 2004-03-15 devnull /*RSC: let's try this */
1733 3d77c87e 2004-03-15 devnull /*presotto - lets not
1734 3d77c87e 2004-03-15 devnull if(f->up)
1735 3d77c87e 2004-03-15 devnull filewaccess(f->up, mid);
1736 3d77c87e 2004-03-15 devnull */
1737 3d77c87e 2004-03-15 devnull }
1738 3d77c87e 2004-03-15 devnull
1739 3d77c87e 2004-03-15 devnull #if 0
1740 3d77c87e 2004-03-15 devnull static void
1741 3d77c87e 2004-03-15 devnull markCopied(Block *b)
1742 3d77c87e 2004-03-15 devnull {
1743 3d77c87e 2004-03-15 devnull VtBlock *lb;
1744 3d77c87e 2004-03-15 devnull Label l;
1745 3d77c87e 2004-03-15 devnull
1746 3d77c87e 2004-03-15 devnull if(globalToLocal(b->score) == NilBlock)
1747 3d77c87e 2004-03-15 devnull return;
1748 3d77c87e 2004-03-15 devnull
1749 3d77c87e 2004-03-15 devnull if(!(b->l.state & BsCopied)){
1750 3d77c87e 2004-03-15 devnull /*
1751 3d77c87e 2004-03-15 devnull * We need to record that there are now pointers in
1752 3d77c87e 2004-03-15 devnull * b that are not unique to b. We do this by marking
1753 3d77c87e 2004-03-15 devnull * b as copied. Since we don't return the label block,
1754 3d77c87e 2004-03-15 devnull * the caller can't get the dependencies right. So we have
1755 3d77c87e 2004-03-15 devnull * to flush the block ourselves. This is a rare occurrence.
1756 3d77c87e 2004-03-15 devnull */
1757 3d77c87e 2004-03-15 devnull l = b->l;
1758 3d77c87e 2004-03-15 devnull l.state |= BsCopied;
1759 3d77c87e 2004-03-15 devnull lb = _blockSetLabel(b, &l);
1760 3d77c87e 2004-03-15 devnull WriteAgain:
1761 3d77c87e 2004-03-15 devnull while(!blockWrite(lb)){
1762 3d77c87e 2004-03-15 devnull fprint(2, "getEntry: could not write label block\n");
1763 3d77c87e 2004-03-15 devnull sleep(10*1000);
1764 3d77c87e 2004-03-15 devnull }
1765 3d77c87e 2004-03-15 devnull while(lb->iostate != BioClean && lb->iostate != BioDirty){
1766 3d77c87e 2004-03-15 devnull assert(lb->iostate == BioWriting);
1767 3d77c87e 2004-03-15 devnull vtSleep(lb->ioready);
1768 3d77c87e 2004-03-15 devnull }
1769 3d77c87e 2004-03-15 devnull if(lb->iostate == BioDirty)
1770 3d77c87e 2004-03-15 devnull goto WriteAgain;
1771 3d77c87e 2004-03-15 devnull vtblockput(lb);
1772 3d77c87e 2004-03-15 devnull }
1773 3d77c87e 2004-03-15 devnull }
1774 3d77c87e 2004-03-15 devnull
1775 3d77c87e 2004-03-15 devnull static int
1776 3d77c87e 2004-03-15 devnull getEntry(VtFile *r, Entry *e, int mark)
1777 3d77c87e 2004-03-15 devnull {
1778 3d77c87e 2004-03-15 devnull Block *b;
1779 3d77c87e 2004-03-15 devnull
1780 3d77c87e 2004-03-15 devnull if(r == nil){
1781 3d77c87e 2004-03-15 devnull memset(&e, 0, sizeof e);
1782 3d77c87e 2004-03-15 devnull return 1;
1783 3d77c87e 2004-03-15 devnull }
1784 3d77c87e 2004-03-15 devnull
1785 3d77c87e 2004-03-15 devnull b = cacheGlobal(r->fs->cache, r->score, BtDir, r->tag, VtOREAD);
1786 3d77c87e 2004-03-15 devnull if(b == nil)
1787 3d77c87e 2004-03-15 devnull return 0;
1788 3d77c87e 2004-03-15 devnull if(!entryUnpack(e, b->data, r->offset % r->epb)){
1789 3d77c87e 2004-03-15 devnull vtblockput(b);
1790 3d77c87e 2004-03-15 devnull return 0;
1791 3d77c87e 2004-03-15 devnull }
1792 3d77c87e 2004-03-15 devnull
1793 3d77c87e 2004-03-15 devnull if(mark)
1794 3d77c87e 2004-03-15 devnull markCopied(b);
1795 3d77c87e 2004-03-15 devnull vtblockput(b);
1796 3d77c87e 2004-03-15 devnull return 1;
1797 3d77c87e 2004-03-15 devnull }
1798 3d77c87e 2004-03-15 devnull
1799 3d77c87e 2004-03-15 devnull static int
1800 3d77c87e 2004-03-15 devnull setEntry(Source *r, Entry *e)
1801 3d77c87e 2004-03-15 devnull {
1802 3d77c87e 2004-03-15 devnull Block *b;
1803 3d77c87e 2004-03-15 devnull Entry oe;
1804 3d77c87e 2004-03-15 devnull
1805 3d77c87e 2004-03-15 devnull b = cacheGlobal(r->fs->cache, r->score, BtDir, r->tag, VtORDWR);
1806 3d77c87e 2004-03-15 devnull if(0) fprint(2, "setEntry: b %#ux %d score=%V\n", b->addr, r->offset % r->epb, e->score);
1807 3d77c87e 2004-03-15 devnull if(b == nil)
1808 3d77c87e 2004-03-15 devnull return 0;
1809 3d77c87e 2004-03-15 devnull if(!entryUnpack(&oe, b->data, r->offset % r->epb)){
1810 3d77c87e 2004-03-15 devnull vtblockput(b);
1811 3d77c87e 2004-03-15 devnull return 0;
1812 3d77c87e 2004-03-15 devnull }
1813 3d77c87e 2004-03-15 devnull e->gen = oe.gen;
1814 3d77c87e 2004-03-15 devnull entryPack(e, b->data, r->offset % r->epb);
1815 3d77c87e 2004-03-15 devnull
1816 3d77c87e 2004-03-15 devnull /* BUG b should depend on the entry pointer */
1817 3d77c87e 2004-03-15 devnull
1818 3d77c87e 2004-03-15 devnull markCopied(b);
1819 c1e6f642 2005-07-13 devnull /* vtblockdirty(b); */
1820 3d77c87e 2004-03-15 devnull vtblockput(b);
1821 3d77c87e 2004-03-15 devnull return 1;
1822 3d77c87e 2004-03-15 devnull }
1823 3d77c87e 2004-03-15 devnull
1824 3d77c87e 2004-03-15 devnull /* assumes hold elk */
1825 3d77c87e 2004-03-15 devnull int
1826 3d77c87e 2004-03-15 devnull fileSnapshot(VacFile *dst, VacFile *src, u32int epoch, int doarchive)
1827 3d77c87e 2004-03-15 devnull {
1828 3d77c87e 2004-03-15 devnull Entry e, ee;
1829 3d77c87e 2004-03-15 devnull
1830 3d77c87e 2004-03-15 devnull /* add link to snapshot */
1831 3d77c87e 2004-03-15 devnull if(!getEntry(src->source, &e, 1) || !getEntry(src->msource, &ee, 1))
1832 3d77c87e 2004-03-15 devnull return 0;
1833 3d77c87e 2004-03-15 devnull
1834 3d77c87e 2004-03-15 devnull e.snap = epoch;
1835 3d77c87e 2004-03-15 devnull e.archive = doarchive;
1836 3d77c87e 2004-03-15 devnull ee.snap = epoch;
1837 3d77c87e 2004-03-15 devnull ee.archive = doarchive;
1838 3d77c87e 2004-03-15 devnull
1839 3d77c87e 2004-03-15 devnull if(!setEntry(dst->source, &e) || !setEntry(dst->msource, &ee))
1840 3d77c87e 2004-03-15 devnull return 0;
1841 3d77c87e 2004-03-15 devnull return 1;
1842 3d77c87e 2004-03-15 devnull }
1843 3d77c87e 2004-03-15 devnull
1844 3d77c87e 2004-03-15 devnull int
1845 3d77c87e 2004-03-15 devnull fileGetSources(VacFile *f, Entry *e, Entry *ee, int mark)
1846 3d77c87e 2004-03-15 devnull {
1847 3d77c87e 2004-03-15 devnull if(!getEntry(f->source, e, mark)
1848 3d77c87e 2004-03-15 devnull || !getEntry(f->msource, ee, mark))
1849 3d77c87e 2004-03-15 devnull return 0;
1850 3d77c87e 2004-03-15 devnull return 1;
1851 3d77c87e 2004-03-15 devnull }
1852 3d77c87e 2004-03-15 devnull
1853 3d77c87e 2004-03-15 devnull int
1854 3d77c87e 2004-03-15 devnull fileWalkSources(VacFile *f)
1855 3d77c87e 2004-03-15 devnull {
1856 3d77c87e 2004-03-15 devnull if(f->mode == VtOREAD)
1857 3d77c87e 2004-03-15 devnull return 1;
1858 3d77c87e 2004-03-15 devnull if(!sourceLock2(f->source, f->msource, VtORDWR))
1859 3d77c87e 2004-03-15 devnull return 0;
1860 3d77c87e 2004-03-15 devnull vtfileunlock(f->source);
1861 3d77c87e 2004-03-15 devnull vtfileunlock(f->msource);
1862 3d77c87e 2004-03-15 devnull return 1;
1863 3d77c87e 2004-03-15 devnull }
1864 3d77c87e 2004-03-15 devnull
1865 3d77c87e 2004-03-15 devnull #endif