ref: c1eed337afadb15156a5364767c3e3755586e537
parent: ee1d11532120bbac4e12e0fed95cf2c1b69bff81
author: kvik <kvik@a-b.xyz>
date: Thu Aug 5 14:01:43 EDT 2021
Implement Tflush handling This patch implements Tflush message handling for Topen, Tread, and Twrite requests. These are the most common things you'd happen to flush, but it's worth noting that unionfs, being a proxying server, does potentially blocking system calls while handling most of the requests. At some point I'll add that, perhaps when I figure out some more imaginative way of doing it.
--- a/unionfs.c
+++ b/unionfs.c
@@ -83,6 +83,16 @@
a->muid = estrdup(b->muid);
}
+int
+catchflush(void*, char *note)
+{
+ if(strcmp(note, "flush") == 0){
+ atnotify(catchflush, 0);
+ return 1;
+ }
+ return 0;
+}
+
void
fsattach(Req *r)
{
@@ -186,6 +196,8 @@
R = &r->ofcall;
f = r->fid->aux;
+ f->pid = getpid();
+ atnotify(catchflush, 1);
srvrelease(&thefs);
if(f->mode & DMDIR){
f->mtpt = mtptgrab();
@@ -208,12 +220,16 @@
if((f->fd = open(s_to_c(f->realpath), T->mode)) == -1)
goto error;
R->iounit = iounit(f->fd);
- respond(r, nil);
+ if(f->flushed == 0)
+ respond(r, nil);
srvacquire(&thefs);
+ atnotify(catchflush, 0);
return;
error:
- responderror(r);
+ if(f->flushed == 0)
+ responderror(r);
srvacquire(&thefs);
+ atnotify(catchflush, 0);
}
void
@@ -257,6 +273,8 @@
R = &r->ofcall;
f = r->fid->aux;
+ f->pid = getpid();
+ atnotify(catchflush, 1);
srvrelease(&thefs);
if(f->mode&DMDIR){
if(T->offset == 0){
@@ -273,12 +291,16 @@
goto error;
r->ofcall.count = n;
}
- respond(r, nil);
+ if(f->flushed == 0)
+ respond(r, nil);
srvacquire(&thefs);
+ atnotify(catchflush, 0);
return;
error:
- responderror(r);
+ if(f->flushed == 0)
+ responderror(r);
srvacquire(&thefs);
+ atnotify(catchflush, 0);
}
void
@@ -292,15 +314,40 @@
f = r->fid->aux;
srvrelease(&thefs);
+ atnotify(catchflush, 1);
if((R->count = pwrite(f->fd, T->data, T->count, T->offset)) != T->count){
- responderror(r);
+ if(f->flushed == 0)
+ responderror(r);
goto done;
}
- respond(r, nil);
+ if(f->flushed == 0)
+ respond(r, nil);
done:
srvacquire(&thefs);
+ atnotify(catchflush, 0);
}
+void
+fsflush(Req *r)
+{
+ FILE *f = r->oldreq->fid->aux;
+
+ if(f->pid == 0){
+ respond(r, nil);
+ return;
+ }
+ switch(r->oldreq->type){
+ case Topen:
+ case Tread:
+ case Twrite:
+ f->flushed = 1;
+ while(postnote(PNPROC, f->pid, "flush") != 0)
+ sleep(100);
+ respond(r->oldreq, "interrupted");
+ }
+ respond(r, nil);
+}
+
int
mkdirp(char *path)
{
@@ -505,6 +552,7 @@
thefs.write = fswrite;
thefs.stat = fsstat;
thefs.wstat = fswstat;
+ thefs.flush = fsflush;
thefs.destroyfid = destroyfid;
if(stdio == 0){
postmountsrv(&thefs, srvname, mountat, mflag);
--- a/unionfs.h
+++ b/unionfs.h
@@ -23,6 +23,9 @@
int fd;
Mtpt *mtpt;
Dirlist *dl;
+
+ int pid;
+ int flushed;
};
struct Mtpt {