ref: 856c1dd4e268797581995d9addc0aa3c939e100a
parent: a289e5c5a595ae8e3283c1b5a616fcc5068715a4
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Apr 27 23:12:49 EDT 2023
fs: handle deletion via different fids phase errors are your friends.
--- a/dat.h
+++ b/dat.h
@@ -543,6 +543,7 @@
Xdir;
Dent *next;
long ref;
+ char gone;
char buf[Maxent];
};
--- a/fs.c
+++ b/fs.c
@@ -1134,6 +1134,10 @@
}
de = f->dent;
wlock(de);
+ if(de->gone){
+ rerror(m, Ephase);
+ goto Out;
+ }
if((de->qid.type & QTAUTH) || (de->qid.path & Qdump)){
rerror(m, Emode);
goto Out;
@@ -1278,7 +1282,7 @@
/* update directory entry */
nm = 0;
- if(rename){
+ if(rename && !de->gone){
mb[nm].op = Odelete;
mb[nm].Key = de->Key;
mb[nm].v = nil;
@@ -1451,6 +1455,7 @@
f->qpath = d.qid.path;
f->dent = de;
wlock(de);
+ de->gone = 0;
if((e = clearb(f, 0, de->length)) != nil){
unlock(f);
clunkdent(de);
@@ -1504,7 +1509,11 @@
}
clunkfid(m->conn, f);
- rlock(f->dent);
+ wlock(f->dent);
+ if(f->dent->gone){
+ e = Ephase;
+ goto Error;
+ }
if((e = candelete(f)) != nil)
goto Error;
if(fsaccess(f, f->dmode, f->duid, f->dgid, DMWRITE) == -1){
@@ -1515,6 +1524,7 @@
mb.k = f->dent->k;
mb.nk = f->dent->nk;
mb.nv = 0;
+
if((e = upsert(f->mnt, &mb, 1)) != nil)
goto Error;
if(f->dent->qid.type == QTFILE){
@@ -1522,8 +1532,9 @@
if(e != nil)
goto Error;
}
+ f->dent->gone = 1;
+ wunlock(f->dent);
- runlock(f->dent);
r.type = Rremove;
respond(m, &r);
putfid(f);
@@ -1530,7 +1541,7 @@
return;
Error:
- runlock(f->dent);
+ wunlock(f->dent);
rerror(m, e);
putfid(f);
}
@@ -1566,12 +1577,19 @@
return;
}
}
+ wlock(f->dent);
+ if(f->dent->gone){
+ rerror(m, Ephase);
+ wunlock(f->dent);
+ putfid(f);
+ return;
+ }
if(fsaccess(f, d.mode, d.uid, d.gid, mbits) == -1){
rerror(m, Eperm);
+ wunlock(f->dent);
putfid(f);
return;
}
- wlock(f->dent);
f->dent->length = d.length;
wunlock(f->dent);
r.type = Ropen;
@@ -1887,6 +1905,13 @@
putfid(f);
return;
}
+ wlock(f->dent);
+ if(f->dent->gone){
+ rerror(m, Ephase);
+ wunlock(f->dent);
+ putfid(f);
+ return;
+ }
if(f->dent->qid.type == QTAUTH){
e = writeauth(m, f, &r);
if(e != nil)
@@ -1893,11 +1918,11 @@
rerror(m, e);
else
respond(m, &r);
+ wunlock(f->dent);
putfid(f);
return;
}
- wlock(f->dent);
w = 0;
p = m->data;
o = m->offset;