aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/vac/file.c
diff options
context:
space:
mode:
authorRuss Cox <rsc@swtch.com>2008-07-03 01:34:48 -0400
committerRuss Cox <rsc@swtch.com>2008-07-03 01:34:48 -0400
commite05b0ff3ebd8086809714527a27b412345ff4d72 (patch)
tree44dcf95f09055fb28e406a845b2d7fec4c3bd15b /src/cmd/vac/file.c
parentd9841dc7adc0ad99e56cf508d5d6b6d2e59afbb5 (diff)
downloadplan9port-e05b0ff3ebd8086809714527a27b412345ff4d72.tar.gz
plan9port-e05b0ff3ebd8086809714527a27b412345ff4d72.tar.bz2
plan9port-e05b0ff3ebd8086809714527a27b412345ff4d72.zip
vac: add -a and -x flags
Thanks to Michael Kaminsky for the suggestion.
Diffstat (limited to 'src/cmd/vac/file.c')
-rw-r--r--src/cmd/vac/file.c58
1 files changed, 35 insertions, 23 deletions
diff --git a/src/cmd/vac/file.c b/src/cmd/vac/file.c
index f5f823d7..d7ad2056 100644
--- a/src/cmd/vac/file.c
+++ b/src/cmd/vac/file.c
@@ -974,6 +974,7 @@ filemetaalloc(VacFile *fp, VacDir *dir, u32int start)
vtblockput(b);
if((b = vtfileblock(ms, bo, VtORDWR)) == nil)
goto Err;
+ mbunpack(&mb, b->data, ms->dsize);
goto Found;
}
vtblockput(b);
@@ -1002,7 +1003,6 @@ Found:
me.p = p;
me.size = n;
vdpack(dir, &me, VacDirVersion);
-vdunpack(dir, &me);
mbinsert(&mb, i, &me);
mbpack(&mb);
vtblockput(b);
@@ -1166,6 +1166,7 @@ Err:
/*
* Flush all data associated with f out of the cache and onto venti.
* If recursive is set, flush f's children too.
+ * Vacfiledecref knows how to flush source and msource too.
*/
int
vacfileflush(VacFile *f, int recursive)
@@ -1183,25 +1184,12 @@ vacfileflush(VacFile *f, int recursive)
ret = -1;
filemetaunlock(f);
- /*
- * Vacfiledecref knows how to flush source and msource too.
- */
if(filelock(f) < 0)
return -1;
- vtfilelock(f->source, -1);
- if(vtfileflush(f->source) < 0)
- ret = -1;
- vtfileunlock(f->source);
- if(f->msource){
- vtfilelock(f->msource, -1);
- if(vtfileflush(f->msource) < 0)
- ret = -1;
- vtfileunlock(f->msource);
- }
-
+
/*
* Lock order prevents us from flushing kids while holding
- * lock, so make a list.
+ * lock, so make a list and then flush without the lock.
*/
nkids = 0;
kids = nil;
@@ -1216,14 +1204,32 @@ vacfileflush(VacFile *f, int recursive)
p->ref++;
}
}
- fileunlock(f);
-
- for(i=0; i<nkids; i++){
- if(vacfileflush(kids[i], 1) < 0)
- ret = -1;
- vacfiledecref(kids[i]);
+ if(nkids > 0){
+ fileunlock(f);
+ for(i=0; i<nkids; i++){
+ if(vacfileflush(kids[i], 1) < 0)
+ ret = -1;
+ vacfiledecref(kids[i]);
+ }
+ filelock(f);
}
free(kids);
+
+ /*
+ * Now we can flush our own data.
+ */
+ vtfilelock(f->source, -1);
+ if(vtfileflush(f->source) < 0)
+ ret = -1;
+ vtfileunlock(f->source);
+ if(f->msource){
+ vtfilelock(f->msource, -1);
+ if(vtfileflush(f->msource) < 0)
+ ret = -1;
+ vtfileunlock(f->msource);
+ }
+ fileunlock(f);
+
return ret;
}
@@ -1332,6 +1338,12 @@ vacfilecreate(VacFile *fp, char *elem, ulong mode)
vacfileincref(fp);
fileunlock(fp);
+
+ filelock(ff);
+ vtfilelock(ff->source, -1);
+ vtfileunlock(ff->source);
+ fileunlock(ff);
+
return ff;
Err:
@@ -2031,7 +2043,7 @@ vacfssync(VacFs *fs)
return -1;
}
vtfileclose(f);
-
+
/* Build a root block. */
memset(&root, 0, sizeof root);
strcpy(root.type, "vac");