ref: 54309f1cb25e5a65b834dab0e5ff711be3d812d1
parent: b8f1f88fffecf73c5ab9a4e2717e42bc3d445ca3
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Apr 28 01:59:10 EDT 2014
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.
--- a/sys/src/9/port/chan.c
+++ b/sys/src/9/port/chan.c
@@ -225,20 +225,19 @@
lock(&chanalloc);
c = chanalloc.free;
- if(c != 0){+ if(c != nil){chanalloc.free = c->next;
- c->next = 0;
- }
- unlock(&chanalloc);
-
- if(c == nil){+ c->next = nil;
+ } else {+ unlock(&chanalloc);
c = smalloc(sizeof(Chan));
lock(&chanalloc);
- c->fid = ++chanalloc.fid;
c->link = chanalloc.list;
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,
close calls rootclose, a nop */
--- a/sys/src/9/port/devmnt.c
+++ b/sys/src/9/port/devmnt.c
@@ -777,6 +777,13 @@
if(m->rip == up)
mntgate(m);
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);
nexterror();
}
--
⑨