]> git.lizzy.rs Git - plan9front.git/commitdiff
rio: properly handle follow up flushes (fixes unexpected reply tag)
authorcinap_lenrek <cinap_lenrek@gmx.de>
Fri, 1 Nov 2013 17:57:11 +0000 (18:57 +0100)
committercinap_lenrek <cinap_lenrek@gmx.de>
Fri, 1 Nov 2013 17:57:11 +0000 (18:57 +0100)
when multiple flushes are send, they need to be replied
in order. we ensure this by having the flush xfid taking
over the flushtag (synchronized with a new fs->csyncflush
channel) so the next flush will flush the previous flush.

sys/src/cmd/rio/dat.h
sys/src/cmd/rio/fsys.c
sys/src/cmd/rio/rio.c
sys/src/cmd/rio/xfid.c

index f4f7f4efaf35f13c5a818aa9d8c6e7ae6b95e695..dd7d560d530508bc2c0316329012b9de5a98adf8 100644 (file)
@@ -285,6 +285,7 @@ struct Filsys
                int             pid;
                char            *user;
                Channel *cxfidalloc;    /* chan(Xfid*) */
+               Channel *csyncflush;    /* chan(int) */
                Fid             *fids[Nhash];
 };
 
@@ -357,3 +358,4 @@ int         menuing;                /* menu action is pending; waiting for window to be indicated */
 int            snarfversion;   /* updated each time it is written */
 int            messagesize;            /* negotiated in 9P version setup */
 int            shiftdown;
+int            debug;
index f4fea77233ef913c04c9331d29a9e397d849952f..5e680ea85920152d5c1206caff833264120b812e 100644 (file)
@@ -18,10 +18,6 @@ char Eoffset[] = "illegal offset";
 
 int    messagesize = 8192+IOHDRSZ;     /* good start */
 
-enum{
-       DEBUG = 0
-};
-
 Dirtab dirtab[]=
 {
        { ".",                  QTDIR,  Qdir,                   0500|DMDIR },
@@ -142,6 +138,9 @@ filsysinit(Channel *cxfidalloc)
                close(fd);
        }
        fs->user = estrdup(buf);
+       fs->csyncflush = chancreate(sizeof(int), 0);
+       if(fs->csyncflush == nil)
+               error("chancreate syncflush");
        fs->cxfidalloc = cxfidalloc;
        pid = getpid();
 
@@ -210,7 +209,7 @@ filsysproc(void *arg)
                x->buf = buf;
                if(convM2S(buf, n, x) != n)
                        error("convert error in convM2S");
-               if(DEBUG)
+               if(debug)
                        fprint(2, "rio:<-%F\n", &x->Fcall);
                if(fcall[x->type] == nil)
                        x = filsysrespond(fs, x, &t, Ebadfcall);
@@ -266,7 +265,7 @@ filsysrespond(Filsys *fs, Xfid *x, Fcall *t, char *err)
                error("convert error in convS2M");
        if(write(fs->sfd, x->buf, n) != n)
                error("write error in respond");
-       if(DEBUG)
+       if(debug)
                fprint(2, "rio:->%F\n", t);
        free(x->buf);
        x->buf = nil;
@@ -307,14 +306,21 @@ filsysauth(Filsys *fs, Xfid *x, Fid*)
 {
        Fcall t;
 
-               return filsysrespond(fs, x, &t, "rio: authentication not required");
+       return filsysrespond(fs, x, &t, "rio: authentication not required");
 }
 
 static
 Xfid*
-filsysflush(Filsys*, Xfid *x, Fid*)
+filsysflush(Filsys *fs, Xfid *x, Fid*)
 {
        sendp(x->c, xfidflush);
+
+       /*
+        * flushes need to be replied in order. xfidflush() will
+        * awaken us when the flush has been queued.
+        */
+       recv(fs->csyncflush, nil);
+
        return nil;
 }
 
index c65af88919c28bde30566b3b30720cf72c35392d..e6537283fddb5602bb6ef99e4f773501cb4923d2 100644 (file)
@@ -156,6 +156,11 @@ threadmain(int argc, char *argv[])
        case 's':
                scrolling = TRUE;
                break;
+       case 'D':
+               debug++;
+               break;
+       default:
+               usage();
        }ARGEND
 
        if(getwd(buf, sizeof buf) == nil)
index b505b2f06343143772ce67aaf11f87676ddb48f5..662d686cfffe8aaa1bc3f368f61647e4e9d88639 100644 (file)
@@ -124,24 +124,44 @@ xfidflush(Xfid *x)
 
        for(xf=xfid; xf; xf=xf->next)
                if(xf->flushtag == x->oldtag){
-                       xf->flushtag = -1;
-                       xf->flushing = TRUE;
                        incref(xf);     /* to hold data structures up at tail of synchronization */
                        if(xf->ref == 1)
                                error("ref 1 in flush");
-                       if(canqlock(&xf->active)){
-                               qunlock(&xf->active);
-                               sendul(xf->flushc, 0);
-                       }else{
-                               qlock(&xf->active);     /* wait for him to finish */
-                               qunlock(&xf->active);
-                       }
-                       xf->flushing = FALSE;
-                       if(decref(xf) == 0)
-                               sendp(cxfidfree, xf);
+                       /* take over flushtag so follow up flushes wait for us */
+                       x->flushtag = x->oldtag;
+                       xf->flushtag = -1;
                        break;
                }
+
+       /*
+        * wakeup filsysflush() in the filsysproc so the next
+        * flush can come in.
+        */
+       sendul(x->fs->csyncflush, 0);
+
+       if(xf){
+               qlock(&xf->active);
+               if(xf->buf){    /* not responded yet? */
+                       xf->flushing = TRUE;
+                       qunlock(&xf->active);
+                       sendul(xf->flushc, 0);
+                       xf->flushing = FALSE;
+               }else{
+                       qunlock(&xf->active);
+               }
+               if(decref(xf) == 0)
+                       sendp(cxfidfree, xf);
+       }
+
+       qlock(&x->active);
+       if(x->flushing){
+               qunlock(&x->active);
+               recv(x->flushc, nil);   /* wakeup flushing xfid */
+               filsyscancel(x);
+               return;
+       }
        filsysrespond(x->fs, x, &t, nil);
+       qunlock(&x->active);
 }
 
 void