Blame


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