Ejemplo n.º 1
0
void
ixp_srv_walkandclone(Ixp9Req *req, IxpLookupFn lookup) {
	IxpFileId *file, *tfile;
	int i;

	file = ixp_srv_clonefiles(req->fid->aux);
	for(i=0; i < req->ifcall.twalk.nwname; i++) {
		if(!strcmp(req->ifcall.twalk.wname[i], "..")) {
			if(file->next) {
				tfile = file;
				file = file->next;
				ixp_srv_freefile(tfile);
			}
		}else{
			tfile = lookup(file, req->ifcall.twalk.wname[i]);
			if(!tfile)
				break;
			assert(!tfile->next);
			if(strcmp(req->ifcall.twalk.wname[i], ".")) {
				tfile->next = file;
				file = tfile;
			}
		}
		req->ofcall.rwalk.wqid[i].type = file->tab.qtype;
		req->ofcall.rwalk.wqid[i].path = QID(file->tab.type, file->id);
	}
	/* There should be a way to do this on freefid() */
	if(i < req->ifcall.twalk.nwname) {
		while((tfile = file)) {
			file=file->next;
			ixp_srv_freefile(tfile);
		}
		ixp_respond(req, Enofile);
		return;
	}
	/* Remove refs for req->fid if no new fid */
	if(req->ifcall.hdr.fid == req->ifcall.twalk.newfid) {
		tfile = req->fid->aux;
		req->fid->aux = file;
		while((file = tfile)) {
			tfile = tfile->next;
			ixp_srv_freefile(file);
		}
	}else
		req->newfid->aux = file;
	req->ofcall.rwalk.nwqid = i;
	ixp_respond(req, nil);
}
Ejemplo n.º 2
0
void
ixp_pending_respond(Ixp9Req *req) {
	IxpFileId *file;
	IxpPendingLink *p;
	IxpRequestLink *req_link;
	IxpQueue *queue;

	file = req->fid->aux;
	assert(file->pending);
	p = file->p;
	if(p->queue) {
		queue = p->queue;
		p->queue = queue->link;
		req->ofcall.io.data = queue->dat;
		req->ofcall.io.count = queue->len;
		if(req->aux) {
			req_link = req->aux;
			req_link->next->prev = req_link->prev;
			req_link->prev->next = req_link->next;
			free(req_link);
		}
		ixp_respond(req, nil);
		free(queue);
	}else {
		req_link = emallocz(sizeof *req_link);
		req_link->req = req;
		req_link->next = &p->pending->req;
		req_link->prev = req_link->next->prev;
		req_link->next->prev = req_link;
		req_link->prev->next = req_link;
		req->aux = req_link;
	}
}
Ejemplo n.º 3
0
bool
ixp_pending_clunk(Ixp9Req *req) {
	IxpPending *pending;
	IxpPendingLink *pend_link;
	IxpRequestLink *req_link;
	Ixp9Req *r;
	IxpFileId *file;
	IxpQueue *queue;
	bool more;

	file = req->fid->aux;
	pend_link = file->p;

	pending = pend_link->pending;
	for(req_link=pending->req.next; req_link != &pending->req;) {
		r = req_link->req;
		req_link = req_link->next;
		if(r->fid == pend_link->fid) {
			pending_flush(r);
			ixp_respond(r, "interrupted");
		}
	}

	pend_link->prev->next = pend_link->next;
	pend_link->next->prev = pend_link->prev;

	while((queue = pend_link->queue)) {
		pend_link->queue = queue->link;
		free(queue->dat);
		free(queue);
	}
	more = (pend_link->pending->fids.next == &pend_link->pending->fids);
	free(pend_link);
	ixp_respond(req, nil);
	return more;
}
Ejemplo n.º 4
0
Archivo: ops.c Proyecto: pfpacket/unpfs
static void
respond(Ixp9Req *r, int err)
{
    const char *msg = NULL;
    static char buf[ERRNO_MSG_BUF_LENGTH];

    if (err) {
        if (strerror_r(err, buf, sizeof buf) < 0)
            msg = "Input/output error";
        else
            msg = buf;

        unpfs_log(LOG_ERR, "respond: type=%u tag=%u fid=%u: %s\n",
            r->ifcall.hdr.type,
            r->ifcall.hdr.tag,
            r->ifcall.hdr.fid, msg);
    }

    ixp_respond(r, msg);
}
Ejemplo n.º 5
0
void
ixp_srv_readdir(Ixp9Req *req, IxpLookupFn lookup, void (*dostat)(IxpStat*, IxpFileId*)) {
	IxpMsg msg;
	IxpFileId *file, *tfile;
	IxpStat stat;
	char *buf;
	ulong size, n;
	uint64_t offset;

	file = req->fid->aux;

	size = req->ifcall.io.count;
	if(size > req->fid->iounit)
		size = req->fid->iounit;
	buf = emallocz(size);
	msg = ixp_message(buf, size, MsgPack);

	file = lookup(file, nil);
	tfile = file;
	/* Note: The first file is ".", so we skip it. */
	offset = 0;
	for(file=file->next; file; file=file->next) {
		dostat(&stat, file);
		n = ixp_sizeof_stat(&stat);
		if(offset >= req->ifcall.io.offset) {
			if(size < n)
				break;
			ixp_pstat(&msg, &stat);
			size -= n;
		}
		offset += n;
	}
	while((file = tfile)) {
		tfile=tfile->next;
		ixp_srv_freefile(file);
	}
	req->ofcall.io.count = msg.pos - msg.data;
	req->ofcall.io.data = msg.data;
	ixp_respond(req, nil);
}