Esempio n. 1
0
static char *
logspace(LogfsServer *server, int active, int takearisk, int nbytes, uchar **where, u32int *flashaddr)
{
	char *errmsg;
	LogfsLowLevel *ll = server->ll;
	int pagesize = 1 << ll->l2pagesize;
	LogSegment *seg;

	if(nbytes > pagesize)
		return logfselogmsgtoobig;
retry:
	seg = active ? server->activelog : server->sweptlog;
	for(;;) {
//print("curpage %d nbytes %d\n", seg->curpage, seg->nbytes);
		if(seg->curpage >= 0) {
			if(seg->nbytes + nbytes < pagesize)
				break;
			errmsg = logfslogsegmentflush(server, active);
			if(errmsg)
				return errmsg;
		}
		if(seg->curpage < 0) {
			long block;
			long path;
			block = logfsfindfreeblock(ll,
				active ? (takearisk ? AllocReasonLogExtend : AllocReasonDataExtend) : AllocReasonTransfer);
			if(block < 0) {
				if(active) {
					int didsomething;
					errmsg = logfsserverlogsweep(server, 0, &didsomething);
					if(errmsg)
						return errmsg;
					if(didsomething)
						goto retry;
				}
				return logfselogfull;
			}
			seg->blockmap[++seg->curblockindex] = block;
			path = mklogpath(seg->curblockindex, seg->gen, 0);
			(*ll->setblocktag)(ll, block, LogfsTlog);
			(*ll->setblockpath)(ll, block, path);
			seg->curpage = 0;
#ifdef FUTURE
			/* TODO - do we need one of these if the underlying system supports erase counting? */
			seg->pagebuf[0] = LogfsLogTstart;
			PBIT16(seg->pagebuf + 1, 8);
			PBIT32(seg->pagebuf + 3, path);	/* TODO duplicate information */
			PBIT32(seg->pagebuf + 7, 0);		/* TODO don't have this - discuss with forsyth */
			seg->nbytes = 11;
#else
			seg->nbytes = 0;
#endif
		}
	}
	*where = seg->pagebuf + seg->nbytes;
	if(flashaddr)
		*flashaddr = logfsspo2flashaddr(server, seg->curblockindex, seg->curpage, seg->nbytes);
	seg->nbytes += nbytes;
	return nil;
}
Esempio n. 2
0
static void
packoldstat(uchar *buf, Dir *d)
{
	uchar *p;
	ulong q;

	/* lay down old stat buffer - grotty code but it's temporary */
	p = buf;
	strncpy((char*)p, d->name, 28);
	p += 28;
	strncpy((char*)p, d->uid, 28);
	p += 28;
	strncpy((char*)p, d->gid, 28);
	p += 28;
	q = d->qid.path & ~DMDIR;	/* make sure doesn't accidentally look like directory */
	if(d->qid.type & QTDIR)	/* this is the real test of a new directory */
		q |= DMDIR;
	PBIT32(p, q);
	p += BIT32SZ;
	PBIT32(p, d->qid.vers);
	p += BIT32SZ;
	PBIT32(p, d->mode);
	p += BIT32SZ;
	PBIT32(p, d->atime);
	p += BIT32SZ;
	PBIT32(p, d->mtime);
	p += BIT32SZ;
	PBIT64(p, d->length);
	p += BIT64SZ;
	PBIT16(p, d->type);
	p += BIT16SZ;
	PBIT16(p, d->dev);
}
Esempio n. 3
0
int
xopenfd(Msg *m)
{
	char errs[ERRMAX];
	int n, p[2];
	Conn *nc;

	if(pipe(p) < 0){
		rerrstr(errs, sizeof errs);
		err(m, errs);
		/* XXX return here? */
	}
	if(verbose) fprint(2, "%T xopen pipe %d %d...", p[0], p[1]);

	/* now we're committed. */

	/* a new connection for this fid */
	nc = emalloc(sizeof(Conn));
	nc->internal = chancreate(sizeof(void*), 0);

	/* a ref for us */
	nc->fdfid = m->fid;
	m->fid->ref++;
	nc->fdfid->openfd++;
	nc->fdmode = m->tx.mode;
	nc->fd = p[0];

	/* a thread to tend the pipe */
	threadcreate(openfdthread, nc, STACK);

	/* if mode is ORDWR, that openfdthread will write; start a reader */
	if((m->tx.mode&3) == ORDWR){
		nc = emalloc(sizeof(Conn));
		nc->internal = chancreate(sizeof(void*), 0);
		nc->fdfid = m->fid;
		m->fid->ref++;
		nc->fdfid->openfd++;
		nc->fdmode = OREAD;
		nc->fd = dup(p[0], -1);
		threadcreate(openfdthread, nc, STACK);
	}

	/* steal fid from other connection */
	if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0)
		fidput(m->fid);

	/* rewrite as Ropenfd */
	m->rx.type = Ropenfd;
	n = GBIT32(m->rpkt);
	m->rpkt = erealloc(m->rpkt, n+4);
	PBIT32(m->rpkt+n, p[1]);
	n += 4;
	PBIT32(m->rpkt, n);
	m->rpkt[4] = Ropenfd;
	m->rx.unixfd = p[1];
	return 0;
}
Esempio n. 4
0
uchar*
read9ppkt(Ioproc *io, int fd)
{
	uchar buf[4], *pkt;
	int n, nn;

	n = ioreadn(io, fd, buf, 4);
	if(n != 4)
		return nil;
	n = GBIT32(buf);
	if(n > MAXMSGSIZE)
		return nil;
	pkt = emalloc(n);
	PBIT32(pkt, n);
	nn = ioreadn(io, fd, pkt+4, n-4);
	if(nn != n-4){
		free(pkt);
		return nil;
	}
/* would do this if we ever got one of these, but we only generate them
	if(pkt[4] == Ropenfd){
		newfd = iorecvfd(io, fd);
		PBIT32(pkt+n-4, newfd);
	}
*/
	return pkt;
}
Esempio n. 5
0
File: convS2M.c Progetto: 8l/inferno
static
uchar*
pqid(uchar *p, Qid *q)
{
	PBIT8(p, q->type);
	p += BIT8SZ;
	PBIT32(p, q->vers);
	p += BIT32SZ;
	PBIT64(p, q->path);
	p += BIT64SZ;
	return p;
}
Esempio n. 6
0
u32int
logfsflattenentry(LogfsIdentityStore *is, uchar *buf, u32int limit, Entry *e)
{
	int unamelen, gnamelen, munamelen, namelen;
	uint len;
	uchar *p;
	int unamebad = 0, gnamebad = 0, munamebad = 0;
	char *uname, *gname, *muname;

	id2name(is, e->uid, &uname, &unamebad, &unamelen);
	id2name(is, e->gid, &gname, &gnamebad, &gnamelen);
	id2name(is, e->muid, &muname, &munamebad, &munamelen);
	namelen = strlen(e->name);
	len = 49 + unamelen + unamebad + gnamelen + gnamebad + munamelen + munamebad + namelen;
	if(buf == nil)
		return len;
	if(len > limit)
		return 0;
	p = buf;
	/* size */		PBIT16(p, len - BIT16SZ); p += BIT16SZ;
	/* type */		p += BIT16SZ;
	/* dev */		p += BIT32SZ;
	/* qid.type */	*p++ = e->qid.type;
	/* qid.vers */	PBIT32(p, e->qid.vers); p += BIT32SZ;
	/* qid.path */	PBIT64(p, e->qid.path); p+= 8;
	/* mode */	PBIT32(p, e->perm); p+= BIT32SZ;
	/* atime */	PBIT32(p, e->mtime); p+= BIT32SZ;
	/* mtime */	PBIT32(p, e->mtime); p+= BIT32SZ;
	/* length */	if(e->qid.type & QTDIR) {
					PBIT64(p, 0);
					p += 8;
				}
				else {
					PBIT32(p, e->u.file.length); p += BIT32SZ;
					PBIT32(p, 0); p += BIT32SZ;
				}
	/* name */	PBIT16(p, namelen); p += BIT16SZ; memmove(p, e->name, namelen); p+= namelen;
	/* uid */		PBIT16(p, unamelen + unamebad); p += BIT16SZ;
				if(unamebad)
					*p++ = '(';
				memmove(p, uname, unamelen + unamebad); p+= unamelen;
				if(unamebad)
					*p++ = ')';
	/* gid */		PBIT16(p, gnamelen + gnamebad); p += BIT16SZ;
				if(gnamebad)
					*p++ = '(';
				memmove(p, gname, gnamelen); p+= gnamelen;
				if(gnamebad)
					*p++ = ')';
	/* muid */	PBIT16(p, munamelen + munamebad); p += BIT16SZ;
				if(munamebad)
					*p++ = '(';
				memmove(p, muname, munamelen); p+= munamelen;
				if(munamebad)
					*p = ')';
//print("len %ud p - buf %ld\n", len, p - buf);
	return len;
}
Esempio n. 7
0
void
rewritehdr(Fcall *f, uchar *pkt)
{
	int i, n;

	n = GBIT32(pkt);
	PBIT16(pkt+5, f->tag);
	switch(f->type){
	case Tversion:
	case Rversion:
		restring(pkt, n, f->version);
		break;
	case Tauth:
		PBIT32(pkt+7, f->afid);
		restring(pkt, n, f->uname);
		restring(pkt, n, f->aname);
		break;
	case Tflush:
		PBIT16(pkt+7, f->oldtag);
		break;
	case Tattach:
		restring(pkt, n, f->uname);
		restring(pkt, n, f->aname);
		PBIT32(pkt+7, f->fid);
		PBIT32(pkt+11, f->afid);
		break;
	case Twalk:
		PBIT32(pkt+7, f->fid);
		PBIT32(pkt+11, f->newfid);
		for(i=0; i<f->nwname; i++)
			restring(pkt, n, f->wname[i]);
		break;
	case Tcreate:
		restring(pkt, n, f->name);
		/* fall through */
	case Topen:
	case Tclunk:
	case Tremove:
	case Tstat:
	case Twstat:
	case Twrite:
		PBIT32(pkt+7, f->fid);
		break;
	case Tread:
		PBIT32(pkt+7, f->fid);
		PBIT64(pkt+11, f->offset);
		break;
	case Rerror:
		restring(pkt, n, f->ename);
		break;
	}
}
Esempio n. 8
0
static int
pcicfgrw(Pcidev *pcidev, int rno, int data, int len, int read)
{
	uchar buf[4];

	if(read){
		memset(buf, 0, sizeof(buf));
		if(pread(pcidev->rawfd, buf, len, rno) != len)
			return -1;
		switch(len){
		case 1:
			return GBIT8(buf);
		case 2:
			return GBIT16(buf);
		case 4:
			return GBIT32(buf);
		default:
			abort();
		}
	} else {
		switch(len){
		case 1:
			PBIT8(buf, data);
			break;
		case 2:
			PBIT16(buf, data);
			break;
		case 4:
			PBIT32(buf, data);
			break;
		default:
			abort();
		}
		if(pwrite(pcidev->rawfd, buf, len, rno) != len)
			return -1;
	}
	return 0;
}
Esempio n. 9
0
uint
convD2M(Dir *d, uchar *buf, uint nbuf)
{
    uchar *p, *ebuf;
    char *sv[5];
    int i, ns, nsv[5], ss, nstr, fixlen;

    if(nbuf < BIT16SZ)
        return 0;

    p = buf;
    ebuf = buf + nbuf;

    sv[0] = d->name;
    sv[1] = d->uid;
    sv[2] = d->gid;
    sv[3] = d->muid;

    fixlen = STATFIXLEN;
    nstr = 4;

    ns = 0;
    for(i = 0; i < nstr; i++) {
        if(sv[i])
            nsv[i] = strlen(sv[i]);
        else
            nsv[i] = 0;
        ns += nsv[i];
    }

    ss = fixlen + ns;

    /* set size befor erroring, so user can know how much is needed */
    /* note that length excludes count field itself */
    PBIT16(p, ss-BIT16SZ);
    p += BIT16SZ;

    if(ss > nbuf)
        return BIT16SZ;

    PBIT16(p, d->type);
    p += BIT16SZ;
    PBIT32(p, d->dev);
    p += BIT32SZ;
    PBIT8(p, d->qid.type);
    p += BIT8SZ;
    PBIT32(p, d->qid.vers);
    p += BIT32SZ;
    PBIT64(p, d->qid.path);
    p += BIT64SZ;
    PBIT32(p, d->mode);
    p += BIT32SZ;
    PBIT32(p, d->atime);
    p += BIT32SZ;
    PBIT32(p, d->mtime);
    p += BIT32SZ;
    PBIT64(p, d->length);
    p += BIT64SZ;

    for(i = 0; i < nstr; i++) {
        ns = nsv[i];
        if(p + ns + BIT16SZ > ebuf)
            return 0;
        PBIT16(p, ns);
        p += BIT16SZ;
        if(ns)
            memmove(p, sv[i], ns);
        p += ns;
    }

    if(ss != p - buf)
        return 0;

    return p - buf;
}
Esempio n. 10
0
File: convS2M.c Progetto: 8l/inferno
uint
convS2M(Fcall *f, uchar *ap, uint nap)
{
	uchar *p;
	uint i, size;

	size = sizeS2M(f);
	if(size == 0)
		return 0;
	if(size > nap)
		return 0;

	p = (uchar*)ap;

	PBIT32(p, size);
	p += BIT32SZ;
	PBIT8(p, f->type);
	p += BIT8SZ;
	PBIT16(p, f->tag);
	p += BIT16SZ;

	switch(f->type)
	{
	default:
		return 0;

	case Tversion:
		PBIT32(p, f->msize);
		p += BIT32SZ;
		p = pstring(p, f->version);
		break;

	case Tflush:
		PBIT16(p, f->oldtag);
		p += BIT16SZ;
		break;

	case Tauth:
		PBIT32(p, f->afid);
		p += BIT32SZ;
		p  = pstring(p, f->uname);
		p  = pstring(p, f->aname);
		break;

	case Tattach:
		PBIT32(p, f->fid);
		p += BIT32SZ;
		PBIT32(p, f->afid);
		p += BIT32SZ;
		p  = pstring(p, f->uname);
		p  = pstring(p, f->aname);
		break;

	case Twalk:
		PBIT32(p, f->fid);
		p += BIT32SZ;
		PBIT32(p, f->newfid);
		p += BIT32SZ;
		PBIT16(p, f->nwname);
		p += BIT16SZ;
		if(f->nwname > MAXWELEM)
			return 0;
		for(i=0; i<f->nwname; i++)
			p = pstring(p, f->wname[i]);
		break;

	case Topen:
		PBIT32(p, f->fid);
		p += BIT32SZ;
		PBIT8(p, f->mode);
		p += BIT8SZ;
		break;

	case Tcreate:
		PBIT32(p, f->fid);
		p += BIT32SZ;
		p = pstring(p, f->name);
		PBIT32(p, f->perm);
		p += BIT32SZ;
		PBIT8(p, f->mode);
		p += BIT8SZ;
		break;

	case Tread:
		PBIT32(p, f->fid);
		p += BIT32SZ;
		PBIT64(p, f->offset);
		p += BIT64SZ;
		PBIT32(p, f->count);
		p += BIT32SZ;
		break;

	case Twrite:
		PBIT32(p, f->fid);
		p += BIT32SZ;
		PBIT64(p, f->offset);
		p += BIT64SZ;
		PBIT32(p, f->count);
		p += BIT32SZ;
		memmove(p, f->data, f->count);
		p += f->count;
		break;

	case Tclunk:
	case Tremove:
		PBIT32(p, f->fid);
		p += BIT32SZ;
		break;

	case Tstat:
		PBIT32(p, f->fid);
		p += BIT32SZ;
		break;

	case Twstat:
		PBIT32(p, f->fid);
		p += BIT32SZ;
		PBIT16(p, f->nstat);
		p += BIT16SZ;
		memmove(p, f->stat, f->nstat);
		p += f->nstat;
		break;
/*
 */

	case Rversion:
		PBIT32(p, f->msize);
		p += BIT32SZ;
		p = pstring(p, f->version);
		break;

	case Rerror:
		p = pstring(p, f->ename);
		break;

	case Rflush:
		break;

	case Rauth:
		p = pqid(p, &f->aqid);
		break;

	case Rattach:
		p = pqid(p, &f->qid);
		break;

	case Rwalk:
		PBIT16(p, f->nwqid);
		p += BIT16SZ;
		if(f->nwqid > MAXWELEM)
			return 0;
		for(i=0; i<f->nwqid; i++)
			p = pqid(p, &f->wqid[i]);
		break;

	case Ropen:
	case Rcreate:
		p = pqid(p, &f->qid);
		PBIT32(p, f->iounit);
		p += BIT32SZ;
		break;

	case Rread:
		PBIT32(p, f->count);
		p += BIT32SZ;
		memmove(p, f->data, f->count);
		p += f->count;
		break;

	case Rwrite:
		PBIT32(p, f->count);
		p += BIT32SZ;
		break;

	case Rclunk:
		break;

	case Rremove:
		break;

	case Rstat:
		PBIT16(p, f->nstat);
		p += BIT16SZ;
		memmove(p, f->stat, f->nstat);
		p += f->nstat;
		break;

	case Rwstat:
		break;
	}
	if(size != p-ap)
		return 0;
	return size;
}