ref: f286eda5878116e4bc8dc08266a5ca499c8378f6
parent: cb8d49e3c2026324252377e601550758dfa30b83
parent: 9a3942718357a83c534ee5a37ae9bd3bc85a2f50
author: cinap_lenrek <[email protected]>
date: Sat Nov 17 20:12:27 EST 2012
merge
--- a/sys/src/cmd/hjfs/auth.c
+++ b/sys/src/cmd/hjfs/auth.c
@@ -366,54 +366,14 @@
createuserdir(Fs *fs, char *name, short uid)
{
Chan *ch;
- Buf *b, *c;
- Dentry *d;
- FLoc f;
- ch = chanattach(fs, 0);
+ ch = chanattach(fs, CHFNOPERM);
if(ch == nil)
return;
- ch->uid = -1;
- if(chanwalk(ch, "usr") <= 0 || (ch->loc->type & QTDIR) == 0){
- direrr:
- chanclunk(ch);
- return;
- }
- chbegin(ch);
- if(willmodify(ch->fs, ch->loc, 0) < 0){
- direrr1:
- chend(ch);
- goto direrr;
- }
- b = getbuf(ch->fs->d, ch->loc->blk, TDENTRY, 0);
- if(b == nil)
- goto direrr1;
- if(newentry(ch->fs, ch->loc, b, name, &f) <= 0){
- direrr2:
- putbuf(b);
- goto direrr1;
- }
- modified(ch, &b->de[ch->loc->deind]);
- c = getbuf(ch->fs->d, f.blk, TDENTRY, 0);
- if(c == nil)
- goto direrr2;
- c->op |= BDELWRI;
- d = &c->de[f.deind];
- memset(d, 0, sizeof(*d));
- if(newqid(fs, &d->path) < 0){
- direrr3:
- putbuf(c);
- goto direrr2;
- }
- strncpy(d->name, name, NAMELEN - 1);
- d->uid = uid;
- d->muid = uid;
- d->gid = uid;
- d->mode = DALLOC | 0775;
- d->type = QTDIR;
- d->atime = time(0);
- d->mtime = d->atime;
- goto direrr3;
+ ch->uid = uid;
+ if(chanwalk(ch, "usr") > 0)
+ chancreat(ch, name, DMDIR | 0775, OREAD);
+ chanclunk(ch);
}
int
--- a/sys/src/cmd/hjfs/buf.c
+++ b/sys/src/cmd/hjfs/buf.c
@@ -266,6 +266,11 @@
req.nodata = nodata;
send(getb, &req);
recv(th->resp, &b);
+ if(b->error != nil){
+ werrstr("%s", b->error);
+ putbuf(b);
+ return nil;
+ }
if(nodata)
b->type = type;
if(b->type != type && type != -1){
@@ -272,11 +277,6 @@
dprint("hjfs: type mismatch, dev %s, block %lld, got %T, want %T, caller %#p\n",
d->name, off, b->type, type, getcallerpc(&d));
werrstr("phase error -- type mismatch");
- putbuf(b);
- return nil;
- }
- if(b->error != nil){
- werrstr("%s", b->error);
putbuf(b);
return nil;
}
--- a/sys/src/cmd/hjfs/conv.c
+++ b/sys/src/cmd/hjfs/conv.c
@@ -53,7 +53,7 @@
GET64(b->sb.qidpath);
break;
case TDENTRY:
- for(d = b->de; d < b->de + nelem(b->de); d++){
+ for(d = b->de; d < &b->de[DEPERBLK]; d++){
GETS(d->name, NAMELEN);
GET16(d->uid);
GET16(d->muid);
--- a/sys/src/cmd/hjfs/dat.h
+++ b/sys/src/cmd/hjfs/dat.h
@@ -185,8 +185,10 @@
CHWRITE = 2,
CHRCLOSE = 4,
CHFDUMP = 1,
+
CHFNOLOCK = 2,
CHFRO = 4,
+ CHFNOPERM = 8,
CHWBUSY = 1,
CHWCLUNK = 2,
--- a/sys/src/cmd/hjfs/dump.c
+++ b/sys/src/cmd/hjfs/dump.c
@@ -24,7 +24,7 @@
putbuf(ba);
return -1;
}
- rc = newentry(fs, b, bb, nname, &c);
+ rc = newentry(fs, b, bb, nname, &c, 1);
if(rc < 0){
err1:
putbuf(bb);
@@ -35,7 +35,7 @@
if(bc == nil)
goto err1;
d = &bc->de[c.deind];
- memcpy(d, &ba->de[a->deind], sizeof(Dentry));
+ memcpy(d, &ba->de[a->deind], sizeof(*d));
strcpy(d->name, nname);
for(i = 0; i < NDIRECT; i++)
if(d->db[i] != 0)
@@ -116,6 +116,7 @@
willmodify(Fs *fs, Loc *l, int nolock)
{
Buf *p;
+ Loc *m;
uvlong i, r;
Dentry *d;
int rc;
@@ -150,7 +151,7 @@
continue;
if(r == l->blk)
goto found;
- }
+ }
phase:
werrstr("willmodify -- phase error");
putbuf(p);
@@ -164,7 +165,19 @@
if(rc == 0)
goto phase;
putbuf(p);
- l->blk = r;
+
+ if(r != l->blk){
+ /*
+ * block got dumped, update the loctree so locs
+ * point to the new block.
+ */
+ qlock(&fs->loctree);
+ for(m = l->cnext; m != l; m = m->cnext)
+ if(m->blk == l->blk)
+ m->blk = r;
+ l->blk = r;
+ qunlock(&fs->loctree);
+ }
done:
l->flags |= LDUMPED;
if(!nolock){
--- a/sys/src/cmd/hjfs/fns.h
+++ b/sys/src/cmd/hjfs/fns.h
@@ -44,7 +44,7 @@
int dprint(char *fmt, ...);
int delete(Fs *, FLoc *, Buf *);
int chref(Fs *, uvlong, int);
-int newentry(Fs *, Loc *, Buf *, char *, FLoc *);
+int newentry(Fs *, Loc *, Buf *, char *, FLoc *, int);
int namevalid(char *);
int usersload(Fs *, Chan *);
int userssave(Fs *, Chan *);
--- a/sys/src/cmd/hjfs/fs1.c
+++ b/sys/src/cmd/hjfs/fs1.c
@@ -34,8 +34,12 @@
{
if(a->type != b->type)
return 1;
- if(a->path != b->path)
+ if(a->path != b->path){
+ /* special case for dump, this is ok */
+ if(a->path==ROOTQID && b->path==DUMPROOTQID)
+ return 0;
return 1;
+ }
return 0;
}
@@ -46,12 +50,14 @@
d = &b->de[l->deind];
if((d->mode & (DGONE | DALLOC)) == 0){
- dprint("hjfs: getdent: file gone, callerpc %#p\n", getcallerpc(&l));
+ dprint("hjfs: getdent: file gone, d=%llux, l=%llud/%d %llux, callerpc %#p\n",
+ d->path, l->blk, l->deind, l->path, getcallerpc(&l));
werrstr("phase error -- getdent");
return nil;
}
if(qidcmp(d, l) != 0){
- dprint("hjfs: getdent: wrong qid, callerpc %#p\n", getcallerpc(&l));
+ dprint("hjfs: getdent: wrong qid d=%llux != l=%llud/%d %llux, callerpc %#p\n",
+ d->path, l->blk, l->deind, l->path, getcallerpc(&l));
werrstr("phase error -- getdent");
return nil;
}
@@ -950,66 +956,70 @@
return 0;
}
+/*
+ * newentry() looks for a free slot in the directory
+ * and returns FLoc pointing to the slot. if no free
+ * slot is available a new block is allocated. if
+ * dump == 0, then the resulting blk from the FLoc
+ * *is not* dumped, so to finally allocate the Dentry,
+ * one has to call willmodify() on res before modyfing it.
+ */
int
-newentry(Fs *fs, Loc *l, Buf *b, char *name, FLoc *res)
+newentry(Fs *fs, Loc *l, Buf *b, char *name, FLoc *res, int dump)
{
Dentry *d, *dd;
uvlong i, si, r;
- int j, sj, rc;
+ int j, sj;
Buf *c;
- FLoc f;
si = sj = -1;
d = getdent(l, b);
- if(d != nil) for(i = 0; i <= d->size; i++){
- if(i >= d->size && si != -1)
- break;
- rc = getblk(fs, l, b, i, &r, si == -1 ? GBCREATE : GBREAD);
- if(rc < 0)
- continue;
- if(rc == 0 && si != -1)
- continue;
- c = getbuf(fs->d, r, TDENTRY, rc == 0);
- if(c == nil)
- continue;
- if(rc == 0){
- memset(c->de, 0, sizeof(c->de));
- if(i >= d->size){
- d->size = i+1;
- b->op |= BDELWRI;
+ if(d != nil){
+ for(i = 0; i < d->size; i++){
+ if(getblk(fs, l, b, i, &r, GBREAD) <= 0)
+ continue;
+ c = getbuf(fs->d, r, TDENTRY, 0);
+ if(c == nil)
+ continue;
+ for(j = 0; j < DEPERBLK; j++){
+ dd = &c->de[j];
+ if((dd->mode & DGONE) != 0)
+ continue;
+ if((dd->mode & DALLOC) != 0){
+ if(strcmp(dd->name, name) == 0){
+ werrstr(Eexists);
+ putbuf(c);
+ return 0;
+ }
+ continue;
+ }
+ if(si != -1 || haveloc(fs, r, j, l))
+ continue;
+ si = i;
+ sj = j;
}
- c->op |= BDELWRI;
+ putbuf(c);
}
- for(j = 0; j < DEPERBLK; j++){
- dd = &c->de[j];
- if((dd->mode & DALLOC) != 0){
- if(strcmp(dd->name, name) == 0){
- werrstr(Eexists);
+ if(si == -1 && i == d->size){
+ if(getblk(fs, l, b, i, &r, GBCREATE) >= 0){
+ c = getbuf(fs->d, r, TDENTRY, 1);
+ if(c != nil){
+ si = i;
+ sj = 0;
+ d->size = i+1;
+ b->op |= BDELWRI;
+ memset(c->de, 0, sizeof(c->de));
+ c->op |= BDELWRI;
putbuf(c);
- return 0;
}
- continue;
}
- if(si != -1 || haveloc(fs, r, j, l))
- continue;
- if((dd->mode & DGONE) != 0){
- memset(&f, 0, sizeof(f));
- f.blk = r;
- f.deind = j;
- f.Qid = dd->Qid;
- if(delete(fs, &f, c) < 0)
- continue;
- }
- si = i;
- sj = j;
}
- putbuf(c);
}
if(si == -1 || sj == -1){
werrstr("phase error -- create");
return -1;
}
- if(getblk(fs, l, b, si, &res->blk, GBWRITE) <= 0)
+ if(getblk(fs, l, b, si, &res->blk, dump != 0 ? GBWRITE : GBREAD) <= 0)
return -1;
res->deind = sj;
res->Qid = (Qid){0, 0, 0};
--- a/sys/src/cmd/hjfs/fs2.c
+++ b/sys/src/cmd/hjfs/fs2.c
@@ -104,11 +104,12 @@
int
chancreat(Chan *ch, char *name, int perm, int mode)
{
- Buf *b, *c;
+ Buf *b;
Dentry *d;
int isdir;
+ Loc *l;
FLoc f;
-
+
if((ch->flags & CHFRO) != 0){
werrstr(Einval);
return -1;
@@ -134,6 +135,7 @@
chend(ch);
return -1;
}
+ l = nil;
d = getdent(ch->loc, b);
if(d == nil)
goto error;
@@ -141,36 +143,40 @@
werrstr(Enotadir);
goto error;
}
- if(!permcheck(ch->fs, d, ch->uid, OWRITE)){
- werrstr(Eperm);
+ if((ch->flags & CHFNOPERM) == 0) /* for console */
+ if(!permcheck(ch->fs, d, ch->uid, OWRITE)){
+ werrstr(Eperm);
+ goto error;
+ }
+ if(newentry(ch->fs, ch->loc, b, name, &f, 0) <= 0)
goto error;
- }
- if(newentry(ch->fs, ch->loc, b, name, &f) <= 0)
- goto error;
- c = getbuf(ch->fs->d, f.blk, TDENTRY, 0);
- if(c == nil)
- goto error;
- modified(ch, d);
- b->op |= BDELWRI;
- c->op |= BDELWRI;
if(isdir)
perm &= ~0777 | d->mode & 0777;
else
perm &= ~0666 | d->mode & 0666;
- d = &c->de[f.deind];
- memset(d, 0, sizeof(*d));
- if(newqid(ch->fs, &d->path) < 0){
- putbuf(c);
+ f.type = perm >> 24;
+ if(newqid(ch->fs, &f.path) < 0)
goto error;
- }
- d->type = perm >> 24;
+ l = getloc(ch->fs, f, ch->loc);
+ modified(ch, d);
+ b->op |= BDELWRI;
+ putbuf(b);
+ b = nil;
+
+ if(willmodify(ch->fs, l, ch->flags & CHFNOLOCK) < 0)
+ goto error;
+ b = getbuf(ch->fs->d, l->blk, TDENTRY, 0);
+ if(b == nil)
+ goto error;
+ ch->loc = l;
+ d = &b->de[l->deind];
+ memset(d, 0, sizeof(*d));
+ d->Qid = l->Qid;
strcpy(d->name, name);
d->mtime = time(0);
d->atime = d->mtime;
d->gid = d->uid = d->muid = ch->uid;
d->mode = DALLOC | perm & 0777;
- f.Qid = d->Qid;
- ch->loc = getloc(ch->fs, f, ch->loc);
if((d->type & QTEXCL) != 0){
qlock(&ch->loc->ex);
ch->loc->exlock = ch;
@@ -177,8 +183,9 @@
ch->loc->lwrite = d->atime;
qunlock(&ch->loc->ex);
}
- putbuf(c);
+ b->op |= BDELWRI;
putbuf(b);
+
switch(mode & OEXEC){
case ORDWR:
ch->open |= CHREAD;
@@ -194,7 +201,10 @@
return 1;
error:
- putbuf(b);
+ if(l != nil)
+ putloc(ch->fs, l, 0);
+ if(b != nil)
+ putbuf(b);
chend(ch);
return -1;
}
@@ -212,6 +222,11 @@
chend(ch);
return -1;
}
+ if((mode & OTRUNC) != 0)
+ if(willmodify(ch->fs, ch->loc, ch->flags & CHFNOLOCK) < 0){
+ chend(ch);
+ return -1;
+ }
b = getbuf(ch->fs->d, ch->loc->blk, TDENTRY, 0);
if(b == nil){
chend(ch);