ref: 7fa15946915dfffc3856c9075b20f591d1b00195
parent: 5bdac7aa918b452953323093051c758938e381fe
author: Ori Bernstein <ori@eigenstate.org>
date: Sun May 7 21:21:05 EDT 2023
fs: give correct errors on rename and create return Efsrch instead of Eexist when something doesn't exist, and check if we're clobbering a file with wstat
--- a/dat.h
+++ b/dat.h
@@ -129,6 +129,8 @@
extern char Efid[];
extern char Etype[];
extern char Edscan[];
+extern char Esrch[];
+extern char Efsrch[];
extern char Eexist[];
extern char Emode[];
extern char Efull[];
@@ -551,6 +553,7 @@
Key;
Xdir;
Dent *next;
+ vlong up;
long ref;
char gone;
--- a/error.c
+++ b/error.c
@@ -11,6 +11,8 @@
char Efid[] = "fid in use";
char Etype[] = "invalid fid type";
char Edscan[] = "invalid dir scan offset";
+char Esrch[] = "key not found";
+char Efsrch[] = "directory entry not found";
char Eexist[] = "create/wstat -- file exists";
char Emode[] = "open/create -- unknown mode";
char Efull[] = "file system full";
--- a/fs.c
+++ b/fs.c
@@ -320,7 +320,7 @@
e = lookup(f->mnt, &k, &kv, kvbuf, sizeof(kvbuf));
if(e != nil){
- if(e != Eexist){
+ if(e != Esrch){
werrstr(e);
return -1;
}
@@ -369,7 +369,7 @@
memcpy(b->buf, t->buf, Blksz);
freeblk(f->mnt->root, t);
dropblk(t);
- }else if(e != Eexist){
+ }else if(e != Esrch){
werrstr("%s", e);
return -1;
}
@@ -411,6 +411,7 @@
goto Out;
de->Xdir = *d;
de->ref = 1;
+ de->up = pqid;
de->qid = d->qid;
de->length = d->length;
@@ -528,13 +529,13 @@
Conn *c;
for(c = fs->conns; c != nil; c = c->next){
- fprint(fd, "fids:%d\n", c->rfd);
+ fprint(fd, "fids:\n");
for(i = 0; i < Nfidtab; i++){
lock(&c->fidtablk[i]);
for(f = c->fidtab[i]; f != nil; f = f->next){
rlock(f->dent);
- fprint(fd, "\tfid[%d]: %d [refs=%ld, k=%K, qid=%Q]\n",
- i, f->fid, f->dent->ref, &f->dent->Key, f->dent->qid);
+ fprint(fd, "\tfid[%d] from %#zx: %d [refs=%ld, k=%K, qid=%Q]\n",
+ i, getmalloctag(f), f->fid, f->dent->ref, &f->dent->Key, f->dent->qid);
runlock(f->dent);
}
unlock(&c->fidtablk[i]);
@@ -603,6 +604,7 @@
if(n->mnt != nil)
ainc(&n->mnt->ref);
ainc(&n->dent->ref);
+ setmalloctag(n, getcallerpc(&c));
return n;
}
@@ -1078,7 +1080,7 @@
name = m->wname[i];
if(d.qid.path == Qdump){
if((mnt = getmount(m->wname[i])) == nil){
- rerror(m, Eexist);
+ rerror(m, Efsrch);
putfid(o);
return;
}
@@ -1202,6 +1204,8 @@
char rnbuf[Kvmax], opbuf[Kvmax], upbuf[Upksz];
char *p, *e, strs[65535];
int op, nm, rename;
+ vlong oldlen;
+ Qid old;
Fcall r;
Dent *de;
Msg mb[3];
@@ -1254,6 +1258,10 @@
rerror(m, Ename);
goto Out;
}
+ if(walk1(f->mnt->root, f->dent->up, d.name, &old, &oldlen) == 0){
+ rerror(m, Eexist);
+ goto Out;
+ }
n.name = d.name;
}
}
@@ -1433,9 +1441,8 @@
free(f->scan);
f->scan = nil;
}
- unlock(f);
-
clunkfid(m->conn, f);
+ unlock(f);
r.type = Rclunk;
respond(m, &r);
putfid(f);
@@ -1470,7 +1477,7 @@
de = f->dent;
if(walk1(f->mnt->root, f->qpath, m->name, &old, &oldlen) == 0){
- rerror(m, Emode);
+ rerror(m, Eexist);
putfid(f);
return;
}
@@ -1477,8 +1484,8 @@
rlock(de);
if(fsaccess(f, de->mode, de->uid, de->gid, DMWRITE) == -1){
+ rerror(m, Eperm);
runlock(de);
- rerror(m, Eexist);
putfid(f);
return;
}
@@ -1677,15 +1684,17 @@
wlock(f->dent);
if(f->dent->gone){
rerror(m, Ephase);
- wunlock(f->dent);
+Disallow: wunlock(f->dent);
putfid(f);
return;
}
+ if(f->dent->mode & DMEXCL){
+ rerror(m, Elocked);
+ goto Disallow;
+ }
if(fsaccess(f, d.mode, d.uid, d.gid, mbits) == -1){
rerror(m, Eperm);
- wunlock(f->dent);
- putfid(f);
- return;
+ goto Disallow;
}
f->dent->length = d.length;
wunlock(f->dent);
--- a/tree.c
+++ b/tree.c
@@ -1320,7 +1320,7 @@
dropblk(b);
return Enomem;
}
- err = Eexist;
+ err = Esrch;
ok = 0;
p[0] = holdblk(b);
for(i = 1; i < h; i++){