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; }
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); }
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; }
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; }
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; }
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; }
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; } }
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; }
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; }
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; }