Blame


1 6f4d00ee 2013-09-23 0intro #include "stdinc.h"
2 6f4d00ee 2013-09-23 0intro #include <bio.h>
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 "9.h"
6 6f4d00ee 2013-09-23 0intro
7 6f4d00ee 2013-09-23 0intro struct Fsys {
8 4b576658 2013-09-23 0intro QLock lock;
9 6f4d00ee 2013-09-23 0intro
10 6f4d00ee 2013-09-23 0intro char* name; /* copy here & Fs to ease error reporting */
11 6f4d00ee 2013-09-23 0intro char* dev;
12 6f4d00ee 2013-09-23 0intro char* venti;
13 6f4d00ee 2013-09-23 0intro
14 6f4d00ee 2013-09-23 0intro Fs* fs;
15 4b576658 2013-09-23 0intro VtConn* session;
16 6f4d00ee 2013-09-23 0intro int ref;
17 6f4d00ee 2013-09-23 0intro
18 6f4d00ee 2013-09-23 0intro int noauth;
19 6f4d00ee 2013-09-23 0intro int noperm;
20 6f4d00ee 2013-09-23 0intro int wstatallow;
21 6f4d00ee 2013-09-23 0intro
22 6f4d00ee 2013-09-23 0intro Fsys* next;
23 6f4d00ee 2013-09-23 0intro };
24 6f4d00ee 2013-09-23 0intro
25 6f4d00ee 2013-09-23 0intro int mempcnt; /* from fossil.c */
26 6f4d00ee 2013-09-23 0intro
27 6f4d00ee 2013-09-23 0intro int fsGetBlockSize(Fs *fs);
28 6f4d00ee 2013-09-23 0intro
29 6f4d00ee 2013-09-23 0intro static struct {
30 4b576658 2013-09-23 0intro RWLock lock;
31 6f4d00ee 2013-09-23 0intro Fsys* head;
32 6f4d00ee 2013-09-23 0intro Fsys* tail;
33 6f4d00ee 2013-09-23 0intro
34 6f4d00ee 2013-09-23 0intro char* curfsys;
35 6f4d00ee 2013-09-23 0intro } sbox;
36 6f4d00ee 2013-09-23 0intro
37 6f4d00ee 2013-09-23 0intro static char *_argv0;
38 6f4d00ee 2013-09-23 0intro #define argv0 _argv0
39 6f4d00ee 2013-09-23 0intro
40 6f4d00ee 2013-09-23 0intro static char FsysAll[] = "all";
41 6f4d00ee 2013-09-23 0intro
42 6f4d00ee 2013-09-23 0intro static char EFsysBusy[] = "fsys: '%s' busy";
43 6f4d00ee 2013-09-23 0intro static char EFsysExists[] = "fsys: '%s' already exists";
44 6f4d00ee 2013-09-23 0intro static char EFsysNoCurrent[] = "fsys: no current fsys";
45 6f4d00ee 2013-09-23 0intro static char EFsysNotFound[] = "fsys: '%s' not found";
46 6f4d00ee 2013-09-23 0intro static char EFsysNotOpen[] = "fsys: '%s' not open";
47 6f4d00ee 2013-09-23 0intro
48 6f4d00ee 2013-09-23 0intro static char *
49 6f4d00ee 2013-09-23 0intro ventihost(char *host)
50 6f4d00ee 2013-09-23 0intro {
51 6f4d00ee 2013-09-23 0intro if(host != nil)
52 4b576658 2013-09-23 0intro return vtstrdup(host);
53 6f4d00ee 2013-09-23 0intro host = getenv("venti");
54 6f4d00ee 2013-09-23 0intro if(host == nil)
55 4b576658 2013-09-23 0intro host = vtstrdup("$venti");
56 6f4d00ee 2013-09-23 0intro return host;
57 6f4d00ee 2013-09-23 0intro }
58 6f4d00ee 2013-09-23 0intro
59 6f4d00ee 2013-09-23 0intro static void
60 6f4d00ee 2013-09-23 0intro prventihost(char *host)
61 6f4d00ee 2013-09-23 0intro {
62 6f4d00ee 2013-09-23 0intro char *vh;
63 6f4d00ee 2013-09-23 0intro
64 6f4d00ee 2013-09-23 0intro vh = ventihost(host);
65 6f4d00ee 2013-09-23 0intro fprint(2, "%s: dialing venti at %s\n",
66 6f4d00ee 2013-09-23 0intro argv0, netmkaddr(vh, 0, "venti"));
67 6f4d00ee 2013-09-23 0intro free(vh);
68 6f4d00ee 2013-09-23 0intro }
69 6f4d00ee 2013-09-23 0intro
70 4b576658 2013-09-23 0intro static VtConn *
71 4b576658 2013-09-23 0intro myDial(char *host)
72 6f4d00ee 2013-09-23 0intro {
73 6f4d00ee 2013-09-23 0intro prventihost(host);
74 4b576658 2013-09-23 0intro return vtdial(host);
75 6f4d00ee 2013-09-23 0intro }
76 6f4d00ee 2013-09-23 0intro
77 6f4d00ee 2013-09-23 0intro static int
78 4b576658 2013-09-23 0intro myRedial(VtConn *z, char *host)
79 6f4d00ee 2013-09-23 0intro {
80 6f4d00ee 2013-09-23 0intro prventihost(host);
81 4b576658 2013-09-23 0intro return vtredial(z, host);
82 6f4d00ee 2013-09-23 0intro }
83 6f4d00ee 2013-09-23 0intro
84 6f4d00ee 2013-09-23 0intro static Fsys*
85 6f4d00ee 2013-09-23 0intro _fsysGet(char* name)
86 6f4d00ee 2013-09-23 0intro {
87 6f4d00ee 2013-09-23 0intro Fsys *fsys;
88 6f4d00ee 2013-09-23 0intro
89 6f4d00ee 2013-09-23 0intro if(name == nil || name[0] == '\0')
90 6f4d00ee 2013-09-23 0intro name = "main";
91 6f4d00ee 2013-09-23 0intro
92 4b576658 2013-09-23 0intro rlock(&sbox.lock);
93 6f4d00ee 2013-09-23 0intro for(fsys = sbox.head; fsys != nil; fsys = fsys->next){
94 6f4d00ee 2013-09-23 0intro if(strcmp(name, fsys->name) == 0){
95 6f4d00ee 2013-09-23 0intro fsys->ref++;
96 6f4d00ee 2013-09-23 0intro break;
97 6f4d00ee 2013-09-23 0intro }
98 6f4d00ee 2013-09-23 0intro }
99 4b576658 2013-09-23 0intro runlock(&sbox.lock);
100 6f4d00ee 2013-09-23 0intro if(fsys == nil)
101 4b576658 2013-09-23 0intro werrstr(EFsysNotFound, name);
102 6f4d00ee 2013-09-23 0intro return fsys;
103 6f4d00ee 2013-09-23 0intro }
104 6f4d00ee 2013-09-23 0intro
105 6f4d00ee 2013-09-23 0intro static int
106 6f4d00ee 2013-09-23 0intro cmdPrintConfig(int argc, char* argv[])
107 6f4d00ee 2013-09-23 0intro {
108 6f4d00ee 2013-09-23 0intro Fsys *fsys;
109 6f4d00ee 2013-09-23 0intro char *usage = "usage: printconfig";
110 6f4d00ee 2013-09-23 0intro
111 6f4d00ee 2013-09-23 0intro ARGBEGIN{
112 6f4d00ee 2013-09-23 0intro default:
113 6f4d00ee 2013-09-23 0intro return cliError(usage);
114 6f4d00ee 2013-09-23 0intro }ARGEND
115 6f4d00ee 2013-09-23 0intro
116 6f4d00ee 2013-09-23 0intro if(argc)
117 6f4d00ee 2013-09-23 0intro return cliError(usage);
118 6f4d00ee 2013-09-23 0intro
119 4b576658 2013-09-23 0intro rlock(&sbox.lock);
120 6f4d00ee 2013-09-23 0intro for(fsys = sbox.head; fsys != nil; fsys = fsys->next){
121 6f4d00ee 2013-09-23 0intro consPrint("\tfsys %s config %s\n", fsys->name, fsys->dev);
122 6f4d00ee 2013-09-23 0intro if(fsys->venti && fsys->venti[0])
123 6f4d00ee 2013-09-23 0intro consPrint("\tfsys %s venti %q\n", fsys->name,
124 6f4d00ee 2013-09-23 0intro fsys->venti);
125 6f4d00ee 2013-09-23 0intro }
126 4b576658 2013-09-23 0intro runlock(&sbox.lock);
127 6f4d00ee 2013-09-23 0intro return 1;
128 6f4d00ee 2013-09-23 0intro }
129 6f4d00ee 2013-09-23 0intro
130 6f4d00ee 2013-09-23 0intro Fsys*
131 6f4d00ee 2013-09-23 0intro fsysGet(char* name)
132 6f4d00ee 2013-09-23 0intro {
133 6f4d00ee 2013-09-23 0intro Fsys *fsys;
134 6f4d00ee 2013-09-23 0intro
135 6f4d00ee 2013-09-23 0intro if((fsys = _fsysGet(name)) == nil)
136 6f4d00ee 2013-09-23 0intro return nil;
137 6f4d00ee 2013-09-23 0intro
138 4b576658 2013-09-23 0intro qlock(&fsys->lock);
139 6f4d00ee 2013-09-23 0intro if(fsys->fs == nil){
140 4b576658 2013-09-23 0intro werrstr(EFsysNotOpen, fsys->name);
141 4b576658 2013-09-23 0intro qunlock(&fsys->lock);
142 6f4d00ee 2013-09-23 0intro fsysPut(fsys);
143 6f4d00ee 2013-09-23 0intro return nil;
144 6f4d00ee 2013-09-23 0intro }
145 4b576658 2013-09-23 0intro qunlock(&fsys->lock);
146 6f4d00ee 2013-09-23 0intro
147 6f4d00ee 2013-09-23 0intro return fsys;
148 6f4d00ee 2013-09-23 0intro }
149 6f4d00ee 2013-09-23 0intro
150 6f4d00ee 2013-09-23 0intro char*
151 6f4d00ee 2013-09-23 0intro fsysGetName(Fsys* fsys)
152 6f4d00ee 2013-09-23 0intro {
153 6f4d00ee 2013-09-23 0intro return fsys->name;
154 6f4d00ee 2013-09-23 0intro }
155 6f4d00ee 2013-09-23 0intro
156 6f4d00ee 2013-09-23 0intro Fsys*
157 6f4d00ee 2013-09-23 0intro fsysIncRef(Fsys* fsys)
158 6f4d00ee 2013-09-23 0intro {
159 4b576658 2013-09-23 0intro wlock(&sbox.lock);
160 6f4d00ee 2013-09-23 0intro fsys->ref++;
161 4b576658 2013-09-23 0intro wunlock(&sbox.lock);
162 6f4d00ee 2013-09-23 0intro
163 6f4d00ee 2013-09-23 0intro return fsys;
164 6f4d00ee 2013-09-23 0intro }
165 6f4d00ee 2013-09-23 0intro
166 6f4d00ee 2013-09-23 0intro void
167 6f4d00ee 2013-09-23 0intro fsysPut(Fsys* fsys)
168 6f4d00ee 2013-09-23 0intro {
169 4b576658 2013-09-23 0intro wlock(&sbox.lock);
170 6f4d00ee 2013-09-23 0intro assert(fsys->ref > 0);
171 6f4d00ee 2013-09-23 0intro fsys->ref--;
172 4b576658 2013-09-23 0intro wunlock(&sbox.lock);
173 6f4d00ee 2013-09-23 0intro }
174 6f4d00ee 2013-09-23 0intro
175 6f4d00ee 2013-09-23 0intro Fs*
176 6f4d00ee 2013-09-23 0intro fsysGetFs(Fsys* fsys)
177 6f4d00ee 2013-09-23 0intro {
178 6f4d00ee 2013-09-23 0intro assert(fsys != nil && fsys->fs != nil);
179 6f4d00ee 2013-09-23 0intro
180 6f4d00ee 2013-09-23 0intro return fsys->fs;
181 6f4d00ee 2013-09-23 0intro }
182 6f4d00ee 2013-09-23 0intro
183 6f4d00ee 2013-09-23 0intro void
184 6f4d00ee 2013-09-23 0intro fsysFsRlock(Fsys* fsys)
185 6f4d00ee 2013-09-23 0intro {
186 4b576658 2013-09-23 0intro rlock(&fsys->fs->elk);
187 6f4d00ee 2013-09-23 0intro }
188 6f4d00ee 2013-09-23 0intro
189 6f4d00ee 2013-09-23 0intro void
190 6f4d00ee 2013-09-23 0intro fsysFsRUnlock(Fsys* fsys)
191 6f4d00ee 2013-09-23 0intro {
192 4b576658 2013-09-23 0intro runlock(&fsys->fs->elk);
193 6f4d00ee 2013-09-23 0intro }
194 6f4d00ee 2013-09-23 0intro
195 6f4d00ee 2013-09-23 0intro int
196 6f4d00ee 2013-09-23 0intro fsysNoAuthCheck(Fsys* fsys)
197 6f4d00ee 2013-09-23 0intro {
198 6f4d00ee 2013-09-23 0intro return fsys->noauth;
199 6f4d00ee 2013-09-23 0intro }
200 6f4d00ee 2013-09-23 0intro
201 6f4d00ee 2013-09-23 0intro int
202 6f4d00ee 2013-09-23 0intro fsysNoPermCheck(Fsys* fsys)
203 6f4d00ee 2013-09-23 0intro {
204 6f4d00ee 2013-09-23 0intro return fsys->noperm;
205 6f4d00ee 2013-09-23 0intro }
206 6f4d00ee 2013-09-23 0intro
207 6f4d00ee 2013-09-23 0intro int
208 6f4d00ee 2013-09-23 0intro fsysWstatAllow(Fsys* fsys)
209 6f4d00ee 2013-09-23 0intro {
210 6f4d00ee 2013-09-23 0intro return fsys->wstatallow;
211 6f4d00ee 2013-09-23 0intro }
212 6f4d00ee 2013-09-23 0intro
213 6f4d00ee 2013-09-23 0intro static char modechars[] = "YUGalLdHSATs";
214 6f4d00ee 2013-09-23 0intro static ulong modebits[] = {
215 6f4d00ee 2013-09-23 0intro ModeSticky,
216 6f4d00ee 2013-09-23 0intro ModeSetUid,
217 6f4d00ee 2013-09-23 0intro ModeSetGid,
218 6f4d00ee 2013-09-23 0intro ModeAppend,
219 6f4d00ee 2013-09-23 0intro ModeExclusive,
220 6f4d00ee 2013-09-23 0intro ModeLink,
221 6f4d00ee 2013-09-23 0intro ModeDir,
222 6f4d00ee 2013-09-23 0intro ModeHidden,
223 6f4d00ee 2013-09-23 0intro ModeSystem,
224 6f4d00ee 2013-09-23 0intro ModeArchive,
225 6f4d00ee 2013-09-23 0intro ModeTemporary,
226 6f4d00ee 2013-09-23 0intro ModeSnapshot,
227 6f4d00ee 2013-09-23 0intro 0
228 6f4d00ee 2013-09-23 0intro };
229 6f4d00ee 2013-09-23 0intro
230 6f4d00ee 2013-09-23 0intro char*
231 6f4d00ee 2013-09-23 0intro fsysModeString(ulong mode, char *buf)
232 6f4d00ee 2013-09-23 0intro {
233 6f4d00ee 2013-09-23 0intro int i;
234 6f4d00ee 2013-09-23 0intro char *p;
235 6f4d00ee 2013-09-23 0intro
236 6f4d00ee 2013-09-23 0intro p = buf;
237 6f4d00ee 2013-09-23 0intro for(i=0; modebits[i]; i++)
238 6f4d00ee 2013-09-23 0intro if(mode & modebits[i])
239 6f4d00ee 2013-09-23 0intro *p++ = modechars[i];
240 6f4d00ee 2013-09-23 0intro sprint(p, "%luo", mode&0777);
241 6f4d00ee 2013-09-23 0intro return buf;
242 6f4d00ee 2013-09-23 0intro }
243 6f4d00ee 2013-09-23 0intro
244 6f4d00ee 2013-09-23 0intro int
245 6f4d00ee 2013-09-23 0intro fsysParseMode(char* s, ulong* mode)
246 6f4d00ee 2013-09-23 0intro {
247 6f4d00ee 2013-09-23 0intro ulong x, y;
248 6f4d00ee 2013-09-23 0intro char *p;
249 6f4d00ee 2013-09-23 0intro
250 6f4d00ee 2013-09-23 0intro x = 0;
251 6f4d00ee 2013-09-23 0intro for(; *s < '0' || *s > '9'; s++){
252 6f4d00ee 2013-09-23 0intro if(*s == 0)
253 6f4d00ee 2013-09-23 0intro return 0;
254 6f4d00ee 2013-09-23 0intro p = strchr(modechars, *s);
255 6f4d00ee 2013-09-23 0intro if(p == nil)
256 6f4d00ee 2013-09-23 0intro return 0;
257 6f4d00ee 2013-09-23 0intro x |= modebits[p-modechars];
258 6f4d00ee 2013-09-23 0intro }
259 6f4d00ee 2013-09-23 0intro y = strtoul(s, &p, 8);
260 6f4d00ee 2013-09-23 0intro if(*p != '\0' || y > 0777)
261 6f4d00ee 2013-09-23 0intro return 0;
262 6f4d00ee 2013-09-23 0intro *mode = x|y;
263 6f4d00ee 2013-09-23 0intro return 1;
264 6f4d00ee 2013-09-23 0intro }
265 6f4d00ee 2013-09-23 0intro
266 6f4d00ee 2013-09-23 0intro File*
267 6f4d00ee 2013-09-23 0intro fsysGetRoot(Fsys* fsys, char* name)
268 6f4d00ee 2013-09-23 0intro {
269 6f4d00ee 2013-09-23 0intro File *root, *sub;
270 6f4d00ee 2013-09-23 0intro
271 6f4d00ee 2013-09-23 0intro assert(fsys != nil && fsys->fs != nil);
272 6f4d00ee 2013-09-23 0intro
273 6f4d00ee 2013-09-23 0intro root = fsGetRoot(fsys->fs);
274 6f4d00ee 2013-09-23 0intro if(name == nil || strcmp(name, "") == 0)
275 6f4d00ee 2013-09-23 0intro return root;
276 6f4d00ee 2013-09-23 0intro
277 6f4d00ee 2013-09-23 0intro sub = fileWalk(root, name);
278 6f4d00ee 2013-09-23 0intro fileDecRef(root);
279 6f4d00ee 2013-09-23 0intro
280 6f4d00ee 2013-09-23 0intro return sub;
281 6f4d00ee 2013-09-23 0intro }
282 6f4d00ee 2013-09-23 0intro
283 6f4d00ee 2013-09-23 0intro static Fsys*
284 6f4d00ee 2013-09-23 0intro fsysAlloc(char* name, char* dev)
285 6f4d00ee 2013-09-23 0intro {
286 6f4d00ee 2013-09-23 0intro Fsys *fsys;
287 6f4d00ee 2013-09-23 0intro
288 4b576658 2013-09-23 0intro wlock(&sbox.lock);
289 6f4d00ee 2013-09-23 0intro for(fsys = sbox.head; fsys != nil; fsys = fsys->next){
290 6f4d00ee 2013-09-23 0intro if(strcmp(fsys->name, name) != 0)
291 6f4d00ee 2013-09-23 0intro continue;
292 4b576658 2013-09-23 0intro werrstr(EFsysExists, name);
293 4b576658 2013-09-23 0intro wunlock(&sbox.lock);
294 6f4d00ee 2013-09-23 0intro return nil;
295 6f4d00ee 2013-09-23 0intro }
296 6f4d00ee 2013-09-23 0intro
297 4b576658 2013-09-23 0intro fsys = vtmallocz(sizeof(Fsys));
298 4b576658 2013-09-23 0intro fsys->name = vtstrdup(name);
299 4b576658 2013-09-23 0intro fsys->dev = vtstrdup(dev);
300 6f4d00ee 2013-09-23 0intro
301 6f4d00ee 2013-09-23 0intro fsys->ref = 1;
302 6f4d00ee 2013-09-23 0intro
303 6f4d00ee 2013-09-23 0intro if(sbox.tail != nil)
304 6f4d00ee 2013-09-23 0intro sbox.tail->next = fsys;
305 6f4d00ee 2013-09-23 0intro else
306 6f4d00ee 2013-09-23 0intro sbox.head = fsys;
307 6f4d00ee 2013-09-23 0intro sbox.tail = fsys;
308 4b576658 2013-09-23 0intro wunlock(&sbox.lock);
309 6f4d00ee 2013-09-23 0intro
310 6f4d00ee 2013-09-23 0intro return fsys;
311 6f4d00ee 2013-09-23 0intro }
312 6f4d00ee 2013-09-23 0intro
313 6f4d00ee 2013-09-23 0intro static int
314 6f4d00ee 2013-09-23 0intro fsysClose(Fsys* fsys, int argc, char* argv[])
315 6f4d00ee 2013-09-23 0intro {
316 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] close";
317 6f4d00ee 2013-09-23 0intro
318 6f4d00ee 2013-09-23 0intro ARGBEGIN{
319 6f4d00ee 2013-09-23 0intro default:
320 6f4d00ee 2013-09-23 0intro return cliError(usage);
321 6f4d00ee 2013-09-23 0intro }ARGEND
322 6f4d00ee 2013-09-23 0intro if(argc)
323 6f4d00ee 2013-09-23 0intro return cliError(usage);
324 6f4d00ee 2013-09-23 0intro
325 6f4d00ee 2013-09-23 0intro return cliError("close isn't working yet; halt %s and then kill fossil",
326 6f4d00ee 2013-09-23 0intro fsys->name);
327 6f4d00ee 2013-09-23 0intro
328 6f4d00ee 2013-09-23 0intro /*
329 6f4d00ee 2013-09-23 0intro * Oooh. This could be hard. What if fsys->ref != 1?
330 6f4d00ee 2013-09-23 0intro * Also, fsClose() either does the job or panics, can we
331 6f4d00ee 2013-09-23 0intro * gracefully detect it's still busy?
332 6f4d00ee 2013-09-23 0intro *
333 6f4d00ee 2013-09-23 0intro * More thought and care needed here.
334 6f4d00ee 2013-09-23 0intro fsClose(fsys->fs);
335 6f4d00ee 2013-09-23 0intro fsys->fs = nil;
336 4b576658 2013-09-23 0intro vtfreeconn(fsys->session);
337 6f4d00ee 2013-09-23 0intro fsys->session = nil;
338 6f4d00ee 2013-09-23 0intro
339 6f4d00ee 2013-09-23 0intro if(sbox.curfsys != nil && strcmp(fsys->name, sbox.curfsys) == 0){
340 6f4d00ee 2013-09-23 0intro sbox.curfsys = nil;
341 6f4d00ee 2013-09-23 0intro consPrompt(nil);
342 6f4d00ee 2013-09-23 0intro }
343 6f4d00ee 2013-09-23 0intro
344 6f4d00ee 2013-09-23 0intro return 1;
345 6f4d00ee 2013-09-23 0intro */
346 6f4d00ee 2013-09-23 0intro }
347 6f4d00ee 2013-09-23 0intro
348 6f4d00ee 2013-09-23 0intro static int
349 6f4d00ee 2013-09-23 0intro fsysVac(Fsys* fsys, int argc, char* argv[])
350 6f4d00ee 2013-09-23 0intro {
351 6f4d00ee 2013-09-23 0intro uchar score[VtScoreSize];
352 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] vac path";
353 6f4d00ee 2013-09-23 0intro
354 6f4d00ee 2013-09-23 0intro ARGBEGIN{
355 6f4d00ee 2013-09-23 0intro default:
356 6f4d00ee 2013-09-23 0intro return cliError(usage);
357 6f4d00ee 2013-09-23 0intro }ARGEND
358 6f4d00ee 2013-09-23 0intro if(argc != 1)
359 6f4d00ee 2013-09-23 0intro return cliError(usage);
360 6f4d00ee 2013-09-23 0intro
361 6f4d00ee 2013-09-23 0intro if(!fsVac(fsys->fs, argv[0], score))
362 6f4d00ee 2013-09-23 0intro return 0;
363 6f4d00ee 2013-09-23 0intro
364 6f4d00ee 2013-09-23 0intro consPrint("vac:%V\n", score);
365 6f4d00ee 2013-09-23 0intro return 1;
366 6f4d00ee 2013-09-23 0intro }
367 6f4d00ee 2013-09-23 0intro
368 6f4d00ee 2013-09-23 0intro static int
369 6f4d00ee 2013-09-23 0intro fsysSnap(Fsys* fsys, int argc, char* argv[])
370 6f4d00ee 2013-09-23 0intro {
371 6f4d00ee 2013-09-23 0intro int doarchive;
372 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] snap [-a] [-s /active] [-d /archive/yyyy/mmmm]";
373 6f4d00ee 2013-09-23 0intro char *src, *dst;
374 6f4d00ee 2013-09-23 0intro
375 6f4d00ee 2013-09-23 0intro src = nil;
376 6f4d00ee 2013-09-23 0intro dst = nil;
377 6f4d00ee 2013-09-23 0intro doarchive = 0;
378 6f4d00ee 2013-09-23 0intro ARGBEGIN{
379 6f4d00ee 2013-09-23 0intro default:
380 6f4d00ee 2013-09-23 0intro return cliError(usage);
381 6f4d00ee 2013-09-23 0intro case 'a':
382 6f4d00ee 2013-09-23 0intro doarchive = 1;
383 6f4d00ee 2013-09-23 0intro break;
384 6f4d00ee 2013-09-23 0intro case 'd':
385 6f4d00ee 2013-09-23 0intro if((dst = ARGF()) == nil)
386 6f4d00ee 2013-09-23 0intro return cliError(usage);
387 6f4d00ee 2013-09-23 0intro break;
388 6f4d00ee 2013-09-23 0intro case 's':
389 6f4d00ee 2013-09-23 0intro if((src = ARGF()) == nil)
390 6f4d00ee 2013-09-23 0intro return cliError(usage);
391 6f4d00ee 2013-09-23 0intro break;
392 6f4d00ee 2013-09-23 0intro }ARGEND
393 6f4d00ee 2013-09-23 0intro if(argc)
394 6f4d00ee 2013-09-23 0intro return cliError(usage);
395 6f4d00ee 2013-09-23 0intro
396 6f4d00ee 2013-09-23 0intro if(!fsSnapshot(fsys->fs, src, dst, doarchive))
397 6f4d00ee 2013-09-23 0intro return 0;
398 6f4d00ee 2013-09-23 0intro
399 6f4d00ee 2013-09-23 0intro return 1;
400 6f4d00ee 2013-09-23 0intro }
401 6f4d00ee 2013-09-23 0intro
402 6f4d00ee 2013-09-23 0intro static int
403 6f4d00ee 2013-09-23 0intro fsysSnapClean(Fsys *fsys, int argc, char* argv[])
404 6f4d00ee 2013-09-23 0intro {
405 6f4d00ee 2013-09-23 0intro u32int arch, snap, life;
406 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] snapclean [maxminutes]\n";
407 6f4d00ee 2013-09-23 0intro
408 6f4d00ee 2013-09-23 0intro ARGBEGIN{
409 6f4d00ee 2013-09-23 0intro default:
410 6f4d00ee 2013-09-23 0intro return cliError(usage);
411 6f4d00ee 2013-09-23 0intro }ARGEND
412 6f4d00ee 2013-09-23 0intro
413 6f4d00ee 2013-09-23 0intro if(argc > 1)
414 6f4d00ee 2013-09-23 0intro return cliError(usage);
415 6f4d00ee 2013-09-23 0intro if(argc == 1)
416 6f4d00ee 2013-09-23 0intro life = atoi(argv[0]);
417 6f4d00ee 2013-09-23 0intro else
418 6f4d00ee 2013-09-23 0intro snapGetTimes(fsys->fs->snap, &arch, &snap, &life);
419 6f4d00ee 2013-09-23 0intro
420 6f4d00ee 2013-09-23 0intro fsSnapshotCleanup(fsys->fs, life);
421 6f4d00ee 2013-09-23 0intro return 1;
422 6f4d00ee 2013-09-23 0intro }
423 6f4d00ee 2013-09-23 0intro
424 6f4d00ee 2013-09-23 0intro static int
425 6f4d00ee 2013-09-23 0intro fsysSnapTime(Fsys* fsys, int argc, char* argv[])
426 6f4d00ee 2013-09-23 0intro {
427 6f4d00ee 2013-09-23 0intro char buf[128], *x;
428 6f4d00ee 2013-09-23 0intro int hh, mm, changed;
429 6f4d00ee 2013-09-23 0intro u32int arch, snap, life;
430 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] snaptime [-a hhmm] [-s snapminutes] [-t maxminutes]";
431 6f4d00ee 2013-09-23 0intro
432 6f4d00ee 2013-09-23 0intro changed = 0;
433 6f4d00ee 2013-09-23 0intro snapGetTimes(fsys->fs->snap, &arch, &snap, &life);
434 6f4d00ee 2013-09-23 0intro ARGBEGIN{
435 6f4d00ee 2013-09-23 0intro case 'a':
436 6f4d00ee 2013-09-23 0intro changed = 1;
437 6f4d00ee 2013-09-23 0intro x = ARGF();
438 6f4d00ee 2013-09-23 0intro if(x == nil)
439 6f4d00ee 2013-09-23 0intro return cliError(usage);
440 6f4d00ee 2013-09-23 0intro if(strcmp(x, "none") == 0){
441 6f4d00ee 2013-09-23 0intro arch = ~(u32int)0;
442 6f4d00ee 2013-09-23 0intro break;
443 6f4d00ee 2013-09-23 0intro }
444 6f4d00ee 2013-09-23 0intro if(strlen(x) != 4 || strspn(x, "0123456789") != 4)
445 6f4d00ee 2013-09-23 0intro return cliError(usage);
446 6f4d00ee 2013-09-23 0intro hh = (x[0]-'0')*10 + x[1]-'0';
447 6f4d00ee 2013-09-23 0intro mm = (x[2]-'0')*10 + x[3]-'0';
448 6f4d00ee 2013-09-23 0intro if(hh >= 24 || mm >= 60)
449 6f4d00ee 2013-09-23 0intro return cliError(usage);
450 6f4d00ee 2013-09-23 0intro arch = hh*60+mm;
451 6f4d00ee 2013-09-23 0intro break;
452 6f4d00ee 2013-09-23 0intro case 's':
453 6f4d00ee 2013-09-23 0intro changed = 1;
454 6f4d00ee 2013-09-23 0intro x = ARGF();
455 6f4d00ee 2013-09-23 0intro if(x == nil)
456 6f4d00ee 2013-09-23 0intro return cliError(usage);
457 6f4d00ee 2013-09-23 0intro if(strcmp(x, "none") == 0){
458 6f4d00ee 2013-09-23 0intro snap = ~(u32int)0;
459 6f4d00ee 2013-09-23 0intro break;
460 6f4d00ee 2013-09-23 0intro }
461 6f4d00ee 2013-09-23 0intro snap = atoi(x);
462 6f4d00ee 2013-09-23 0intro break;
463 6f4d00ee 2013-09-23 0intro case 't':
464 6f4d00ee 2013-09-23 0intro changed = 1;
465 6f4d00ee 2013-09-23 0intro x = ARGF();
466 6f4d00ee 2013-09-23 0intro if(x == nil)
467 6f4d00ee 2013-09-23 0intro return cliError(usage);
468 6f4d00ee 2013-09-23 0intro if(strcmp(x, "none") == 0){
469 6f4d00ee 2013-09-23 0intro life = ~(u32int)0;
470 6f4d00ee 2013-09-23 0intro break;
471 6f4d00ee 2013-09-23 0intro }
472 6f4d00ee 2013-09-23 0intro life = atoi(x);
473 6f4d00ee 2013-09-23 0intro break;
474 6f4d00ee 2013-09-23 0intro default:
475 6f4d00ee 2013-09-23 0intro return cliError(usage);
476 6f4d00ee 2013-09-23 0intro }ARGEND
477 6f4d00ee 2013-09-23 0intro if(argc > 0)
478 6f4d00ee 2013-09-23 0intro return cliError(usage);
479 6f4d00ee 2013-09-23 0intro
480 6f4d00ee 2013-09-23 0intro if(changed){
481 6f4d00ee 2013-09-23 0intro snapSetTimes(fsys->fs->snap, arch, snap, life);
482 6f4d00ee 2013-09-23 0intro return 1;
483 6f4d00ee 2013-09-23 0intro }
484 6f4d00ee 2013-09-23 0intro snapGetTimes(fsys->fs->snap, &arch, &snap, &life);
485 6f4d00ee 2013-09-23 0intro if(arch != ~(u32int)0)
486 6f4d00ee 2013-09-23 0intro sprint(buf, "-a %02d%02d", arch/60, arch%60);
487 6f4d00ee 2013-09-23 0intro else
488 6f4d00ee 2013-09-23 0intro sprint(buf, "-a none");
489 6f4d00ee 2013-09-23 0intro if(snap != ~(u32int)0)
490 6f4d00ee 2013-09-23 0intro sprint(buf+strlen(buf), " -s %d", snap);
491 6f4d00ee 2013-09-23 0intro else
492 6f4d00ee 2013-09-23 0intro sprint(buf+strlen(buf), " -s none");
493 6f4d00ee 2013-09-23 0intro if(life != ~(u32int)0)
494 6f4d00ee 2013-09-23 0intro sprint(buf+strlen(buf), " -t %ud", life);
495 6f4d00ee 2013-09-23 0intro else
496 6f4d00ee 2013-09-23 0intro sprint(buf+strlen(buf), " -t none");
497 6f4d00ee 2013-09-23 0intro consPrint("\tsnaptime %s\n", buf);
498 6f4d00ee 2013-09-23 0intro return 1;
499 6f4d00ee 2013-09-23 0intro }
500 6f4d00ee 2013-09-23 0intro
501 6f4d00ee 2013-09-23 0intro static int
502 6f4d00ee 2013-09-23 0intro fsysSync(Fsys* fsys, int argc, char* argv[])
503 6f4d00ee 2013-09-23 0intro {
504 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] sync";
505 6f4d00ee 2013-09-23 0intro int n;
506 6f4d00ee 2013-09-23 0intro
507 6f4d00ee 2013-09-23 0intro ARGBEGIN{
508 6f4d00ee 2013-09-23 0intro default:
509 6f4d00ee 2013-09-23 0intro return cliError(usage);
510 6f4d00ee 2013-09-23 0intro }ARGEND
511 6f4d00ee 2013-09-23 0intro if(argc > 0)
512 6f4d00ee 2013-09-23 0intro return cliError(usage);
513 6f4d00ee 2013-09-23 0intro
514 6f4d00ee 2013-09-23 0intro n = cacheDirty(fsys->fs->cache);
515 6f4d00ee 2013-09-23 0intro fsSync(fsys->fs);
516 6f4d00ee 2013-09-23 0intro consPrint("\t%s sync: wrote %d blocks\n", fsys->name, n);
517 6f4d00ee 2013-09-23 0intro return 1;
518 6f4d00ee 2013-09-23 0intro }
519 6f4d00ee 2013-09-23 0intro
520 6f4d00ee 2013-09-23 0intro static int
521 6f4d00ee 2013-09-23 0intro fsysHalt(Fsys *fsys, int argc, char* argv[])
522 6f4d00ee 2013-09-23 0intro {
523 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] halt";
524 6f4d00ee 2013-09-23 0intro
525 6f4d00ee 2013-09-23 0intro ARGBEGIN{
526 6f4d00ee 2013-09-23 0intro default:
527 6f4d00ee 2013-09-23 0intro return cliError(usage);
528 6f4d00ee 2013-09-23 0intro }ARGEND
529 6f4d00ee 2013-09-23 0intro if(argc > 0)
530 6f4d00ee 2013-09-23 0intro return cliError(usage);
531 6f4d00ee 2013-09-23 0intro
532 6f4d00ee 2013-09-23 0intro fsHalt(fsys->fs);
533 6f4d00ee 2013-09-23 0intro return 1;
534 6f4d00ee 2013-09-23 0intro }
535 6f4d00ee 2013-09-23 0intro
536 6f4d00ee 2013-09-23 0intro static int
537 6f4d00ee 2013-09-23 0intro fsysUnhalt(Fsys *fsys, int argc, char* argv[])
538 6f4d00ee 2013-09-23 0intro {
539 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] unhalt";
540 6f4d00ee 2013-09-23 0intro
541 6f4d00ee 2013-09-23 0intro ARGBEGIN{
542 6f4d00ee 2013-09-23 0intro default:
543 6f4d00ee 2013-09-23 0intro return cliError(usage);
544 6f4d00ee 2013-09-23 0intro }ARGEND
545 6f4d00ee 2013-09-23 0intro if(argc > 0)
546 6f4d00ee 2013-09-23 0intro return cliError(usage);
547 6f4d00ee 2013-09-23 0intro
548 6f4d00ee 2013-09-23 0intro if(!fsys->fs->halted)
549 6f4d00ee 2013-09-23 0intro return cliError("file system %s not halted", fsys->name);
550 6f4d00ee 2013-09-23 0intro
551 6f4d00ee 2013-09-23 0intro fsUnhalt(fsys->fs);
552 6f4d00ee 2013-09-23 0intro return 1;
553 6f4d00ee 2013-09-23 0intro }
554 6f4d00ee 2013-09-23 0intro
555 6f4d00ee 2013-09-23 0intro static int
556 6f4d00ee 2013-09-23 0intro fsysRemove(Fsys* fsys, int argc, char* argv[])
557 6f4d00ee 2013-09-23 0intro {
558 6f4d00ee 2013-09-23 0intro File *file;
559 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] remove path ...";
560 6f4d00ee 2013-09-23 0intro
561 6f4d00ee 2013-09-23 0intro ARGBEGIN{
562 6f4d00ee 2013-09-23 0intro default:
563 6f4d00ee 2013-09-23 0intro return cliError(usage);
564 6f4d00ee 2013-09-23 0intro }ARGEND
565 6f4d00ee 2013-09-23 0intro if(argc == 0)
566 6f4d00ee 2013-09-23 0intro return cliError(usage);
567 6f4d00ee 2013-09-23 0intro
568 4b576658 2013-09-23 0intro rlock(&fsys->fs->elk);
569 6f4d00ee 2013-09-23 0intro while(argc > 0){
570 6f4d00ee 2013-09-23 0intro if((file = fileOpen(fsys->fs, argv[0])) == nil)
571 4b576658 2013-09-23 0intro consPrint("%s: %r\n", argv[0]);
572 6f4d00ee 2013-09-23 0intro else{
573 6f4d00ee 2013-09-23 0intro if(!fileRemove(file, uidadm))
574 4b576658 2013-09-23 0intro consPrint("%s: %r\n", argv[0]);
575 6f4d00ee 2013-09-23 0intro fileDecRef(file);
576 6f4d00ee 2013-09-23 0intro }
577 6f4d00ee 2013-09-23 0intro argc--;
578 6f4d00ee 2013-09-23 0intro argv++;
579 6f4d00ee 2013-09-23 0intro }
580 4b576658 2013-09-23 0intro runlock(&fsys->fs->elk);
581 6f4d00ee 2013-09-23 0intro
582 6f4d00ee 2013-09-23 0intro return 1;
583 6f4d00ee 2013-09-23 0intro }
584 6f4d00ee 2013-09-23 0intro
585 6f4d00ee 2013-09-23 0intro static int
586 6f4d00ee 2013-09-23 0intro fsysClri(Fsys* fsys, int argc, char* argv[])
587 6f4d00ee 2013-09-23 0intro {
588 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] clri path ...";
589 6f4d00ee 2013-09-23 0intro
590 6f4d00ee 2013-09-23 0intro ARGBEGIN{
591 6f4d00ee 2013-09-23 0intro default:
592 6f4d00ee 2013-09-23 0intro return cliError(usage);
593 6f4d00ee 2013-09-23 0intro }ARGEND
594 6f4d00ee 2013-09-23 0intro if(argc == 0)
595 6f4d00ee 2013-09-23 0intro return cliError(usage);
596 6f4d00ee 2013-09-23 0intro
597 4b576658 2013-09-23 0intro rlock(&fsys->fs->elk);
598 6f4d00ee 2013-09-23 0intro while(argc > 0){
599 6f4d00ee 2013-09-23 0intro if(!fileClriPath(fsys->fs, argv[0], uidadm))
600 4b576658 2013-09-23 0intro consPrint("clri %s: %r\n", argv[0]);
601 6f4d00ee 2013-09-23 0intro argc--;
602 6f4d00ee 2013-09-23 0intro argv++;
603 6f4d00ee 2013-09-23 0intro }
604 4b576658 2013-09-23 0intro runlock(&fsys->fs->elk);
605 6f4d00ee 2013-09-23 0intro
606 6f4d00ee 2013-09-23 0intro return 1;
607 6f4d00ee 2013-09-23 0intro }
608 6f4d00ee 2013-09-23 0intro
609 6f4d00ee 2013-09-23 0intro /*
610 6f4d00ee 2013-09-23 0intro * Inspect and edit the labels for blocks on disk.
611 6f4d00ee 2013-09-23 0intro */
612 6f4d00ee 2013-09-23 0intro static int
613 6f4d00ee 2013-09-23 0intro fsysLabel(Fsys* fsys, int argc, char* argv[])
614 6f4d00ee 2013-09-23 0intro {
615 6f4d00ee 2013-09-23 0intro Fs *fs;
616 6f4d00ee 2013-09-23 0intro Label l;
617 6f4d00ee 2013-09-23 0intro int n, r;
618 6f4d00ee 2013-09-23 0intro u32int addr;
619 6f4d00ee 2013-09-23 0intro Block *b, *bb;
620 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] label addr [type state epoch epochClose tag]";
621 6f4d00ee 2013-09-23 0intro
622 6f4d00ee 2013-09-23 0intro ARGBEGIN{
623 6f4d00ee 2013-09-23 0intro default:
624 6f4d00ee 2013-09-23 0intro return cliError(usage);
625 6f4d00ee 2013-09-23 0intro }ARGEND
626 6f4d00ee 2013-09-23 0intro if(argc != 1 && argc != 6)
627 6f4d00ee 2013-09-23 0intro return cliError(usage);
628 6f4d00ee 2013-09-23 0intro
629 6f4d00ee 2013-09-23 0intro r = 0;
630 4b576658 2013-09-23 0intro rlock(&fsys->fs->elk);
631 6f4d00ee 2013-09-23 0intro
632 6f4d00ee 2013-09-23 0intro fs = fsys->fs;
633 6f4d00ee 2013-09-23 0intro addr = strtoul(argv[0], 0, 0);
634 6f4d00ee 2013-09-23 0intro b = cacheLocal(fs->cache, PartData, addr, OReadOnly);
635 6f4d00ee 2013-09-23 0intro if(b == nil)
636 6f4d00ee 2013-09-23 0intro goto Out0;
637 6f4d00ee 2013-09-23 0intro
638 6f4d00ee 2013-09-23 0intro l = b->l;
639 6f4d00ee 2013-09-23 0intro consPrint("%slabel %#ux %ud %ud %ud %ud %#x\n",
640 6f4d00ee 2013-09-23 0intro argc==6 ? "old: " : "", addr, l.type, l.state,
641 6f4d00ee 2013-09-23 0intro l.epoch, l.epochClose, l.tag);
642 6f4d00ee 2013-09-23 0intro
643 6f4d00ee 2013-09-23 0intro if(argc == 6){
644 6f4d00ee 2013-09-23 0intro if(strcmp(argv[1], "-") != 0)
645 6f4d00ee 2013-09-23 0intro l.type = atoi(argv[1]);
646 6f4d00ee 2013-09-23 0intro if(strcmp(argv[2], "-") != 0)
647 6f4d00ee 2013-09-23 0intro l.state = atoi(argv[2]);
648 6f4d00ee 2013-09-23 0intro if(strcmp(argv[3], "-") != 0)
649 6f4d00ee 2013-09-23 0intro l.epoch = strtoul(argv[3], 0, 0);
650 6f4d00ee 2013-09-23 0intro if(strcmp(argv[4], "-") != 0)
651 6f4d00ee 2013-09-23 0intro l.epochClose = strtoul(argv[4], 0, 0);
652 6f4d00ee 2013-09-23 0intro if(strcmp(argv[5], "-") != 0)
653 6f4d00ee 2013-09-23 0intro l.tag = strtoul(argv[5], 0, 0);
654 6f4d00ee 2013-09-23 0intro
655 6f4d00ee 2013-09-23 0intro consPrint("new: label %#ux %ud %ud %ud %ud %#x\n",
656 6f4d00ee 2013-09-23 0intro addr, l.type, l.state, l.epoch, l.epochClose, l.tag);
657 6f4d00ee 2013-09-23 0intro bb = _blockSetLabel(b, &l);
658 6f4d00ee 2013-09-23 0intro if(bb == nil)
659 6f4d00ee 2013-09-23 0intro goto Out1;
660 6f4d00ee 2013-09-23 0intro n = 0;
661 6f4d00ee 2013-09-23 0intro for(;;){
662 6f4d00ee 2013-09-23 0intro if(blockWrite(bb, Waitlock)){
663 6f4d00ee 2013-09-23 0intro while(bb->iostate != BioClean){
664 6f4d00ee 2013-09-23 0intro assert(bb->iostate == BioWriting);
665 4b576658 2013-09-23 0intro rsleep(&bb->ioready);
666 6f4d00ee 2013-09-23 0intro }
667 6f4d00ee 2013-09-23 0intro break;
668 6f4d00ee 2013-09-23 0intro }
669 4b576658 2013-09-23 0intro consPrint("blockWrite: %r\n");
670 6f4d00ee 2013-09-23 0intro if(n++ >= 5){
671 6f4d00ee 2013-09-23 0intro consPrint("giving up\n");
672 6f4d00ee 2013-09-23 0intro break;
673 6f4d00ee 2013-09-23 0intro }
674 6f4d00ee 2013-09-23 0intro sleep(5*1000);
675 6f4d00ee 2013-09-23 0intro }
676 6f4d00ee 2013-09-23 0intro blockPut(bb);
677 6f4d00ee 2013-09-23 0intro }
678 6f4d00ee 2013-09-23 0intro r = 1;
679 6f4d00ee 2013-09-23 0intro Out1:
680 6f4d00ee 2013-09-23 0intro blockPut(b);
681 6f4d00ee 2013-09-23 0intro Out0:
682 4b576658 2013-09-23 0intro runlock(&fs->elk);
683 6f4d00ee 2013-09-23 0intro
684 6f4d00ee 2013-09-23 0intro return r;
685 6f4d00ee 2013-09-23 0intro }
686 6f4d00ee 2013-09-23 0intro
687 6f4d00ee 2013-09-23 0intro /*
688 6f4d00ee 2013-09-23 0intro * Inspect and edit the blocks on disk.
689 6f4d00ee 2013-09-23 0intro */
690 6f4d00ee 2013-09-23 0intro static int
691 6f4d00ee 2013-09-23 0intro fsysBlock(Fsys* fsys, int argc, char* argv[])
692 6f4d00ee 2013-09-23 0intro {
693 6f4d00ee 2013-09-23 0intro Fs *fs;
694 6f4d00ee 2013-09-23 0intro char *s;
695 6f4d00ee 2013-09-23 0intro Block *b;
696 6f4d00ee 2013-09-23 0intro uchar *buf;
697 6f4d00ee 2013-09-23 0intro u32int addr;
698 6f4d00ee 2013-09-23 0intro int c, count, i, offset;
699 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] block addr offset [count [data]]";
700 6f4d00ee 2013-09-23 0intro
701 6f4d00ee 2013-09-23 0intro ARGBEGIN{
702 6f4d00ee 2013-09-23 0intro default:
703 6f4d00ee 2013-09-23 0intro return cliError(usage);
704 6f4d00ee 2013-09-23 0intro }ARGEND
705 6f4d00ee 2013-09-23 0intro if(argc < 2 || argc > 4)
706 6f4d00ee 2013-09-23 0intro return cliError(usage);
707 6f4d00ee 2013-09-23 0intro
708 6f4d00ee 2013-09-23 0intro fs = fsys->fs;
709 6f4d00ee 2013-09-23 0intro addr = strtoul(argv[0], 0, 0);
710 6f4d00ee 2013-09-23 0intro offset = strtoul(argv[1], 0, 0);
711 6f4d00ee 2013-09-23 0intro if(offset < 0 || offset >= fs->blockSize){
712 4b576658 2013-09-23 0intro werrstr("bad offset");
713 6f4d00ee 2013-09-23 0intro return 0;
714 6f4d00ee 2013-09-23 0intro }
715 6f4d00ee 2013-09-23 0intro if(argc > 2)
716 6f4d00ee 2013-09-23 0intro count = strtoul(argv[2], 0, 0);
717 6f4d00ee 2013-09-23 0intro else
718 6f4d00ee 2013-09-23 0intro count = 100000000;
719 6f4d00ee 2013-09-23 0intro if(offset+count > fs->blockSize)
720 6f4d00ee 2013-09-23 0intro count = fs->blockSize - count;
721 6f4d00ee 2013-09-23 0intro
722 4b576658 2013-09-23 0intro rlock(&fs->elk);
723 6f4d00ee 2013-09-23 0intro
724 6f4d00ee 2013-09-23 0intro b = cacheLocal(fs->cache, PartData, addr, argc==4 ? OReadWrite : OReadOnly);
725 6f4d00ee 2013-09-23 0intro if(b == nil){
726 4b576658 2013-09-23 0intro werrstr("cacheLocal %#ux: %r", addr);
727 4b576658 2013-09-23 0intro runlock(&fs->elk);
728 6f4d00ee 2013-09-23 0intro return 0;
729 6f4d00ee 2013-09-23 0intro }
730 6f4d00ee 2013-09-23 0intro
731 6f4d00ee 2013-09-23 0intro consPrint("\t%sblock %#ux %ud %ud %.*H\n",
732 6f4d00ee 2013-09-23 0intro argc==4 ? "old: " : "", addr, offset, count, count, b->data+offset);
733 6f4d00ee 2013-09-23 0intro
734 6f4d00ee 2013-09-23 0intro if(argc == 4){
735 6f4d00ee 2013-09-23 0intro s = argv[3];
736 6f4d00ee 2013-09-23 0intro if(strlen(s) != 2*count){
737 4b576658 2013-09-23 0intro werrstr("bad data count");
738 6f4d00ee 2013-09-23 0intro goto Out;
739 6f4d00ee 2013-09-23 0intro }
740 4b576658 2013-09-23 0intro buf = vtmallocz(count);
741 6f4d00ee 2013-09-23 0intro for(i = 0; i < count*2; i++){
742 6f4d00ee 2013-09-23 0intro if(s[i] >= '0' && s[i] <= '9')
743 6f4d00ee 2013-09-23 0intro c = s[i] - '0';
744 6f4d00ee 2013-09-23 0intro else if(s[i] >= 'a' && s[i] <= 'f')
745 6f4d00ee 2013-09-23 0intro c = s[i] - 'a' + 10;
746 6f4d00ee 2013-09-23 0intro else if(s[i] >= 'A' && s[i] <= 'F')
747 6f4d00ee 2013-09-23 0intro c = s[i] - 'A' + 10;
748 6f4d00ee 2013-09-23 0intro else{
749 4b576658 2013-09-23 0intro werrstr("bad hex");
750 4b576658 2013-09-23 0intro vtfree(buf);
751 6f4d00ee 2013-09-23 0intro goto Out;
752 6f4d00ee 2013-09-23 0intro }
753 6f4d00ee 2013-09-23 0intro if((i & 1) == 0)
754 6f4d00ee 2013-09-23 0intro c <<= 4;
755 6f4d00ee 2013-09-23 0intro buf[i>>1] |= c;
756 6f4d00ee 2013-09-23 0intro }
757 6f4d00ee 2013-09-23 0intro memmove(b->data+offset, buf, count);
758 6f4d00ee 2013-09-23 0intro consPrint("\tnew: block %#ux %ud %ud %.*H\n",
759 6f4d00ee 2013-09-23 0intro addr, offset, count, count, b->data+offset);
760 6f4d00ee 2013-09-23 0intro blockDirty(b);
761 6f4d00ee 2013-09-23 0intro }
762 6f4d00ee 2013-09-23 0intro
763 6f4d00ee 2013-09-23 0intro Out:
764 6f4d00ee 2013-09-23 0intro blockPut(b);
765 4b576658 2013-09-23 0intro runlock(&fs->elk);
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 /*
771 6f4d00ee 2013-09-23 0intro * Free a disk block.
772 6f4d00ee 2013-09-23 0intro */
773 6f4d00ee 2013-09-23 0intro static int
774 6f4d00ee 2013-09-23 0intro fsysBfree(Fsys* fsys, int argc, char* argv[])
775 6f4d00ee 2013-09-23 0intro {
776 6f4d00ee 2013-09-23 0intro Fs *fs;
777 6f4d00ee 2013-09-23 0intro Label l;
778 6f4d00ee 2013-09-23 0intro char *p;
779 6f4d00ee 2013-09-23 0intro Block *b;
780 6f4d00ee 2013-09-23 0intro u32int addr;
781 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] bfree addr ...";
782 6f4d00ee 2013-09-23 0intro
783 6f4d00ee 2013-09-23 0intro ARGBEGIN{
784 6f4d00ee 2013-09-23 0intro default:
785 6f4d00ee 2013-09-23 0intro return cliError(usage);
786 6f4d00ee 2013-09-23 0intro }ARGEND
787 6f4d00ee 2013-09-23 0intro if(argc == 0)
788 6f4d00ee 2013-09-23 0intro return cliError(usage);
789 6f4d00ee 2013-09-23 0intro
790 6f4d00ee 2013-09-23 0intro fs = fsys->fs;
791 4b576658 2013-09-23 0intro rlock(&fs->elk);
792 6f4d00ee 2013-09-23 0intro while(argc > 0){
793 6f4d00ee 2013-09-23 0intro addr = strtoul(argv[0], &p, 0);
794 6f4d00ee 2013-09-23 0intro if(*p != '\0'){
795 6f4d00ee 2013-09-23 0intro consPrint("bad address - '%ud'\n", addr);
796 6f4d00ee 2013-09-23 0intro /* syntax error; let's stop */
797 4b576658 2013-09-23 0intro runlock(&fs->elk);
798 6f4d00ee 2013-09-23 0intro return 0;
799 6f4d00ee 2013-09-23 0intro }
800 6f4d00ee 2013-09-23 0intro b = cacheLocal(fs->cache, PartData, addr, OReadOnly);
801 6f4d00ee 2013-09-23 0intro if(b == nil){
802 4b576658 2013-09-23 0intro consPrint("loading %#ux: %r\n", addr);
803 6f4d00ee 2013-09-23 0intro continue;
804 6f4d00ee 2013-09-23 0intro }
805 6f4d00ee 2013-09-23 0intro l = b->l;
806 6f4d00ee 2013-09-23 0intro if(l.state == BsFree)
807 6f4d00ee 2013-09-23 0intro consPrint("%#ux is already free\n", addr);
808 6f4d00ee 2013-09-23 0intro else{
809 6f4d00ee 2013-09-23 0intro consPrint("label %#ux %ud %ud %ud %ud %#x\n",
810 6f4d00ee 2013-09-23 0intro addr, l.type, l.state, l.epoch, l.epochClose, l.tag);
811 6f4d00ee 2013-09-23 0intro l.state = BsFree;
812 6f4d00ee 2013-09-23 0intro l.type = BtMax;
813 6f4d00ee 2013-09-23 0intro l.tag = 0;
814 6f4d00ee 2013-09-23 0intro l.epoch = 0;
815 6f4d00ee 2013-09-23 0intro l.epochClose = 0;
816 6f4d00ee 2013-09-23 0intro if(!blockSetLabel(b, &l, 0))
817 4b576658 2013-09-23 0intro consPrint("freeing %#ux: %r\n", addr);
818 6f4d00ee 2013-09-23 0intro }
819 6f4d00ee 2013-09-23 0intro blockPut(b);
820 6f4d00ee 2013-09-23 0intro argc--;
821 6f4d00ee 2013-09-23 0intro argv++;
822 6f4d00ee 2013-09-23 0intro }
823 4b576658 2013-09-23 0intro runlock(&fs->elk);
824 6f4d00ee 2013-09-23 0intro
825 6f4d00ee 2013-09-23 0intro return 1;
826 6f4d00ee 2013-09-23 0intro }
827 6f4d00ee 2013-09-23 0intro
828 6f4d00ee 2013-09-23 0intro static int
829 6f4d00ee 2013-09-23 0intro fsysDf(Fsys *fsys, int argc, char* argv[])
830 6f4d00ee 2013-09-23 0intro {
831 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] df";
832 6f4d00ee 2013-09-23 0intro u32int used, tot, bsize;
833 6f4d00ee 2013-09-23 0intro Fs *fs;
834 6f4d00ee 2013-09-23 0intro
835 6f4d00ee 2013-09-23 0intro ARGBEGIN{
836 6f4d00ee 2013-09-23 0intro default:
837 6f4d00ee 2013-09-23 0intro return cliError(usage);
838 6f4d00ee 2013-09-23 0intro }ARGEND
839 6f4d00ee 2013-09-23 0intro if(argc != 0)
840 6f4d00ee 2013-09-23 0intro return cliError(usage);
841 6f4d00ee 2013-09-23 0intro
842 6f4d00ee 2013-09-23 0intro fs = fsys->fs;
843 6f4d00ee 2013-09-23 0intro cacheCountUsed(fs->cache, fs->elo, &used, &tot, &bsize);
844 6f4d00ee 2013-09-23 0intro consPrint("\t%s: %,llud used + %,llud free = %,llud (%.1f%% used)\n",
845 6f4d00ee 2013-09-23 0intro fsys->name, used*(vlong)bsize, (tot-used)*(vlong)bsize,
846 6f4d00ee 2013-09-23 0intro tot*(vlong)bsize, used*100.0/tot);
847 6f4d00ee 2013-09-23 0intro return 1;
848 6f4d00ee 2013-09-23 0intro }
849 6f4d00ee 2013-09-23 0intro
850 6f4d00ee 2013-09-23 0intro /*
851 6f4d00ee 2013-09-23 0intro * Zero an entry or a pointer.
852 6f4d00ee 2013-09-23 0intro */
853 6f4d00ee 2013-09-23 0intro static int
854 6f4d00ee 2013-09-23 0intro fsysClrep(Fsys* fsys, int argc, char* argv[], int ch)
855 6f4d00ee 2013-09-23 0intro {
856 6f4d00ee 2013-09-23 0intro Fs *fs;
857 6f4d00ee 2013-09-23 0intro Entry e;
858 6f4d00ee 2013-09-23 0intro Block *b;
859 6f4d00ee 2013-09-23 0intro u32int addr;
860 6f4d00ee 2013-09-23 0intro int i, max, offset, sz;
861 6f4d00ee 2013-09-23 0intro uchar zero[VtEntrySize];
862 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] clr%c addr offset ...";
863 6f4d00ee 2013-09-23 0intro
864 6f4d00ee 2013-09-23 0intro ARGBEGIN{
865 6f4d00ee 2013-09-23 0intro default:
866 6f4d00ee 2013-09-23 0intro return cliError(usage, ch);
867 6f4d00ee 2013-09-23 0intro }ARGEND
868 6f4d00ee 2013-09-23 0intro if(argc < 2)
869 6f4d00ee 2013-09-23 0intro return cliError(usage, ch);
870 6f4d00ee 2013-09-23 0intro
871 6f4d00ee 2013-09-23 0intro fs = fsys->fs;
872 4b576658 2013-09-23 0intro rlock(&fsys->fs->elk);
873 6f4d00ee 2013-09-23 0intro
874 6f4d00ee 2013-09-23 0intro addr = strtoul(argv[0], 0, 0);
875 6f4d00ee 2013-09-23 0intro b = cacheLocal(fs->cache, PartData, addr, argc==4 ? OReadWrite : OReadOnly);
876 6f4d00ee 2013-09-23 0intro if(b == nil){
877 4b576658 2013-09-23 0intro werrstr("cacheLocal %#ux: %r", addr);
878 6f4d00ee 2013-09-23 0intro Err:
879 4b576658 2013-09-23 0intro runlock(&fsys->fs->elk);
880 6f4d00ee 2013-09-23 0intro return 0;
881 6f4d00ee 2013-09-23 0intro }
882 6f4d00ee 2013-09-23 0intro
883 6f4d00ee 2013-09-23 0intro switch(ch){
884 6f4d00ee 2013-09-23 0intro default:
885 4b576658 2013-09-23 0intro werrstr("clrep");
886 6f4d00ee 2013-09-23 0intro goto Err;
887 6f4d00ee 2013-09-23 0intro case 'e':
888 6f4d00ee 2013-09-23 0intro if(b->l.type != BtDir){
889 4b576658 2013-09-23 0intro werrstr("wrong block type");
890 6f4d00ee 2013-09-23 0intro goto Err;
891 6f4d00ee 2013-09-23 0intro }
892 6f4d00ee 2013-09-23 0intro sz = VtEntrySize;
893 6f4d00ee 2013-09-23 0intro memset(&e, 0, sizeof e);
894 6f4d00ee 2013-09-23 0intro entryPack(&e, zero, 0);
895 6f4d00ee 2013-09-23 0intro break;
896 6f4d00ee 2013-09-23 0intro case 'p':
897 6f4d00ee 2013-09-23 0intro if(b->l.type == BtDir || b->l.type == BtData){
898 4b576658 2013-09-23 0intro werrstr("wrong block type");
899 6f4d00ee 2013-09-23 0intro goto Err;
900 6f4d00ee 2013-09-23 0intro }
901 6f4d00ee 2013-09-23 0intro sz = VtScoreSize;
902 4b576658 2013-09-23 0intro memmove(zero, vtzeroscore, VtScoreSize);
903 6f4d00ee 2013-09-23 0intro break;
904 6f4d00ee 2013-09-23 0intro }
905 6f4d00ee 2013-09-23 0intro max = fs->blockSize/sz;
906 6f4d00ee 2013-09-23 0intro
907 6f4d00ee 2013-09-23 0intro for(i = 1; i < argc; i++){
908 6f4d00ee 2013-09-23 0intro offset = atoi(argv[i]);
909 6f4d00ee 2013-09-23 0intro if(offset >= max){
910 6f4d00ee 2013-09-23 0intro consPrint("\toffset %d too large (>= %d)\n", i, max);
911 6f4d00ee 2013-09-23 0intro continue;
912 6f4d00ee 2013-09-23 0intro }
913 6f4d00ee 2013-09-23 0intro consPrint("\tblock %#ux %d %d %.*H\n", addr, offset*sz, sz, sz, b->data+offset*sz);
914 6f4d00ee 2013-09-23 0intro memmove(b->data+offset*sz, zero, sz);
915 6f4d00ee 2013-09-23 0intro }
916 6f4d00ee 2013-09-23 0intro blockDirty(b);
917 6f4d00ee 2013-09-23 0intro blockPut(b);
918 4b576658 2013-09-23 0intro runlock(&fsys->fs->elk);
919 6f4d00ee 2013-09-23 0intro
920 6f4d00ee 2013-09-23 0intro return 1;
921 6f4d00ee 2013-09-23 0intro }
922 6f4d00ee 2013-09-23 0intro
923 6f4d00ee 2013-09-23 0intro static int
924 6f4d00ee 2013-09-23 0intro fsysClre(Fsys* fsys, int argc, char* argv[])
925 6f4d00ee 2013-09-23 0intro {
926 6f4d00ee 2013-09-23 0intro return fsysClrep(fsys, argc, argv, 'e');
927 6f4d00ee 2013-09-23 0intro }
928 6f4d00ee 2013-09-23 0intro
929 6f4d00ee 2013-09-23 0intro static int
930 6f4d00ee 2013-09-23 0intro fsysClrp(Fsys* fsys, int argc, char* argv[])
931 6f4d00ee 2013-09-23 0intro {
932 6f4d00ee 2013-09-23 0intro return fsysClrep(fsys, argc, argv, 'p');
933 6f4d00ee 2013-09-23 0intro }
934 6f4d00ee 2013-09-23 0intro
935 6f4d00ee 2013-09-23 0intro static int
936 6f4d00ee 2013-09-23 0intro fsysEsearch1(File* f, char* s, u32int elo)
937 6f4d00ee 2013-09-23 0intro {
938 6f4d00ee 2013-09-23 0intro int n, r;
939 6f4d00ee 2013-09-23 0intro DirEntry de;
940 6f4d00ee 2013-09-23 0intro DirEntryEnum *dee;
941 6f4d00ee 2013-09-23 0intro File *ff;
942 6f4d00ee 2013-09-23 0intro Entry e, ee;
943 6f4d00ee 2013-09-23 0intro char *t;
944 6f4d00ee 2013-09-23 0intro
945 6f4d00ee 2013-09-23 0intro dee = deeOpen(f);
946 6f4d00ee 2013-09-23 0intro if(dee == nil)
947 6f4d00ee 2013-09-23 0intro return 0;
948 6f4d00ee 2013-09-23 0intro
949 6f4d00ee 2013-09-23 0intro n = 0;
950 6f4d00ee 2013-09-23 0intro for(;;){
951 6f4d00ee 2013-09-23 0intro r = deeRead(dee, &de);
952 6f4d00ee 2013-09-23 0intro if(r < 0){
953 4b576658 2013-09-23 0intro consPrint("\tdeeRead %s/%s: %r\n", s, de.elem);
954 6f4d00ee 2013-09-23 0intro break;
955 6f4d00ee 2013-09-23 0intro }
956 6f4d00ee 2013-09-23 0intro if(r == 0)
957 6f4d00ee 2013-09-23 0intro break;
958 6f4d00ee 2013-09-23 0intro if(de.mode & ModeSnapshot){
959 6f4d00ee 2013-09-23 0intro if((ff = fileWalk(f, de.elem)) == nil)
960 4b576658 2013-09-23 0intro consPrint("\tcannot walk %s/%s: %r\n", s, de.elem);
961 6f4d00ee 2013-09-23 0intro else{
962 6f4d00ee 2013-09-23 0intro if(!fileGetSources(ff, &e, &ee))
963 4b576658 2013-09-23 0intro consPrint("\tcannot get sources for %s/%s: %r\n", s, de.elem);
964 6f4d00ee 2013-09-23 0intro else if(e.snap != 0 && e.snap < elo){
965 6f4d00ee 2013-09-23 0intro consPrint("\t%ud\tclri %s/%s\n", e.snap, s, de.elem);
966 6f4d00ee 2013-09-23 0intro n++;
967 6f4d00ee 2013-09-23 0intro }
968 6f4d00ee 2013-09-23 0intro fileDecRef(ff);
969 6f4d00ee 2013-09-23 0intro }
970 6f4d00ee 2013-09-23 0intro }
971 6f4d00ee 2013-09-23 0intro else if(de.mode & ModeDir){
972 6f4d00ee 2013-09-23 0intro if((ff = fileWalk(f, de.elem)) == nil)
973 4b576658 2013-09-23 0intro consPrint("\tcannot walk %s/%s: %r\n", s, de.elem);
974 6f4d00ee 2013-09-23 0intro else{
975 6f4d00ee 2013-09-23 0intro t = smprint("%s/%s", s, de.elem);
976 6f4d00ee 2013-09-23 0intro n += fsysEsearch1(ff, t, elo);
977 4b576658 2013-09-23 0intro vtfree(t);
978 6f4d00ee 2013-09-23 0intro fileDecRef(ff);
979 6f4d00ee 2013-09-23 0intro }
980 6f4d00ee 2013-09-23 0intro }
981 6f4d00ee 2013-09-23 0intro deCleanup(&de);
982 6f4d00ee 2013-09-23 0intro if(r < 0)
983 6f4d00ee 2013-09-23 0intro break;
984 6f4d00ee 2013-09-23 0intro }
985 6f4d00ee 2013-09-23 0intro deeClose(dee);
986 6f4d00ee 2013-09-23 0intro
987 6f4d00ee 2013-09-23 0intro return n;
988 6f4d00ee 2013-09-23 0intro }
989 6f4d00ee 2013-09-23 0intro
990 6f4d00ee 2013-09-23 0intro static int
991 6f4d00ee 2013-09-23 0intro fsysEsearch(Fs* fs, char* path, u32int elo)
992 6f4d00ee 2013-09-23 0intro {
993 6f4d00ee 2013-09-23 0intro int n;
994 6f4d00ee 2013-09-23 0intro File *f;
995 6f4d00ee 2013-09-23 0intro DirEntry de;
996 6f4d00ee 2013-09-23 0intro
997 6f4d00ee 2013-09-23 0intro f = fileOpen(fs, path);
998 6f4d00ee 2013-09-23 0intro if(f == nil)
999 6f4d00ee 2013-09-23 0intro return 0;
1000 6f4d00ee 2013-09-23 0intro if(!fileGetDir(f, &de)){
1001 4b576658 2013-09-23 0intro consPrint("\tfileGetDir %s failed: %r\n", path);
1002 6f4d00ee 2013-09-23 0intro fileDecRef(f);
1003 6f4d00ee 2013-09-23 0intro return 0;
1004 6f4d00ee 2013-09-23 0intro }
1005 6f4d00ee 2013-09-23 0intro if((de.mode & ModeDir) == 0){
1006 6f4d00ee 2013-09-23 0intro fileDecRef(f);
1007 6f4d00ee 2013-09-23 0intro deCleanup(&de);
1008 6f4d00ee 2013-09-23 0intro return 0;
1009 6f4d00ee 2013-09-23 0intro }
1010 6f4d00ee 2013-09-23 0intro deCleanup(&de);
1011 6f4d00ee 2013-09-23 0intro n = fsysEsearch1(f, path, elo);
1012 6f4d00ee 2013-09-23 0intro fileDecRef(f);
1013 6f4d00ee 2013-09-23 0intro return n;
1014 6f4d00ee 2013-09-23 0intro }
1015 6f4d00ee 2013-09-23 0intro
1016 6f4d00ee 2013-09-23 0intro static int
1017 6f4d00ee 2013-09-23 0intro fsysEpoch(Fsys* fsys, int argc, char* argv[])
1018 6f4d00ee 2013-09-23 0intro {
1019 6f4d00ee 2013-09-23 0intro Fs *fs;
1020 6f4d00ee 2013-09-23 0intro int force, n, remove;
1021 6f4d00ee 2013-09-23 0intro u32int low, old;
1022 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] epoch [[-ry] low]";
1023 6f4d00ee 2013-09-23 0intro
1024 6f4d00ee 2013-09-23 0intro force = 0;
1025 6f4d00ee 2013-09-23 0intro remove = 0;
1026 6f4d00ee 2013-09-23 0intro ARGBEGIN{
1027 6f4d00ee 2013-09-23 0intro case 'y':
1028 6f4d00ee 2013-09-23 0intro force = 1;
1029 6f4d00ee 2013-09-23 0intro break;
1030 6f4d00ee 2013-09-23 0intro case 'r':
1031 6f4d00ee 2013-09-23 0intro remove = 1;
1032 6f4d00ee 2013-09-23 0intro break;
1033 6f4d00ee 2013-09-23 0intro default:
1034 6f4d00ee 2013-09-23 0intro return cliError(usage);
1035 6f4d00ee 2013-09-23 0intro }ARGEND
1036 6f4d00ee 2013-09-23 0intro if(argc > 1)
1037 6f4d00ee 2013-09-23 0intro return cliError(usage);
1038 6f4d00ee 2013-09-23 0intro if(argc > 0)
1039 6f4d00ee 2013-09-23 0intro low = strtoul(argv[0], 0, 0);
1040 6f4d00ee 2013-09-23 0intro else
1041 6f4d00ee 2013-09-23 0intro low = ~(u32int)0;
1042 6f4d00ee 2013-09-23 0intro
1043 6f4d00ee 2013-09-23 0intro if(low == 0)
1044 6f4d00ee 2013-09-23 0intro return cliError("low epoch cannot be zero");
1045 6f4d00ee 2013-09-23 0intro
1046 6f4d00ee 2013-09-23 0intro fs = fsys->fs;
1047 6f4d00ee 2013-09-23 0intro
1048 4b576658 2013-09-23 0intro rlock(&fs->elk);
1049 6f4d00ee 2013-09-23 0intro consPrint("\tlow %ud hi %ud\n", fs->elo, fs->ehi);
1050 6f4d00ee 2013-09-23 0intro if(low == ~(u32int)0){
1051 4b576658 2013-09-23 0intro runlock(&fs->elk);
1052 6f4d00ee 2013-09-23 0intro return 1;
1053 6f4d00ee 2013-09-23 0intro }
1054 6f4d00ee 2013-09-23 0intro n = fsysEsearch(fsys->fs, "/archive", low);
1055 6f4d00ee 2013-09-23 0intro n += fsysEsearch(fsys->fs, "/snapshot", low);
1056 6f4d00ee 2013-09-23 0intro consPrint("\t%d snapshot%s found with epoch < %ud\n", n, n==1 ? "" : "s", low);
1057 4b576658 2013-09-23 0intro runlock(&fs->elk);
1058 6f4d00ee 2013-09-23 0intro
1059 6f4d00ee 2013-09-23 0intro /*
1060 6f4d00ee 2013-09-23 0intro * There's a small race here -- a new snapshot with epoch < low might
1061 6f4d00ee 2013-09-23 0intro * get introduced now that we unlocked fs->elk. Low has to
1062 6f4d00ee 2013-09-23 0intro * be <= fs->ehi. Of course, in order for this to happen low has
1063 6f4d00ee 2013-09-23 0intro * to be equal to the current fs->ehi _and_ a snapshot has to
1064 6f4d00ee 2013-09-23 0intro * run right now. This is a small enough window that I don't care.
1065 6f4d00ee 2013-09-23 0intro */
1066 6f4d00ee 2013-09-23 0intro if(n != 0 && !force){
1067 6f4d00ee 2013-09-23 0intro consPrint("\tnot setting low epoch\n");
1068 6f4d00ee 2013-09-23 0intro return 1;
1069 6f4d00ee 2013-09-23 0intro }
1070 6f4d00ee 2013-09-23 0intro old = fs->elo;
1071 6f4d00ee 2013-09-23 0intro if(!fsEpochLow(fs, low))
1072 4b576658 2013-09-23 0intro consPrint("\tfsEpochLow: %r\n");
1073 6f4d00ee 2013-09-23 0intro else{
1074 6f4d00ee 2013-09-23 0intro consPrint("\told: epoch%s %ud\n", force ? " -y" : "", old);
1075 6f4d00ee 2013-09-23 0intro consPrint("\tnew: epoch%s %ud\n", force ? " -y" : "", fs->elo);
1076 6f4d00ee 2013-09-23 0intro if(fs->elo < low)
1077 6f4d00ee 2013-09-23 0intro consPrint("\twarning: new low epoch < old low epoch\n");
1078 6f4d00ee 2013-09-23 0intro if(force && remove)
1079 6f4d00ee 2013-09-23 0intro fsSnapshotRemove(fs);
1080 6f4d00ee 2013-09-23 0intro }
1081 6f4d00ee 2013-09-23 0intro
1082 6f4d00ee 2013-09-23 0intro return 1;
1083 6f4d00ee 2013-09-23 0intro }
1084 6f4d00ee 2013-09-23 0intro
1085 6f4d00ee 2013-09-23 0intro static int
1086 6f4d00ee 2013-09-23 0intro fsysCreate(Fsys* fsys, int argc, char* argv[])
1087 6f4d00ee 2013-09-23 0intro {
1088 6f4d00ee 2013-09-23 0intro int r;
1089 6f4d00ee 2013-09-23 0intro ulong mode;
1090 6f4d00ee 2013-09-23 0intro char *elem, *p, *path;
1091 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] create path uid gid perm";
1092 6f4d00ee 2013-09-23 0intro DirEntry de;
1093 6f4d00ee 2013-09-23 0intro File *file, *parent;
1094 6f4d00ee 2013-09-23 0intro
1095 6f4d00ee 2013-09-23 0intro ARGBEGIN{
1096 6f4d00ee 2013-09-23 0intro default:
1097 6f4d00ee 2013-09-23 0intro return cliError(usage);
1098 6f4d00ee 2013-09-23 0intro }ARGEND
1099 6f4d00ee 2013-09-23 0intro if(argc != 4)
1100 6f4d00ee 2013-09-23 0intro return cliError(usage);
1101 6f4d00ee 2013-09-23 0intro
1102 6f4d00ee 2013-09-23 0intro if(!fsysParseMode(argv[3], &mode))
1103 6f4d00ee 2013-09-23 0intro return cliError(usage);
1104 6f4d00ee 2013-09-23 0intro if(mode&ModeSnapshot)
1105 6f4d00ee 2013-09-23 0intro return cliError("create - cannot create with snapshot bit set");
1106 6f4d00ee 2013-09-23 0intro
1107 6f4d00ee 2013-09-23 0intro if(strcmp(argv[1], uidnoworld) == 0)
1108 6f4d00ee 2013-09-23 0intro return cliError("permission denied");
1109 6f4d00ee 2013-09-23 0intro
1110 4b576658 2013-09-23 0intro rlock(&fsys->fs->elk);
1111 4b576658 2013-09-23 0intro path = vtstrdup(argv[0]);
1112 6f4d00ee 2013-09-23 0intro if((p = strrchr(path, '/')) != nil){
1113 6f4d00ee 2013-09-23 0intro *p++ = '\0';
1114 6f4d00ee 2013-09-23 0intro elem = p;
1115 6f4d00ee 2013-09-23 0intro p = path;
1116 6f4d00ee 2013-09-23 0intro if(*p == '\0')
1117 6f4d00ee 2013-09-23 0intro p = "/";
1118 6f4d00ee 2013-09-23 0intro }
1119 6f4d00ee 2013-09-23 0intro else{
1120 6f4d00ee 2013-09-23 0intro p = "/";
1121 6f4d00ee 2013-09-23 0intro elem = path;
1122 6f4d00ee 2013-09-23 0intro }
1123 6f4d00ee 2013-09-23 0intro
1124 6f4d00ee 2013-09-23 0intro r = 0;
1125 6f4d00ee 2013-09-23 0intro if((parent = fileOpen(fsys->fs, p)) == nil)
1126 6f4d00ee 2013-09-23 0intro goto out;
1127 6f4d00ee 2013-09-23 0intro
1128 6f4d00ee 2013-09-23 0intro file = fileCreate(parent, elem, mode, argv[1]);
1129 6f4d00ee 2013-09-23 0intro fileDecRef(parent);
1130 6f4d00ee 2013-09-23 0intro if(file == nil){
1131 4b576658 2013-09-23 0intro werrstr("create %s/%s: %r", p, elem);
1132 6f4d00ee 2013-09-23 0intro goto out;
1133 6f4d00ee 2013-09-23 0intro }
1134 6f4d00ee 2013-09-23 0intro
1135 6f4d00ee 2013-09-23 0intro if(!fileGetDir(file, &de)){
1136 4b576658 2013-09-23 0intro werrstr("stat failed after create: %r");
1137 6f4d00ee 2013-09-23 0intro goto out1;
1138 6f4d00ee 2013-09-23 0intro }
1139 6f4d00ee 2013-09-23 0intro
1140 6f4d00ee 2013-09-23 0intro if(strcmp(de.gid, argv[2]) != 0){
1141 4b576658 2013-09-23 0intro vtfree(de.gid);
1142 4b576658 2013-09-23 0intro de.gid = vtstrdup(argv[2]);
1143 6f4d00ee 2013-09-23 0intro if(!fileSetDir(file, &de, argv[1])){
1144 4b576658 2013-09-23 0intro werrstr("wstat failed after create: %r");
1145 6f4d00ee 2013-09-23 0intro goto out2;
1146 6f4d00ee 2013-09-23 0intro }
1147 6f4d00ee 2013-09-23 0intro }
1148 6f4d00ee 2013-09-23 0intro r = 1;
1149 6f4d00ee 2013-09-23 0intro
1150 6f4d00ee 2013-09-23 0intro out2:
1151 6f4d00ee 2013-09-23 0intro deCleanup(&de);
1152 6f4d00ee 2013-09-23 0intro out1:
1153 6f4d00ee 2013-09-23 0intro fileDecRef(file);
1154 6f4d00ee 2013-09-23 0intro out:
1155 4b576658 2013-09-23 0intro vtfree(path);
1156 4b576658 2013-09-23 0intro runlock(&fsys->fs->elk);
1157 6f4d00ee 2013-09-23 0intro
1158 6f4d00ee 2013-09-23 0intro return r;
1159 6f4d00ee 2013-09-23 0intro }
1160 6f4d00ee 2013-09-23 0intro
1161 6f4d00ee 2013-09-23 0intro static void
1162 6f4d00ee 2013-09-23 0intro fsysPrintStat(char *prefix, char *file, DirEntry *de)
1163 6f4d00ee 2013-09-23 0intro {
1164 6f4d00ee 2013-09-23 0intro char buf[64];
1165 6f4d00ee 2013-09-23 0intro
1166 6f4d00ee 2013-09-23 0intro if(prefix == nil)
1167 6f4d00ee 2013-09-23 0intro prefix = "";
1168 6f4d00ee 2013-09-23 0intro consPrint("%sstat %q %q %q %q %s %llud\n", prefix,
1169 6f4d00ee 2013-09-23 0intro file, de->elem, de->uid, de->gid, fsysModeString(de->mode, buf), de->size);
1170 6f4d00ee 2013-09-23 0intro }
1171 6f4d00ee 2013-09-23 0intro
1172 6f4d00ee 2013-09-23 0intro static int
1173 6f4d00ee 2013-09-23 0intro fsysStat(Fsys* fsys, int argc, char* argv[])
1174 6f4d00ee 2013-09-23 0intro {
1175 6f4d00ee 2013-09-23 0intro int i;
1176 6f4d00ee 2013-09-23 0intro File *f;
1177 6f4d00ee 2013-09-23 0intro DirEntry de;
1178 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] stat files...";
1179 6f4d00ee 2013-09-23 0intro
1180 6f4d00ee 2013-09-23 0intro ARGBEGIN{
1181 6f4d00ee 2013-09-23 0intro default:
1182 6f4d00ee 2013-09-23 0intro return cliError(usage);
1183 6f4d00ee 2013-09-23 0intro }ARGEND
1184 6f4d00ee 2013-09-23 0intro
1185 6f4d00ee 2013-09-23 0intro if(argc == 0)
1186 6f4d00ee 2013-09-23 0intro return cliError(usage);
1187 6f4d00ee 2013-09-23 0intro
1188 4b576658 2013-09-23 0intro rlock(&fsys->fs->elk);
1189 6f4d00ee 2013-09-23 0intro for(i=0; i<argc; i++){
1190 6f4d00ee 2013-09-23 0intro if((f = fileOpen(fsys->fs, argv[i])) == nil){
1191 4b576658 2013-09-23 0intro consPrint("%s: %r\n", argv[i]);
1192 6f4d00ee 2013-09-23 0intro continue;
1193 6f4d00ee 2013-09-23 0intro }
1194 6f4d00ee 2013-09-23 0intro if(!fileGetDir(f, &de)){
1195 4b576658 2013-09-23 0intro consPrint("%s: %r\n", argv[i]);
1196 6f4d00ee 2013-09-23 0intro fileDecRef(f);
1197 6f4d00ee 2013-09-23 0intro continue;
1198 6f4d00ee 2013-09-23 0intro }
1199 6f4d00ee 2013-09-23 0intro fsysPrintStat("\t", argv[i], &de);
1200 6f4d00ee 2013-09-23 0intro deCleanup(&de);
1201 6f4d00ee 2013-09-23 0intro fileDecRef(f);
1202 6f4d00ee 2013-09-23 0intro }
1203 4b576658 2013-09-23 0intro runlock(&fsys->fs->elk);
1204 6f4d00ee 2013-09-23 0intro return 1;
1205 6f4d00ee 2013-09-23 0intro }
1206 6f4d00ee 2013-09-23 0intro
1207 6f4d00ee 2013-09-23 0intro static int
1208 6f4d00ee 2013-09-23 0intro fsysWstat(Fsys *fsys, int argc, char* argv[])
1209 6f4d00ee 2013-09-23 0intro {
1210 6f4d00ee 2013-09-23 0intro File *f;
1211 6f4d00ee 2013-09-23 0intro char *p;
1212 6f4d00ee 2013-09-23 0intro DirEntry de;
1213 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] wstat file elem uid gid mode length\n"
1214 6f4d00ee 2013-09-23 0intro "\tuse - for any field to mean don't change";
1215 6f4d00ee 2013-09-23 0intro
1216 6f4d00ee 2013-09-23 0intro ARGBEGIN{
1217 6f4d00ee 2013-09-23 0intro default:
1218 6f4d00ee 2013-09-23 0intro return cliError(usage);
1219 6f4d00ee 2013-09-23 0intro }ARGEND
1220 6f4d00ee 2013-09-23 0intro
1221 6f4d00ee 2013-09-23 0intro if(argc != 6)
1222 6f4d00ee 2013-09-23 0intro return cliError(usage);
1223 6f4d00ee 2013-09-23 0intro
1224 4b576658 2013-09-23 0intro rlock(&fsys->fs->elk);
1225 6f4d00ee 2013-09-23 0intro if((f = fileOpen(fsys->fs, argv[0])) == nil){
1226 4b576658 2013-09-23 0intro werrstr("console wstat - walk - %r");
1227 4b576658 2013-09-23 0intro runlock(&fsys->fs->elk);
1228 6f4d00ee 2013-09-23 0intro return 0;
1229 6f4d00ee 2013-09-23 0intro }
1230 6f4d00ee 2013-09-23 0intro if(!fileGetDir(f, &de)){
1231 4b576658 2013-09-23 0intro werrstr("console wstat - stat - %r");
1232 6f4d00ee 2013-09-23 0intro fileDecRef(f);
1233 4b576658 2013-09-23 0intro runlock(&fsys->fs->elk);
1234 6f4d00ee 2013-09-23 0intro return 0;
1235 6f4d00ee 2013-09-23 0intro }
1236 6f4d00ee 2013-09-23 0intro fsysPrintStat("\told: w", argv[0], &de);
1237 6f4d00ee 2013-09-23 0intro
1238 6f4d00ee 2013-09-23 0intro if(strcmp(argv[1], "-") != 0){
1239 6f4d00ee 2013-09-23 0intro if(!validFileName(argv[1])){
1240 4b576658 2013-09-23 0intro werrstr("console wstat - bad elem");
1241 6f4d00ee 2013-09-23 0intro goto error;
1242 6f4d00ee 2013-09-23 0intro }
1243 4b576658 2013-09-23 0intro vtfree(de.elem);
1244 4b576658 2013-09-23 0intro de.elem = vtstrdup(argv[1]);
1245 6f4d00ee 2013-09-23 0intro }
1246 6f4d00ee 2013-09-23 0intro if(strcmp(argv[2], "-") != 0){
1247 6f4d00ee 2013-09-23 0intro if(!validUserName(argv[2])){
1248 4b576658 2013-09-23 0intro werrstr("console wstat - bad uid");
1249 6f4d00ee 2013-09-23 0intro goto error;
1250 6f4d00ee 2013-09-23 0intro }
1251 4b576658 2013-09-23 0intro vtfree(de.uid);
1252 4b576658 2013-09-23 0intro de.uid = vtstrdup(argv[2]);
1253 6f4d00ee 2013-09-23 0intro }
1254 6f4d00ee 2013-09-23 0intro if(strcmp(argv[3], "-") != 0){
1255 6f4d00ee 2013-09-23 0intro if(!validUserName(argv[3])){
1256 4b576658 2013-09-23 0intro werrstr("console wstat - bad gid");
1257 6f4d00ee 2013-09-23 0intro goto error;
1258 6f4d00ee 2013-09-23 0intro }
1259 4b576658 2013-09-23 0intro vtfree(de.gid);
1260 4b576658 2013-09-23 0intro de.gid = vtstrdup(argv[3]);
1261 6f4d00ee 2013-09-23 0intro }
1262 6f4d00ee 2013-09-23 0intro if(strcmp(argv[4], "-") != 0){
1263 6f4d00ee 2013-09-23 0intro if(!fsysParseMode(argv[4], &de.mode)){
1264 4b576658 2013-09-23 0intro werrstr("console wstat - bad mode");
1265 6f4d00ee 2013-09-23 0intro goto error;
1266 6f4d00ee 2013-09-23 0intro }
1267 6f4d00ee 2013-09-23 0intro }
1268 6f4d00ee 2013-09-23 0intro if(strcmp(argv[5], "-") != 0){
1269 6f4d00ee 2013-09-23 0intro de.size = strtoull(argv[5], &p, 0);
1270 6f4d00ee 2013-09-23 0intro if(argv[5][0] == '\0' || *p != '\0' || (vlong)de.size < 0){
1271 4b576658 2013-09-23 0intro werrstr("console wstat - bad length");
1272 6f4d00ee 2013-09-23 0intro goto error;
1273 6f4d00ee 2013-09-23 0intro }
1274 6f4d00ee 2013-09-23 0intro }
1275 6f4d00ee 2013-09-23 0intro
1276 6f4d00ee 2013-09-23 0intro if(!fileSetDir(f, &de, uidadm)){
1277 4b576658 2013-09-23 0intro werrstr("console wstat - %r");
1278 6f4d00ee 2013-09-23 0intro goto error;
1279 6f4d00ee 2013-09-23 0intro }
1280 6f4d00ee 2013-09-23 0intro deCleanup(&de);
1281 6f4d00ee 2013-09-23 0intro
1282 6f4d00ee 2013-09-23 0intro if(!fileGetDir(f, &de)){
1283 4b576658 2013-09-23 0intro werrstr("console wstat - stat2 - %r");
1284 6f4d00ee 2013-09-23 0intro goto error;
1285 6f4d00ee 2013-09-23 0intro }
1286 6f4d00ee 2013-09-23 0intro fsysPrintStat("\tnew: w", argv[0], &de);
1287 6f4d00ee 2013-09-23 0intro deCleanup(&de);
1288 6f4d00ee 2013-09-23 0intro fileDecRef(f);
1289 4b576658 2013-09-23 0intro runlock(&fsys->fs->elk);
1290 6f4d00ee 2013-09-23 0intro
1291 6f4d00ee 2013-09-23 0intro return 1;
1292 6f4d00ee 2013-09-23 0intro
1293 6f4d00ee 2013-09-23 0intro error:
1294 6f4d00ee 2013-09-23 0intro deCleanup(&de); /* okay to do this twice */
1295 6f4d00ee 2013-09-23 0intro fileDecRef(f);
1296 4b576658 2013-09-23 0intro runlock(&fsys->fs->elk);
1297 6f4d00ee 2013-09-23 0intro return 0;
1298 6f4d00ee 2013-09-23 0intro }
1299 6f4d00ee 2013-09-23 0intro
1300 6f4d00ee 2013-09-23 0intro static void
1301 6f4d00ee 2013-09-23 0intro fsckClri(Fsck *fsck, char *name, MetaBlock *mb, int i, Block *b)
1302 6f4d00ee 2013-09-23 0intro {
1303 6f4d00ee 2013-09-23 0intro USED(name);
1304 6f4d00ee 2013-09-23 0intro
1305 6f4d00ee 2013-09-23 0intro if((fsck->flags&DoClri) == 0)
1306 6f4d00ee 2013-09-23 0intro return;
1307 6f4d00ee 2013-09-23 0intro
1308 6f4d00ee 2013-09-23 0intro mbDelete(mb, i);
1309 6f4d00ee 2013-09-23 0intro mbPack(mb);
1310 6f4d00ee 2013-09-23 0intro blockDirty(b);
1311 6f4d00ee 2013-09-23 0intro }
1312 6f4d00ee 2013-09-23 0intro
1313 6f4d00ee 2013-09-23 0intro static void
1314 6f4d00ee 2013-09-23 0intro fsckClose(Fsck *fsck, Block *b, u32int epoch)
1315 6f4d00ee 2013-09-23 0intro {
1316 6f4d00ee 2013-09-23 0intro Label l;
1317 6f4d00ee 2013-09-23 0intro
1318 6f4d00ee 2013-09-23 0intro if((fsck->flags&DoClose) == 0)
1319 6f4d00ee 2013-09-23 0intro return;
1320 6f4d00ee 2013-09-23 0intro l = b->l;
1321 6f4d00ee 2013-09-23 0intro if(l.state == BsFree || (l.state&BsClosed)){
1322 6f4d00ee 2013-09-23 0intro consPrint("%#ux is already closed\n", b->addr);
1323 6f4d00ee 2013-09-23 0intro return;
1324 6f4d00ee 2013-09-23 0intro }
1325 6f4d00ee 2013-09-23 0intro if(epoch){
1326 6f4d00ee 2013-09-23 0intro l.state |= BsClosed;
1327 6f4d00ee 2013-09-23 0intro l.epochClose = epoch;
1328 6f4d00ee 2013-09-23 0intro }else
1329 6f4d00ee 2013-09-23 0intro l.state = BsFree;
1330 6f4d00ee 2013-09-23 0intro
1331 6f4d00ee 2013-09-23 0intro if(!blockSetLabel(b, &l, 0))
1332 4b576658 2013-09-23 0intro consPrint("%#ux setlabel: %r\n", b->addr);
1333 6f4d00ee 2013-09-23 0intro }
1334 6f4d00ee 2013-09-23 0intro
1335 6f4d00ee 2013-09-23 0intro static void
1336 6f4d00ee 2013-09-23 0intro fsckClre(Fsck *fsck, Block *b, int offset)
1337 6f4d00ee 2013-09-23 0intro {
1338 6f4d00ee 2013-09-23 0intro Entry e;
1339 6f4d00ee 2013-09-23 0intro
1340 6f4d00ee 2013-09-23 0intro if((fsck->flags&DoClre) == 0)
1341 6f4d00ee 2013-09-23 0intro return;
1342 6f4d00ee 2013-09-23 0intro if(offset<0 || offset*VtEntrySize >= fsck->bsize){
1343 6f4d00ee 2013-09-23 0intro consPrint("bad clre\n");
1344 6f4d00ee 2013-09-23 0intro return;
1345 6f4d00ee 2013-09-23 0intro }
1346 6f4d00ee 2013-09-23 0intro memset(&e, 0, sizeof e);
1347 6f4d00ee 2013-09-23 0intro entryPack(&e, b->data, offset);
1348 6f4d00ee 2013-09-23 0intro blockDirty(b);
1349 6f4d00ee 2013-09-23 0intro }
1350 6f4d00ee 2013-09-23 0intro
1351 6f4d00ee 2013-09-23 0intro static void
1352 6f4d00ee 2013-09-23 0intro fsckClrp(Fsck *fsck, Block *b, int offset)
1353 6f4d00ee 2013-09-23 0intro {
1354 6f4d00ee 2013-09-23 0intro if((fsck->flags&DoClrp) == 0)
1355 6f4d00ee 2013-09-23 0intro return;
1356 6f4d00ee 2013-09-23 0intro if(offset<0 || offset*VtScoreSize >= fsck->bsize){
1357 6f4d00ee 2013-09-23 0intro consPrint("bad clre\n");
1358 6f4d00ee 2013-09-23 0intro return;
1359 6f4d00ee 2013-09-23 0intro }
1360 4b576658 2013-09-23 0intro memmove(b->data+offset*VtScoreSize, vtzeroscore, VtScoreSize);
1361 6f4d00ee 2013-09-23 0intro blockDirty(b);
1362 6f4d00ee 2013-09-23 0intro }
1363 6f4d00ee 2013-09-23 0intro
1364 6f4d00ee 2013-09-23 0intro static int
1365 6f4d00ee 2013-09-23 0intro fsysCheck(Fsys *fsys, int argc, char *argv[])
1366 6f4d00ee 2013-09-23 0intro {
1367 6f4d00ee 2013-09-23 0intro int i, halting;
1368 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] check [-v] [options]";
1369 6f4d00ee 2013-09-23 0intro Fsck fsck;
1370 6f4d00ee 2013-09-23 0intro Block *b;
1371 6f4d00ee 2013-09-23 0intro Super super;
1372 6f4d00ee 2013-09-23 0intro
1373 6f4d00ee 2013-09-23 0intro memset(&fsck, 0, sizeof fsck);
1374 6f4d00ee 2013-09-23 0intro fsck.fs = fsys->fs;
1375 6f4d00ee 2013-09-23 0intro fsck.clri = fsckClri;
1376 6f4d00ee 2013-09-23 0intro fsck.clre = fsckClre;
1377 6f4d00ee 2013-09-23 0intro fsck.clrp = fsckClrp;
1378 6f4d00ee 2013-09-23 0intro fsck.close = fsckClose;
1379 6f4d00ee 2013-09-23 0intro fsck.print = consPrint;
1380 6f4d00ee 2013-09-23 0intro
1381 6f4d00ee 2013-09-23 0intro ARGBEGIN{
1382 6f4d00ee 2013-09-23 0intro default:
1383 6f4d00ee 2013-09-23 0intro return cliError(usage);
1384 6f4d00ee 2013-09-23 0intro }ARGEND
1385 6f4d00ee 2013-09-23 0intro
1386 6f4d00ee 2013-09-23 0intro for(i=0; i<argc; i++){
1387 6f4d00ee 2013-09-23 0intro if(strcmp(argv[i], "pblock") == 0)
1388 6f4d00ee 2013-09-23 0intro fsck.printblocks = 1;
1389 6f4d00ee 2013-09-23 0intro else if(strcmp(argv[i], "pdir") == 0)
1390 6f4d00ee 2013-09-23 0intro fsck.printdirs = 1;
1391 6f4d00ee 2013-09-23 0intro else if(strcmp(argv[i], "pfile") == 0)
1392 6f4d00ee 2013-09-23 0intro fsck.printfiles = 1;
1393 6f4d00ee 2013-09-23 0intro else if(strcmp(argv[i], "bclose") == 0)
1394 6f4d00ee 2013-09-23 0intro fsck.flags |= DoClose;
1395 6f4d00ee 2013-09-23 0intro else if(strcmp(argv[i], "clri") == 0)
1396 6f4d00ee 2013-09-23 0intro fsck.flags |= DoClri;
1397 6f4d00ee 2013-09-23 0intro else if(strcmp(argv[i], "clre") == 0)
1398 6f4d00ee 2013-09-23 0intro fsck.flags |= DoClre;
1399 6f4d00ee 2013-09-23 0intro else if(strcmp(argv[i], "clrp") == 0)
1400 6f4d00ee 2013-09-23 0intro fsck.flags |= DoClrp;
1401 6f4d00ee 2013-09-23 0intro else if(strcmp(argv[i], "fix") == 0)
1402 6f4d00ee 2013-09-23 0intro fsck.flags |= DoClose|DoClri|DoClre|DoClrp;
1403 6f4d00ee 2013-09-23 0intro else if(strcmp(argv[i], "venti") == 0)
1404 6f4d00ee 2013-09-23 0intro fsck.useventi = 1;
1405 6f4d00ee 2013-09-23 0intro else if(strcmp(argv[i], "snapshot") == 0)
1406 6f4d00ee 2013-09-23 0intro fsck.walksnapshots = 1;
1407 6f4d00ee 2013-09-23 0intro else{
1408 6f4d00ee 2013-09-23 0intro consPrint("unknown option '%s'\n", argv[i]);
1409 6f4d00ee 2013-09-23 0intro return cliError(usage);
1410 6f4d00ee 2013-09-23 0intro }
1411 6f4d00ee 2013-09-23 0intro }
1412 6f4d00ee 2013-09-23 0intro
1413 6f4d00ee 2013-09-23 0intro halting = fsys->fs->halted==0;
1414 6f4d00ee 2013-09-23 0intro if(halting)
1415 6f4d00ee 2013-09-23 0intro fsHalt(fsys->fs);
1416 6f4d00ee 2013-09-23 0intro if(fsys->fs->arch){
1417 6f4d00ee 2013-09-23 0intro b = superGet(fsys->fs->cache, &super);
1418 6f4d00ee 2013-09-23 0intro if(b == nil){
1419 6f4d00ee 2013-09-23 0intro consPrint("could not load super block\n");
1420 6f4d00ee 2013-09-23 0intro goto Out;
1421 6f4d00ee 2013-09-23 0intro }
1422 6f4d00ee 2013-09-23 0intro blockPut(b);
1423 6f4d00ee 2013-09-23 0intro if(super.current != NilBlock){
1424 6f4d00ee 2013-09-23 0intro consPrint("cannot check fs while archiver is running; "
1425 6f4d00ee 2013-09-23 0intro "wait for it to finish\n");
1426 6f4d00ee 2013-09-23 0intro goto Out;
1427 6f4d00ee 2013-09-23 0intro }
1428 6f4d00ee 2013-09-23 0intro }
1429 6f4d00ee 2013-09-23 0intro fsCheck(&fsck);
1430 6f4d00ee 2013-09-23 0intro consPrint("fsck: %d clri, %d clre, %d clrp, %d bclose\n",
1431 6f4d00ee 2013-09-23 0intro fsck.nclri, fsck.nclre, fsck.nclrp, fsck.nclose);
1432 6f4d00ee 2013-09-23 0intro Out:
1433 6f4d00ee 2013-09-23 0intro if(halting)
1434 6f4d00ee 2013-09-23 0intro fsUnhalt(fsys->fs);
1435 6f4d00ee 2013-09-23 0intro return 1;
1436 6f4d00ee 2013-09-23 0intro }
1437 6f4d00ee 2013-09-23 0intro
1438 6f4d00ee 2013-09-23 0intro static int
1439 6f4d00ee 2013-09-23 0intro fsysVenti(char* name, int argc, char* argv[])
1440 6f4d00ee 2013-09-23 0intro {
1441 6f4d00ee 2013-09-23 0intro int r;
1442 6f4d00ee 2013-09-23 0intro char *host;
1443 6f4d00ee 2013-09-23 0intro char *usage = "usage: [fsys name] venti [address]";
1444 6f4d00ee 2013-09-23 0intro Fsys *fsys;
1445 6f4d00ee 2013-09-23 0intro
1446 6f4d00ee 2013-09-23 0intro ARGBEGIN{
1447 6f4d00ee 2013-09-23 0intro default:
1448 6f4d00ee 2013-09-23 0intro return cliError(usage);
1449 6f4d00ee 2013-09-23 0intro }ARGEND
1450 6f4d00ee 2013-09-23 0intro
1451 6f4d00ee 2013-09-23 0intro if(argc == 0)
1452 6f4d00ee 2013-09-23 0intro host = nil;
1453 6f4d00ee 2013-09-23 0intro else if(argc == 1)
1454 6f4d00ee 2013-09-23 0intro host = argv[0];
1455 6f4d00ee 2013-09-23 0intro else
1456 6f4d00ee 2013-09-23 0intro return cliError(usage);
1457 6f4d00ee 2013-09-23 0intro
1458 6f4d00ee 2013-09-23 0intro if((fsys = _fsysGet(name)) == nil)
1459 6f4d00ee 2013-09-23 0intro return 0;
1460 6f4d00ee 2013-09-23 0intro
1461 4b576658 2013-09-23 0intro qlock(&fsys->lock);
1462 6f4d00ee 2013-09-23 0intro if(host == nil)
1463 6f4d00ee 2013-09-23 0intro host = fsys->venti;
1464 6f4d00ee 2013-09-23 0intro else{
1465 4b576658 2013-09-23 0intro vtfree(fsys->venti);
1466 6f4d00ee 2013-09-23 0intro if(host[0])
1467 4b576658 2013-09-23 0intro fsys->venti = vtstrdup(host);
1468 6f4d00ee 2013-09-23 0intro else{
1469 6f4d00ee 2013-09-23 0intro host = nil;
1470 6f4d00ee 2013-09-23 0intro fsys->venti = nil;
1471 6f4d00ee 2013-09-23 0intro }
1472 6f4d00ee 2013-09-23 0intro }
1473 6f4d00ee 2013-09-23 0intro
1474 6f4d00ee 2013-09-23 0intro /* already open: do a redial */
1475 6f4d00ee 2013-09-23 0intro if(fsys->fs != nil){
1476 6f4d00ee 2013-09-23 0intro if(fsys->session == nil){
1477 4b576658 2013-09-23 0intro werrstr("file system was opened with -V");
1478 6f4d00ee 2013-09-23 0intro r = 0;
1479 6f4d00ee 2013-09-23 0intro goto out;
1480 6f4d00ee 2013-09-23 0intro }
1481 6f4d00ee 2013-09-23 0intro r = 1;
1482 4b576658 2013-09-23 0intro if(myRedial(fsys->session, host) < 0
1483 4b576658 2013-09-23 0intro || vtconnect(fsys->session) < 0)
1484 6f4d00ee 2013-09-23 0intro r = 0;
1485 6f4d00ee 2013-09-23 0intro goto out;
1486 6f4d00ee 2013-09-23 0intro }
1487 6f4d00ee 2013-09-23 0intro
1488 6f4d00ee 2013-09-23 0intro /* not yet open: try to dial */
1489 6f4d00ee 2013-09-23 0intro if(fsys->session)
1490 4b576658 2013-09-23 0intro vtfreeconn(fsys->session);
1491 6f4d00ee 2013-09-23 0intro r = 1;
1492 4b576658 2013-09-23 0intro if((fsys->session = myDial(host)) == nil
1493 4b576658 2013-09-23 0intro || vtconnect(fsys->session) < 0)
1494 6f4d00ee 2013-09-23 0intro r = 0;
1495 6f4d00ee 2013-09-23 0intro out:
1496 4b576658 2013-09-23 0intro qunlock(&fsys->lock);
1497 6f4d00ee 2013-09-23 0intro fsysPut(fsys);
1498 6f4d00ee 2013-09-23 0intro return r;
1499 6f4d00ee 2013-09-23 0intro }
1500 6f4d00ee 2013-09-23 0intro
1501 6f4d00ee 2013-09-23 0intro static ulong
1502 6f4d00ee 2013-09-23 0intro freemem(void)
1503 6f4d00ee 2013-09-23 0intro {
1504 6f4d00ee 2013-09-23 0intro int nf, pgsize = 0;
1505 6f4d00ee 2013-09-23 0intro uvlong size, userpgs = 0, userused = 0;
1506 6f4d00ee 2013-09-23 0intro char *ln, *sl;
1507 6f4d00ee 2013-09-23 0intro char *fields[2];
1508 6f4d00ee 2013-09-23 0intro Biobuf *bp;
1509 6f4d00ee 2013-09-23 0intro
1510 6f4d00ee 2013-09-23 0intro size = 64*1024*1024;
1511 6f4d00ee 2013-09-23 0intro bp = Bopen("#c/swap", OREAD);
1512 6f4d00ee 2013-09-23 0intro if (bp != nil) {
1513 6f4d00ee 2013-09-23 0intro while ((ln = Brdline(bp, '\n')) != nil) {
1514 6f4d00ee 2013-09-23 0intro ln[Blinelen(bp)-1] = '\0';
1515 6f4d00ee 2013-09-23 0intro nf = tokenize(ln, fields, nelem(fields));
1516 6f4d00ee 2013-09-23 0intro if (nf != 2)
1517 6f4d00ee 2013-09-23 0intro continue;
1518 6f4d00ee 2013-09-23 0intro if (strcmp(fields[1], "pagesize") == 0)
1519 6f4d00ee 2013-09-23 0intro pgsize = atoi(fields[0]);
1520 6f4d00ee 2013-09-23 0intro else if (strcmp(fields[1], "user") == 0) {
1521 6f4d00ee 2013-09-23 0intro sl = strchr(fields[0], '/');
1522 6f4d00ee 2013-09-23 0intro if (sl == nil)
1523 6f4d00ee 2013-09-23 0intro continue;
1524 6f4d00ee 2013-09-23 0intro userpgs = atoll(sl+1);
1525 6f4d00ee 2013-09-23 0intro userused = atoll(fields[0]);
1526 6f4d00ee 2013-09-23 0intro }
1527 6f4d00ee 2013-09-23 0intro }
1528 6f4d00ee 2013-09-23 0intro Bterm(bp);
1529 6f4d00ee 2013-09-23 0intro if (pgsize > 0 && userpgs > 0)
1530 6f4d00ee 2013-09-23 0intro size = (userpgs - userused) * pgsize;
1531 6f4d00ee 2013-09-23 0intro }
1532 6f4d00ee 2013-09-23 0intro /* cap it to keep the size within 32 bits */
1533 6f4d00ee 2013-09-23 0intro if (size >= 3840UL * 1024 * 1024)
1534 6f4d00ee 2013-09-23 0intro size = 3840UL * 1024 * 1024;
1535 6f4d00ee 2013-09-23 0intro return size;
1536 6f4d00ee 2013-09-23 0intro }
1537 6f4d00ee 2013-09-23 0intro
1538 6f4d00ee 2013-09-23 0intro static int
1539 6f4d00ee 2013-09-23 0intro fsysOpen(char* name, int argc, char* argv[])
1540 6f4d00ee 2013-09-23 0intro {
1541 6f4d00ee 2013-09-23 0intro char *p, *host;
1542 6f4d00ee 2013-09-23 0intro Fsys *fsys;
1543 6f4d00ee 2013-09-23 0intro int noauth, noventi, noperm, rflag, wstatallow, noatimeupd;
1544 6f4d00ee 2013-09-23 0intro long ncache;
1545 6f4d00ee 2013-09-23 0intro char *usage = "usage: fsys name open [-APVWr] [-c ncache]";
1546 6f4d00ee 2013-09-23 0intro
1547 6f4d00ee 2013-09-23 0intro ncache = 1000;
1548 6f4d00ee 2013-09-23 0intro noauth = noperm = wstatallow = noventi = noatimeupd = 0;
1549 6f4d00ee 2013-09-23 0intro rflag = OReadWrite;
1550 6f4d00ee 2013-09-23 0intro
1551 6f4d00ee 2013-09-23 0intro ARGBEGIN{
1552 6f4d00ee 2013-09-23 0intro default:
1553 6f4d00ee 2013-09-23 0intro return cliError(usage);
1554 6f4d00ee 2013-09-23 0intro case 'A':
1555 6f4d00ee 2013-09-23 0intro noauth = 1;
1556 6f4d00ee 2013-09-23 0intro break;
1557 6f4d00ee 2013-09-23 0intro case 'P':
1558 6f4d00ee 2013-09-23 0intro noperm = 1;
1559 6f4d00ee 2013-09-23 0intro break;
1560 6f4d00ee 2013-09-23 0intro case 'V':
1561 6f4d00ee 2013-09-23 0intro noventi = 1;
1562 6f4d00ee 2013-09-23 0intro break;
1563 6f4d00ee 2013-09-23 0intro case 'W':
1564 6f4d00ee 2013-09-23 0intro wstatallow = 1;
1565 6f4d00ee 2013-09-23 0intro break;
1566 6f4d00ee 2013-09-23 0intro case 'a':
1567 6f4d00ee 2013-09-23 0intro noatimeupd = 1;
1568 6f4d00ee 2013-09-23 0intro break;
1569 6f4d00ee 2013-09-23 0intro case 'c':
1570 6f4d00ee 2013-09-23 0intro p = ARGF();
1571 6f4d00ee 2013-09-23 0intro if(p == nil)
1572 6f4d00ee 2013-09-23 0intro return cliError(usage);
1573 6f4d00ee 2013-09-23 0intro ncache = strtol(argv[0], &p, 0);
1574 6f4d00ee 2013-09-23 0intro if(ncache <= 0 || p == argv[0] || *p != '\0')
1575 6f4d00ee 2013-09-23 0intro return cliError(usage);
1576 6f4d00ee 2013-09-23 0intro break;
1577 6f4d00ee 2013-09-23 0intro case 'r':
1578 6f4d00ee 2013-09-23 0intro rflag = OReadOnly;
1579 6f4d00ee 2013-09-23 0intro break;
1580 6f4d00ee 2013-09-23 0intro }ARGEND
1581 6f4d00ee 2013-09-23 0intro if(argc)
1582 6f4d00ee 2013-09-23 0intro return cliError(usage);
1583 6f4d00ee 2013-09-23 0intro
1584 6f4d00ee 2013-09-23 0intro if((fsys = _fsysGet(name)) == nil)
1585 6f4d00ee 2013-09-23 0intro return 0;
1586 6f4d00ee 2013-09-23 0intro
1587 6f4d00ee 2013-09-23 0intro /* automatic memory sizing? */
1588 6f4d00ee 2013-09-23 0intro if(mempcnt > 0) {
1589 6f4d00ee 2013-09-23 0intro /* TODO: 8K is a hack; use the actual block size */
1590 6f4d00ee 2013-09-23 0intro ncache = (((vlong)freemem() * mempcnt) / 100) / (8*1024);
1591 6f4d00ee 2013-09-23 0intro if (ncache < 100)
1592 6f4d00ee 2013-09-23 0intro ncache = 100;
1593 6f4d00ee 2013-09-23 0intro }
1594 6f4d00ee 2013-09-23 0intro
1595 4b576658 2013-09-23 0intro qlock(&fsys->lock);
1596 6f4d00ee 2013-09-23 0intro if(fsys->fs != nil){
1597 4b576658 2013-09-23 0intro werrstr(EFsysBusy, fsys->name);
1598 4b576658 2013-09-23 0intro qunlock(&fsys->lock);
1599 6f4d00ee 2013-09-23 0intro fsysPut(fsys);
1600 6f4d00ee 2013-09-23 0intro return 0;
1601 6f4d00ee 2013-09-23 0intro }
1602 6f4d00ee 2013-09-23 0intro
1603 6f4d00ee 2013-09-23 0intro if(noventi){
1604 6f4d00ee 2013-09-23 0intro if(fsys->session){
1605 4b576658 2013-09-23 0intro vtfreeconn(fsys->session);
1606 6f4d00ee 2013-09-23 0intro fsys->session = nil;
1607 6f4d00ee 2013-09-23 0intro }
1608 6f4d00ee 2013-09-23 0intro }
1609 6f4d00ee 2013-09-23 0intro else if(fsys->session == nil){
1610 6f4d00ee 2013-09-23 0intro if(fsys->venti && fsys->venti[0])
1611 6f4d00ee 2013-09-23 0intro host = fsys->venti;
1612 6f4d00ee 2013-09-23 0intro else
1613 6f4d00ee 2013-09-23 0intro host = nil;
1614 4b576658 2013-09-23 0intro
1615 4b576658 2013-09-23 0intro if((fsys->session = myDial(host)) == nil
1616 4b576658 2013-09-23 0intro || vtconnect(fsys->session) < 0 && !noventi)
1617 4b576658 2013-09-23 0intro fprint(2, "warning: connecting to venti: %r\n");
1618 6f4d00ee 2013-09-23 0intro }
1619 6f4d00ee 2013-09-23 0intro if((fsys->fs = fsOpen(fsys->dev, fsys->session, ncache, rflag)) == nil){
1620 4b576658 2013-09-23 0intro werrstr("fsOpen: %r");
1621 4b576658 2013-09-23 0intro qunlock(&fsys->lock);
1622 6f4d00ee 2013-09-23 0intro fsysPut(fsys);
1623 6f4d00ee 2013-09-23 0intro return 0;
1624 6f4d00ee 2013-09-23 0intro }
1625 6f4d00ee 2013-09-23 0intro fsys->fs->name = fsys->name; /* for better error messages */
1626 6f4d00ee 2013-09-23 0intro fsys->noauth = noauth;
1627 6f4d00ee 2013-09-23 0intro fsys->noperm = noperm;
1628 6f4d00ee 2013-09-23 0intro fsys->wstatallow = wstatallow;
1629 6f4d00ee 2013-09-23 0intro fsys->fs->noatimeupd = noatimeupd;
1630 4b576658 2013-09-23 0intro qunlock(&fsys->lock);
1631 6f4d00ee 2013-09-23 0intro fsysPut(fsys);
1632 6f4d00ee 2013-09-23 0intro
1633 6f4d00ee 2013-09-23 0intro if(strcmp(name, "main") == 0)
1634 6f4d00ee 2013-09-23 0intro usersFileRead(nil);
1635 6f4d00ee 2013-09-23 0intro
1636 6f4d00ee 2013-09-23 0intro return 1;
1637 6f4d00ee 2013-09-23 0intro }
1638 6f4d00ee 2013-09-23 0intro
1639 6f4d00ee 2013-09-23 0intro static int
1640 6f4d00ee 2013-09-23 0intro fsysUnconfig(char* name, int argc, char* argv[])
1641 6f4d00ee 2013-09-23 0intro {
1642 6f4d00ee 2013-09-23 0intro Fsys *fsys, **fp;
1643 6f4d00ee 2013-09-23 0intro char *usage = "usage: fsys name unconfig";
1644 6f4d00ee 2013-09-23 0intro
1645 6f4d00ee 2013-09-23 0intro ARGBEGIN{
1646 6f4d00ee 2013-09-23 0intro default:
1647 6f4d00ee 2013-09-23 0intro return cliError(usage);
1648 6f4d00ee 2013-09-23 0intro }ARGEND
1649 6f4d00ee 2013-09-23 0intro if(argc)
1650 6f4d00ee 2013-09-23 0intro return cliError(usage);
1651 6f4d00ee 2013-09-23 0intro
1652 4b576658 2013-09-23 0intro wlock(&sbox.lock);
1653 6f4d00ee 2013-09-23 0intro fp = &sbox.head;
1654 6f4d00ee 2013-09-23 0intro for(fsys = *fp; fsys != nil; fsys = fsys->next){
1655 6f4d00ee 2013-09-23 0intro if(strcmp(fsys->name, name) == 0)
1656 6f4d00ee 2013-09-23 0intro break;
1657 6f4d00ee 2013-09-23 0intro fp = &fsys->next;
1658 6f4d00ee 2013-09-23 0intro }
1659 6f4d00ee 2013-09-23 0intro if(fsys == nil){
1660 4b576658 2013-09-23 0intro werrstr(EFsysNotFound, name);
1661 4b576658 2013-09-23 0intro wunlock(&sbox.lock);
1662 6f4d00ee 2013-09-23 0intro return 0;
1663 6f4d00ee 2013-09-23 0intro }
1664 6f4d00ee 2013-09-23 0intro if(fsys->ref != 0 || fsys->fs != nil){
1665 4b576658 2013-09-23 0intro werrstr(EFsysBusy, fsys->name);
1666 4b576658 2013-09-23 0intro wunlock(&sbox.lock);
1667 6f4d00ee 2013-09-23 0intro return 0;
1668 6f4d00ee 2013-09-23 0intro }
1669 6f4d00ee 2013-09-23 0intro *fp = fsys->next;
1670 4b576658 2013-09-23 0intro wunlock(&sbox.lock);
1671 6f4d00ee 2013-09-23 0intro
1672 4b576658 2013-09-23 0intro if(fsys->session != nil)
1673 4b576658 2013-09-23 0intro vtfreeconn(fsys->session);
1674 6f4d00ee 2013-09-23 0intro if(fsys->venti != nil)
1675 4b576658 2013-09-23 0intro vtfree(fsys->venti);
1676 6f4d00ee 2013-09-23 0intro if(fsys->dev != nil)
1677 4b576658 2013-09-23 0intro vtfree(fsys->dev);
1678 6f4d00ee 2013-09-23 0intro if(fsys->name != nil)
1679 4b576658 2013-09-23 0intro vtfree(fsys->name);
1680 4b576658 2013-09-23 0intro vtfree(fsys);
1681 6f4d00ee 2013-09-23 0intro
1682 6f4d00ee 2013-09-23 0intro return 1;
1683 6f4d00ee 2013-09-23 0intro }
1684 6f4d00ee 2013-09-23 0intro
1685 6f4d00ee 2013-09-23 0intro static int
1686 6f4d00ee 2013-09-23 0intro fsysConfig(char* name, int argc, char* argv[])
1687 6f4d00ee 2013-09-23 0intro {
1688 6f4d00ee 2013-09-23 0intro Fsys *fsys;
1689 6f4d00ee 2013-09-23 0intro char *part;
1690 6f4d00ee 2013-09-23 0intro char *usage = "usage: fsys name config [dev]";
1691 6f4d00ee 2013-09-23 0intro
1692 6f4d00ee 2013-09-23 0intro ARGBEGIN{
1693 6f4d00ee 2013-09-23 0intro default:
1694 6f4d00ee 2013-09-23 0intro return cliError(usage);
1695 6f4d00ee 2013-09-23 0intro }ARGEND
1696 6f4d00ee 2013-09-23 0intro if(argc > 1)
1697 6f4d00ee 2013-09-23 0intro return cliError(usage);
1698 6f4d00ee 2013-09-23 0intro
1699 6f4d00ee 2013-09-23 0intro if(argc == 0)
1700 6f4d00ee 2013-09-23 0intro part = foptname;
1701 6f4d00ee 2013-09-23 0intro else
1702 6f4d00ee 2013-09-23 0intro part = argv[0];
1703 6f4d00ee 2013-09-23 0intro
1704 6f4d00ee 2013-09-23 0intro if((fsys = _fsysGet(part)) != nil){
1705 4b576658 2013-09-23 0intro qlock(&fsys->lock);
1706 6f4d00ee 2013-09-23 0intro if(fsys->fs != nil){
1707 4b576658 2013-09-23 0intro werrstr(EFsysBusy, fsys->name);
1708 4b576658 2013-09-23 0intro qunlock(&fsys->lock);
1709 6f4d00ee 2013-09-23 0intro fsysPut(fsys);
1710 6f4d00ee 2013-09-23 0intro return 0;
1711 6f4d00ee 2013-09-23 0intro }
1712 4b576658 2013-09-23 0intro vtfree(fsys->dev);
1713 4b576658 2013-09-23 0intro fsys->dev = vtstrdup(part);
1714 4b576658 2013-09-23 0intro qunlock(&fsys->lock);
1715 6f4d00ee 2013-09-23 0intro }
1716 6f4d00ee 2013-09-23 0intro else if((fsys = fsysAlloc(name, part)) == nil)
1717 6f4d00ee 2013-09-23 0intro return 0;
1718 6f4d00ee 2013-09-23 0intro
1719 6f4d00ee 2013-09-23 0intro fsysPut(fsys);
1720 6f4d00ee 2013-09-23 0intro return 1;
1721 6f4d00ee 2013-09-23 0intro }
1722 6f4d00ee 2013-09-23 0intro
1723 6f4d00ee 2013-09-23 0intro static struct {
1724 6f4d00ee 2013-09-23 0intro char* cmd;
1725 6f4d00ee 2013-09-23 0intro int (*f)(Fsys*, int, char**);
1726 6f4d00ee 2013-09-23 0intro int (*f1)(char*, int, char**);
1727 6f4d00ee 2013-09-23 0intro } fsyscmd[] = {
1728 6f4d00ee 2013-09-23 0intro { "close", fsysClose, },
1729 6f4d00ee 2013-09-23 0intro { "config", nil, fsysConfig, },
1730 6f4d00ee 2013-09-23 0intro { "open", nil, fsysOpen, },
1731 6f4d00ee 2013-09-23 0intro { "unconfig", nil, fsysUnconfig, },
1732 6f4d00ee 2013-09-23 0intro { "venti", nil, fsysVenti, },
1733 6f4d00ee 2013-09-23 0intro
1734 6f4d00ee 2013-09-23 0intro { "bfree", fsysBfree, },
1735 6f4d00ee 2013-09-23 0intro { "block", fsysBlock, },
1736 6f4d00ee 2013-09-23 0intro { "check", fsysCheck, },
1737 6f4d00ee 2013-09-23 0intro { "clre", fsysClre, },
1738 6f4d00ee 2013-09-23 0intro { "clri", fsysClri, },
1739 6f4d00ee 2013-09-23 0intro { "clrp", fsysClrp, },
1740 6f4d00ee 2013-09-23 0intro { "create", fsysCreate, },
1741 6f4d00ee 2013-09-23 0intro { "df", fsysDf, },
1742 6f4d00ee 2013-09-23 0intro { "epoch", fsysEpoch, },
1743 6f4d00ee 2013-09-23 0intro { "halt", fsysHalt, },
1744 6f4d00ee 2013-09-23 0intro { "label", fsysLabel, },
1745 6f4d00ee 2013-09-23 0intro { "remove", fsysRemove, },
1746 6f4d00ee 2013-09-23 0intro { "snap", fsysSnap, },
1747 6f4d00ee 2013-09-23 0intro { "snaptime", fsysSnapTime, },
1748 6f4d00ee 2013-09-23 0intro { "snapclean", fsysSnapClean, },
1749 6f4d00ee 2013-09-23 0intro { "stat", fsysStat, },
1750 6f4d00ee 2013-09-23 0intro { "sync", fsysSync, },
1751 6f4d00ee 2013-09-23 0intro { "unhalt", fsysUnhalt, },
1752 6f4d00ee 2013-09-23 0intro { "wstat", fsysWstat, },
1753 6f4d00ee 2013-09-23 0intro { "vac", fsysVac, },
1754 6f4d00ee 2013-09-23 0intro
1755 6f4d00ee 2013-09-23 0intro { nil, nil, },
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 fsysXXX1(Fsys *fsys, int i, int argc, char* argv[])
1760 6f4d00ee 2013-09-23 0intro {
1761 6f4d00ee 2013-09-23 0intro int r;
1762 6f4d00ee 2013-09-23 0intro
1763 4b576658 2013-09-23 0intro qlock(&fsys->lock);
1764 6f4d00ee 2013-09-23 0intro if(fsys->fs == nil){
1765 4b576658 2013-09-23 0intro qunlock(&fsys->lock);
1766 4b576658 2013-09-23 0intro werrstr(EFsysNotOpen, fsys->name);
1767 6f4d00ee 2013-09-23 0intro return 0;
1768 6f4d00ee 2013-09-23 0intro }
1769 6f4d00ee 2013-09-23 0intro
1770 6f4d00ee 2013-09-23 0intro if(fsys->fs->halted
1771 6f4d00ee 2013-09-23 0intro && fsyscmd[i].f != fsysUnhalt && fsyscmd[i].f != fsysCheck){
1772 4b576658 2013-09-23 0intro werrstr("file system %s is halted", fsys->name);
1773 4b576658 2013-09-23 0intro qunlock(&fsys->lock);
1774 6f4d00ee 2013-09-23 0intro return 0;
1775 6f4d00ee 2013-09-23 0intro }
1776 6f4d00ee 2013-09-23 0intro
1777 6f4d00ee 2013-09-23 0intro r = (*fsyscmd[i].f)(fsys, argc, argv);
1778 4b576658 2013-09-23 0intro qunlock(&fsys->lock);
1779 6f4d00ee 2013-09-23 0intro return r;
1780 6f4d00ee 2013-09-23 0intro }
1781 6f4d00ee 2013-09-23 0intro
1782 6f4d00ee 2013-09-23 0intro static int
1783 6f4d00ee 2013-09-23 0intro fsysXXX(char* name, int argc, char* argv[])
1784 6f4d00ee 2013-09-23 0intro {
1785 6f4d00ee 2013-09-23 0intro int i, r;
1786 6f4d00ee 2013-09-23 0intro Fsys *fsys;
1787 6f4d00ee 2013-09-23 0intro
1788 6f4d00ee 2013-09-23 0intro for(i = 0; fsyscmd[i].cmd != nil; i++){
1789 6f4d00ee 2013-09-23 0intro if(strcmp(fsyscmd[i].cmd, argv[0]) == 0)
1790 6f4d00ee 2013-09-23 0intro break;
1791 6f4d00ee 2013-09-23 0intro }
1792 6f4d00ee 2013-09-23 0intro
1793 6f4d00ee 2013-09-23 0intro if(fsyscmd[i].cmd == nil){
1794 4b576658 2013-09-23 0intro werrstr("unknown command - '%s'", argv[0]);
1795 6f4d00ee 2013-09-23 0intro return 0;
1796 6f4d00ee 2013-09-23 0intro }
1797 6f4d00ee 2013-09-23 0intro
1798 6f4d00ee 2013-09-23 0intro /* some commands want the name... */
1799 6f4d00ee 2013-09-23 0intro if(fsyscmd[i].f1 != nil){
1800 6f4d00ee 2013-09-23 0intro if(strcmp(name, FsysAll) == 0){
1801 4b576658 2013-09-23 0intro werrstr("cannot use fsys %#q with %#q command", FsysAll, argv[0]);
1802 6f4d00ee 2013-09-23 0intro return 0;
1803 6f4d00ee 2013-09-23 0intro }
1804 6f4d00ee 2013-09-23 0intro return (*fsyscmd[i].f1)(name, argc, argv);
1805 6f4d00ee 2013-09-23 0intro }
1806 6f4d00ee 2013-09-23 0intro
1807 6f4d00ee 2013-09-23 0intro /* ... but most commands want the Fsys */
1808 6f4d00ee 2013-09-23 0intro if(strcmp(name, FsysAll) == 0){
1809 6f4d00ee 2013-09-23 0intro r = 1;
1810 4b576658 2013-09-23 0intro rlock(&sbox.lock);
1811 6f4d00ee 2013-09-23 0intro for(fsys = sbox.head; fsys != nil; fsys = fsys->next){
1812 6f4d00ee 2013-09-23 0intro fsys->ref++;
1813 6f4d00ee 2013-09-23 0intro r = fsysXXX1(fsys, i, argc, argv) && r;
1814 6f4d00ee 2013-09-23 0intro fsys->ref--;
1815 6f4d00ee 2013-09-23 0intro }
1816 4b576658 2013-09-23 0intro runlock(&sbox.lock);
1817 6f4d00ee 2013-09-23 0intro }else{
1818 6f4d00ee 2013-09-23 0intro if((fsys = _fsysGet(name)) == nil)
1819 6f4d00ee 2013-09-23 0intro return 0;
1820 6f4d00ee 2013-09-23 0intro r = fsysXXX1(fsys, i, argc, argv);
1821 6f4d00ee 2013-09-23 0intro fsysPut(fsys);
1822 6f4d00ee 2013-09-23 0intro }
1823 6f4d00ee 2013-09-23 0intro return r;
1824 6f4d00ee 2013-09-23 0intro }
1825 6f4d00ee 2013-09-23 0intro
1826 6f4d00ee 2013-09-23 0intro static int
1827 6f4d00ee 2013-09-23 0intro cmdFsysXXX(int argc, char* argv[])
1828 6f4d00ee 2013-09-23 0intro {
1829 6f4d00ee 2013-09-23 0intro char *name;
1830 6f4d00ee 2013-09-23 0intro
1831 6f4d00ee 2013-09-23 0intro if((name = sbox.curfsys) == nil){
1832 4b576658 2013-09-23 0intro werrstr(EFsysNoCurrent, argv[0]);
1833 6f4d00ee 2013-09-23 0intro return 0;
1834 6f4d00ee 2013-09-23 0intro }
1835 6f4d00ee 2013-09-23 0intro
1836 6f4d00ee 2013-09-23 0intro return fsysXXX(name, argc, argv);
1837 6f4d00ee 2013-09-23 0intro }
1838 6f4d00ee 2013-09-23 0intro
1839 6f4d00ee 2013-09-23 0intro static int
1840 6f4d00ee 2013-09-23 0intro cmdFsys(int argc, char* argv[])
1841 6f4d00ee 2013-09-23 0intro {
1842 6f4d00ee 2013-09-23 0intro Fsys *fsys;
1843 6f4d00ee 2013-09-23 0intro char *usage = "usage: fsys [name ...]";
1844 6f4d00ee 2013-09-23 0intro
1845 6f4d00ee 2013-09-23 0intro ARGBEGIN{
1846 6f4d00ee 2013-09-23 0intro default:
1847 6f4d00ee 2013-09-23 0intro return cliError(usage);
1848 6f4d00ee 2013-09-23 0intro }ARGEND
1849 6f4d00ee 2013-09-23 0intro
1850 6f4d00ee 2013-09-23 0intro if(argc == 0){
1851 4b576658 2013-09-23 0intro rlock(&sbox.lock);
1852 6f4d00ee 2013-09-23 0intro currfsysname = sbox.head->name;
1853 6f4d00ee 2013-09-23 0intro for(fsys = sbox.head; fsys != nil; fsys = fsys->next)
1854 6f4d00ee 2013-09-23 0intro consPrint("\t%s\n", fsys->name);
1855 4b576658 2013-09-23 0intro runlock(&sbox.lock);
1856 6f4d00ee 2013-09-23 0intro return 1;
1857 6f4d00ee 2013-09-23 0intro }
1858 6f4d00ee 2013-09-23 0intro if(argc == 1){
1859 6f4d00ee 2013-09-23 0intro fsys = nil;
1860 6f4d00ee 2013-09-23 0intro if(strcmp(argv[0], FsysAll) != 0 && (fsys = fsysGet(argv[0])) == nil)
1861 6f4d00ee 2013-09-23 0intro return 0;
1862 4b576658 2013-09-23 0intro sbox.curfsys = vtstrdup(argv[0]);
1863 6f4d00ee 2013-09-23 0intro consPrompt(sbox.curfsys);
1864 6f4d00ee 2013-09-23 0intro if(fsys)
1865 6f4d00ee 2013-09-23 0intro fsysPut(fsys);
1866 6f4d00ee 2013-09-23 0intro return 1;
1867 6f4d00ee 2013-09-23 0intro }
1868 6f4d00ee 2013-09-23 0intro
1869 6f4d00ee 2013-09-23 0intro return fsysXXX(argv[0], argc-1, argv+1);
1870 6f4d00ee 2013-09-23 0intro }
1871 6f4d00ee 2013-09-23 0intro
1872 6f4d00ee 2013-09-23 0intro int
1873 6f4d00ee 2013-09-23 0intro fsysInit(void)
1874 6f4d00ee 2013-09-23 0intro {
1875 6f4d00ee 2013-09-23 0intro int i;
1876 6f4d00ee 2013-09-23 0intro
1877 6f4d00ee 2013-09-23 0intro fmtinstall('H', encodefmt);
1878 6f4d00ee 2013-09-23 0intro fmtinstall('V', scoreFmt);
1879 6f4d00ee 2013-09-23 0intro fmtinstall('L', labelFmt);
1880 6f4d00ee 2013-09-23 0intro
1881 6f4d00ee 2013-09-23 0intro cliAddCmd("fsys", cmdFsys);
1882 6f4d00ee 2013-09-23 0intro for(i = 0; fsyscmd[i].cmd != nil; i++){
1883 6f4d00ee 2013-09-23 0intro if(fsyscmd[i].f != nil)
1884 6f4d00ee 2013-09-23 0intro cliAddCmd(fsyscmd[i].cmd, cmdFsysXXX);
1885 6f4d00ee 2013-09-23 0intro }
1886 6f4d00ee 2013-09-23 0intro /* the venti cmd is special: the fs can be either open or closed */
1887 6f4d00ee 2013-09-23 0intro cliAddCmd("venti", cmdFsysXXX);
1888 6f4d00ee 2013-09-23 0intro cliAddCmd("printconfig", cmdPrintConfig);
1889 6f4d00ee 2013-09-23 0intro
1890 6f4d00ee 2013-09-23 0intro return 1;
1891 6f4d00ee 2013-09-23 0intro }