The extra tracking that has been proposed is unnecessary,
and waiting for the Rflush doesn't make sense.  The assumption
is that the Rflush isn't ever going to arrive, because the connection
is dead.

The problem is here:

void
mountio(Mnt *m, Mntrpc *r)
{
        int n;

        while(waserror()) {
                if(m->rip == up)
                        mntgate(m);
                if(strcmp(up->errstr, Eintr) != 0){
                        mntflushfree(m, r);    <<<<
                        nexterror();
                }
                r = mntflushalloc(r, m->msize);
        }

The implicit assumption is that if reading from the mounted
connection gets any error other than Eintr, the connection
is dead and will never receive another message.  The call to
mntflushfree cleanly tears down the messages this proc
is waiting for by behaving as if the flush responses had come
back in.

In 9vx, the problem is that the errstr is "Interrupted system call"
(the Unix string for errno EINTR) instead of Eintr == "interrupted".
The fix is to correct whatever has translated EINTR to
"Interrupted system call" to use the correct string.
Drawterm probably has the same issue and the same fix.
There are fewer interrupts flying around in drawterm.

The kernel may even have the same issue, if a mounted
connection can get an error (other than "interrupted")
out of read or write but then work at the next call.
A way to avoid this problem in the future is to mark the
mnt (m) as dead, so that no other procs will try to read
from the connection and get confused.

Russ

Reply via email to