Get rid of the 'mount read: i/o on hungup channel' errors when unmounting some common file servers Reference: /n/sources/patch/sorry/grumble-on-dismount Date: Wed Feb 23 16:47:45 CET 2005 --- /sys/src/cmd/ramfs.c Wed Feb 23 16:46:10 2005 +++ /sys/src/cmd/ramfs.c Wed Feb 23 16:46:06 2005 @@ -745,7 +745,7 @@ void io(void) { - char *err, buf[20]; + char *err, buf[40]; int n, pid, ctl; pid = getpid(); @@ -771,6 +771,12 @@ * so we wait for the error. */ n = read9pmsg(mfd[0], mdata, messagesize); + if(n < 0){ + errstr(buf, sizeof buf); + if (buf[0]=='\0' || strncmp(buf, "i/o on hungup channel", 22)==0) + exits(""); + error("mount read"); + } if(n < 0) error("mount read"); if(n == 0) --- /sys/src/cmd/ip/ftpfs/ftpfs.c Wed Feb 23 16:46:22 2005 +++ /sys/src/cmd/ip/ftpfs/ftpfs.c Wed Feb 23 16:46:19 2005 @@ -247,15 +247,19 @@ void io(void) { - char *err; + char *err, buf[ERRMAX]; int n; kapid = kaproc(); while(!dying){ n = read9pmsg(mfd, mdata, messagesize); - if(n <= 0) - fatal("mount read"); + if(n <= 0){ + errstr(buf, sizeof buf); + if (buf[0]=='\0' || strncmp(buf, "i/o on hungup channel", 22)==0) + exits(""); + fatal("mount read: %s\n", buf); + } if(convM2S(mdata, n, &thdr) == 0) continue; --- /sys/src/cmd/tapefs/fs.c Wed Feb 23 16:46:40 2005 +++ /sys/src/cmd/tapefs/fs.c Wed Feb 23 16:46:37 2005 @@ -18,6 +18,7 @@ int replete; int verbose; int newtap; /* tap with time in sec */ +uchar statbuf[STATMAX]; Fid * newfid(int); int ramstat(Ram*, uchar*, int); @@ -301,8 +302,11 @@ thdr.qid = r->qid; return 0; } - if(mode & ORCLOSE) - return Eperm; + if(mode & ORCLOSE){ + if(r->qid.path==0) + return Eperm; + f->rclose = 1; + } trunc = mode & OTRUNC; mode &= OPERM; if(mode==OWRITE || mode==ORDWR || trunc) @@ -416,14 +420,16 @@ f->busy = 0; f->open = 0; f->ram = 0; - return 0; + return nil; } char * rremove(Fid *f) { - USED(f); - return Eperm; + if(f->ram->qid.path == 0) + return Eperm; + f->ram->busy = 0; + return nil; } char * @@ -435,12 +441,56 @@ return 0; } +static Ram * +firstent(Ram *r) +{ + Ram *s, *t; + for(s = r->parent; s; s = s->next) + if (s->child) + for (t = s->child; t; t = t->next) + if (t == r) + return s->child; + sysfatal("firstent: internal error - can't ever happen\n"); + return nil; +} + char * rwstat(Fid *f) { + Ram *r, *s; + Dir dir; + if(f->ram->busy == 0) return Enotexist; - return Eperm; + + convM2D(rhdr.stat, rhdr.nstat, &dir, (char*)statbuf); + r = f->ram; + + if(dir.length!=~0 && dir.length!=r->ndata) + return Eperm; + + if (dir.name[0] != '\0' && strcmp(dir.name, r->name) != 0) + for(s = firstent(f->ram); s; s = s->next) + if(s->busy && strcmp(dir.name, s->name)==0) + return Eexist; + + + /* all valid, now do it */ + + if(dir.mode != ~0){ + dir.mode &= ~DMDIR; /* cannot change dir bit */ + dir.mode |= r->perm&DMDIR; + r->perm = dir.mode; + } + if(dir.name[0] != '\0'){ + free(r->name); + r->name = estrdup(dir.name); + } + if(dir.uid[0] != '\0') + r->user = estrdup(dir.uid); + if(dir.gid[0] != '\0') + r->group = estrdup(dir.gid); + return 0; } int @@ -541,7 +591,7 @@ if(write(mfd[1], mdata, n) != n) error("mount write"); } - if (buf[0]=='\0' || strncmp(buf, "write to hung", 13)==0) + if (buf[0]=='\0' || strncmp(buf, "i/o on hungup channel", 22)==0) exits(""); fprint(2, "%s: mount read: %s\n", argv0, buf); exits(buf);