~kvik/unionfs

c1eed337afadb15156a5364767c3e3755586e537 — kvik 3 years ago ee1d115
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.
2 files changed, 57 insertions(+), 6 deletions(-)

M unionfs.c
M unionfs.h
M unionfs.c => unionfs.c +54 -6
@@ 83,6 83,16 @@ dircopy(Dir *a, Dir *b)
	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 @@ fsopen(Req *r)
	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 @@ fsopen(Req *r)
		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 @@ fsread(Req *r)
	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 @@ fsread(Req *r)
			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,13 314,38 @@ fswrite(Req *r)
	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


@@ 505,6 552,7 @@ main(int argc, char *argv[])
	thefs.write = fswrite;
	thefs.stat = fsstat;
	thefs.wstat = fswstat;
	thefs.flush = fsflush;
	thefs.destroyfid = destroyfid;
	if(stdio == 0){
		postmountsrv(&thefs, srvname, mountat, mflag);

M unionfs.h => unionfs.h +3 -0
@@ 23,6 23,9 @@ struct FILE {
	int fd;
	Mtpt *mtpt;
	Dirlist *dl;
	
	int pid;
	int flushed;
};

struct Mtpt {