devmnt: abandon fid on botched Tclunk or Tremove

if theres an error transmitting a Tclunk or Tremove request,
we cannot assume the fid to be clunked. in case this was
a transient error, reusing the fid on further requests
will fail.

as a work arround, we zero the channels fid and allocate
a new fid before the chan is reused.

this is not correct as we essentially leak the fid
on the fileserver, but we will still be able to use
the mount.
front
cinap_lenrek 2014-04-28 05:59:10 +02:00
parent 219c312163
commit 2c2a71cd51
2 changed files with 14 additions and 8 deletions

View File

@ -225,20 +225,19 @@ newchan(void)
lock(&chanalloc); lock(&chanalloc);
c = chanalloc.free; c = chanalloc.free;
if(c != 0){ if(c != nil){
chanalloc.free = c->next; chanalloc.free = c->next;
c->next = 0; c->next = nil;
} } else {
unlock(&chanalloc); unlock(&chanalloc);
if(c == nil){
c = smalloc(sizeof(Chan)); c = smalloc(sizeof(Chan));
lock(&chanalloc); lock(&chanalloc);
c->fid = ++chanalloc.fid;
c->link = chanalloc.list; c->link = chanalloc.list;
chanalloc.list = c; chanalloc.list = c;
unlock(&chanalloc);
} }
if(c->fid == 0)
c->fid = ++chanalloc.fid;
unlock(&chanalloc);
/* if you get an error before associating with a dev, /* if you get an error before associating with a dev,
close calls rootclose, a nop */ close calls rootclose, a nop */

View File

@ -777,6 +777,13 @@ mountio(Mnt *m, Mntrpc *r)
if(m->rip == up) if(m->rip == up)
mntgate(m); mntgate(m);
if(strcmp(up->errstr, Eintr) != 0){ if(strcmp(up->errstr, Eintr) != 0){
switch(r->request.type){
case Tremove:
case Tclunk:
/* botch, abandon fid */
if(strcmp(up->errstr, Ehungup) != 0)
r->c->fid = 0;
}
mntflushfree(m, r); mntflushfree(m, r);
nexterror(); nexterror();
} }