Exemple #1
0
static int
srvFd(char* name, int mode, int fd, char** mntpnt)
{
	int n, srvfd;
	char *p, buf[10];

	/*
	 * Drop a file descriptor with given name and mode into /srv.
	 * Create with ORCLOSE and don't close srvfd so it will be removed
	 * automatically on process exit.
	 */
	p = smprint("/srv/%s", name);
	if((srvfd = create(p, ORCLOSE|OWRITE, mode)) < 0){
		vtMemFree(p);
		p = smprint("#s/%s", name);
		if((srvfd = create(p, ORCLOSE|OWRITE, mode)) < 0){
			vtSetError("create %s: %r", p);
			vtMemFree(p);
			return -1;
		}
	}

	n = snprint(buf, sizeof(buf), "%d", fd);
	if(write(srvfd, buf, n) < 0){
		close(srvfd);
		vtSetError("write %s: %r", p);
		vtMemFree(p);
		return -1;
	}

	*mntpnt = p;

	return srvfd;
}
Exemple #2
0
void
deeClose(DirEntryEnum *dee)
{
	int i;
	if(dee == nil)
		return;
	for(i=dee->i; i<dee->n; i++)
		deCleanup(dee->buf+i);
	vtMemFree(dee->buf);
	fileDecRef(dee->file);
	vtMemFree(dee);
}
Exemple #3
0
void
deCleanup(DirEntry *dir)
{
	vtMemFree(dir->elem);
	dir->elem = nil;
	vtMemFree(dir->uid);
	dir->uid = nil;
	vtMemFree(dir->gid);
	dir->gid = nil;
	vtMemFree(dir->mid);
	dir->mid = nil;
}
Exemple #4
0
static void
fidFree(Fid* fid)
{
	if(fid->file != nil){
		fileDecRef(fid->file);
		fid->file = nil;
	}
	if(fid->db != nil){
		dirBufFree(fid->db);
		fid->db = nil;
	}
	fidUnlock(fid);

	if(fid->uid != nil){
		vtMemFree(fid->uid);
		fid->uid = nil;
	}
	if(fid->uname != nil){
		vtMemFree(fid->uname);
		fid->uname = nil;
	}
	if(fid->excl != nil)
		exclFree(fid);
	if(fid->rpc != nil){
		close(fid->rpc->afd);
		auth_freerpc(fid->rpc);
		fid->rpc = nil;
	}
	if(fid->fsys != nil){
		fsysPut(fid->fsys);
		fid->fsys = nil;
	}
	if(fid->cuname != nil){
		vtMemFree(fid->cuname);
		fid->cuname = nil;
	}

	vtLock(fbox.lock);
	fbox.inuse--;
	if(fbox.nfree < 10){
		fid->hash = fbox.free;
		fbox.free = fid;
		fbox.nfree++;
	}
	else{
		vtLockFree(fid->alock);
		vtLockFree(fid->lock);
		vtMemFree(fid);
	}
	vtUnlock(fbox.lock);
}
Exemple #5
0
void
vtDetach(void)
{
	Thread *p;

	p = *vtRock;
	assert(p != nil);
	p->ref--;
	if(p->ref == 0) {
		vtMemFree(p->error);
		vtMemFree(p);
		*vtRock = nil;
	}
}
Exemple #6
0
/*
 * Fsck that MetaBlock has reasonable header, sorted entries,
 */
static int
chkMetaBlock(MetaBlock *mb)
{
	MetaChunk *mc;
	int oo, o, n, i;
	uchar *p;

	mc = vtMemAlloc(mb->nindex*sizeof(MetaChunk));
	p = mb->buf + MetaHeaderSize;
	for(i = 0; i < mb->nindex; i++){
		mc[i].offset = p[0]<<8 | p[1];
		mc[i].size =   p[2]<<8 | p[3];
		mc[i].index = i;
		p += MetaIndexSize;
	}

	qsort(mc, mb->nindex, sizeof(MetaChunk), offsetCmp);

	/* check block looks ok */
	oo = MetaHeaderSize + mb->maxindex*MetaIndexSize;
	o = oo;
	n = 0;
	for(i = 0; i < mb->nindex; i++){
		o = mc[i].offset;
		n = mc[i].size;
		if(o < oo)
			goto Err;
		oo += n;
	}
	if(o+n > mb->size || mb->size - oo != mb->free)
		goto Err;

	vtMemFree(mc);
	return 1;

Err:
if(0){
	fprint(2, "metaChunks failed!\n");
	oo = MetaHeaderSize + mb->maxindex*MetaIndexSize;
	for(i=0; i<mb->nindex; i++){
		fprint(2, "\t%d: %d %d\n", i, mc[i].offset,
			mc[i].offset + mc[i].size);
		oo += mc[i].size;
	}
	fprint(2, "\tused=%d size=%d free=%d free2=%d\n",
		oo, mb->size, mb->free, mb->size - oo);
}
	vtMemFree(mc);
	return 0;
}
Exemple #7
0
int
fileMetaFlush(File *f, int rec)
{
	File **kids, *p;
	int nkids;
	int i, rv;

	fileMetaLock(f);
	rv = fileMetaFlush2(f, nil);
	fileMetaUnlock(f);

	if(!rec || !fileIsDir(f))
		return rv;

	if(!fileLock(f))
		return rv;
	nkids = 0;
	for(p=f->down; p; p=p->next)
		nkids++;
	kids = vtMemAlloc(nkids*sizeof(File*));
	i = 0;
	for(p=f->down; p; p=p->next){
		kids[i++] = p;
		p->ref++;
	}
	fileUnlock(f);

	for(i=0; i<nkids; i++){
		rv |= fileMetaFlush(kids[i], 1);
		fileDecRef(kids[i]);
	}
	vtMemFree(kids);
	return rv;
}
Exemple #8
0
static Packet *
vtRPC(VtSession *z, int op, Packet *p)
{
	uint8_t *hdr, buf[2];
	char *err;

	if(z == nil){
		vtSetError(ENotConnected);
		return nil;
	}

	/*
	 * single threaded for the momment
	 */
	vtLock(z->lk);
	if(z->cstate != VtStateConnected){
		vtSetError(ENotConnected);
		goto Err;
	}
	hdr = packetHeader(p, 2);
	hdr[0] = op;	/* op */
	hdr[1] = 0;	/* tid */
	vtDebug(z, "client send: ");
	vtDebugMesg(z, p, "\n");
	if(!vtSendPacket(z, p)) {
		p = nil;
		goto Err;
	}
	p = vtRecvPacket(z);
	if(p == nil)
		goto Err;
	vtDebug(z, "client recv: ");
	vtDebugMesg(z, p, "\n");
	if(!packetConsume(p, buf, 2))
		goto Err;
	if(buf[0] == VtRError) {
		if(!vtGetString(p, &err)) {
			vtSetError(EProtocolBotch);
			goto Err;
		}
		vtSetError(err);
		vtMemFree(err);
		packetFree(p);
		vtUnlock(z->lk);
		return nil;
	}
	if(buf[0] != op+1 || buf[1] != 0) {
		vtSetError(EProtocolBotch);
		goto Err;
	}
	vtUnlock(z->lk);
	return p;
Err:
	vtDebug(z, "vtRPC failed: %s\n", vtGetError());
	if(p != nil)
		packetFree(p);
	vtUnlock(z->lk);
	vtDisconnect(z, 1);
	return nil;
}
Exemple #9
0
void
vtRendezFree(VtRendez *q)
{
	if(q == nil)
		return;
	assert(q->wfirst == nil);
	vtMemFree(q);
}
Exemple #10
0
uchar *
mbAlloc(MetaBlock *mb, int n)
{
	int i, o;
	MetaChunk *mc;

	/* off the end */
	if(mb->maxsize - mb->size >= n)
		return mb->buf + mb->size;

	/* check if possible */
	if(mb->maxsize - mb->size + mb->free < n)
		return nil;

	mc = metaChunks(mb);
	if(mc == nil){
fprint(2, "mbAlloc: metaChunks failed: %r\n");
		return nil;
	}

	/* look for hole */
	o = MetaHeaderSize + mb->maxindex*MetaIndexSize;
	for(i=0; i<mb->nindex; i++){
		if(mc[i].offset - o >= n){
			vtMemFree(mc);
			return mb->buf + o;
		}
		o = mc[i].offset + mc[i].size;
	}

	if(mb->maxsize - o >= n){
		vtMemFree(mc);
		return mb->buf + o;
	}

	/* compact and return off the end */
	mbCompact(mb, mc);
	vtMemFree(mc);

	if(mb->maxsize - mb->size < n){
		vtSetError(EBadMeta);
		return nil;
	}
	return mb->buf + mb->size;
}
Exemple #11
0
static void
srvFree(Srv* srv)
{
	if(srv->prev != nil)
		srv->prev->next = srv->next;
	else
		sbox.head = srv->next;
	if(srv->next != nil)
		srv->next->prev = srv->prev;
	else
		sbox.tail = srv->prev;

	if(srv->srvfd != -1)
		close(srv->srvfd);
	vtMemFree(srv->service);
	vtMemFree(srv->mntpnt);
	vtMemFree(srv);
}
Exemple #12
0
static void
snapClose(Snap *s)
{
	if(s == nil)
		return;

	periodicKill(s->tick);
	vtMemFree(s);
}
Exemple #13
0
void
vtSha1Free(VtSha1 *s)
{
	if(s == nil)
		return;
	if(s->s != nil)
		free(s->s);
	vtMemFree(s);
}
Exemple #14
0
static void
lstnFree(Lstn* lstn)
{
	vtLock(lbox.lock);
	if(lstn->prev != nil)
		lstn->prev->next = lstn->next;
	else
		lbox.head = lstn->next;
	if(lstn->next != nil)
		lstn->next->prev = lstn->prev;
	else
		lbox.tail = lstn->prev;
	vtUnlock(lbox.lock);

	if(lstn->afd != -1)
		close(lstn->afd);
	vtMemFree(lstn->address);
	vtMemFree(lstn);
}
Exemple #15
0
void
vtLockFree(VtLock *p)
{
	if(p == nil)
		return;
	assert(p->writer == nil);
	assert(p->readers == 0);
	assert(p->qfirst == nil);
	vtMemFree(p);
}
Exemple #16
0
static int
_groupRemMember(Ubox* box, User* g, char* member)
{
	int i;

	if(_userByUname(box, member) == nil)
		return 0;

	for(i = 0; i < g->ngroup; i++){
		if(strcmp(g->group[i], member) == 0)
			break;
	}
	if(i >= g->ngroup){
		if(strcmp(g->uname, member) == 0)
			vtSetError("uname: '%s' always in own group", member);
		else
			vtSetError("uname: '%s' not in group '%s'",
				member, g->uname);
		return 0;
	}

	vtMemFree(g->group[i]);

	box->len -= strlen(member);
	if(g->ngroup > 1)
		box->len--;
	g->ngroup--;
	switch(g->ngroup){
	case 0:
		vtMemFree(g->group);
		g->group = nil;
		break;
	default:
		for(; i < g->ngroup; i++)
			g->group[i] = g->group[i+1];
		g->group[i] = nil;		/* prevent accidents */
		g->group = vtMemRealloc(g->group, g->ngroup * sizeof(char*));
		break;
	}

	return 1;
}
Exemple #17
0
static void
uboxFree(Ubox* box)
{
	User *next, *u;

	for(u = box->head; u != nil; u = next){
		next = u->next;
		userFree(u);
	}
	vtMemFree(box);
}
Exemple #18
0
void
vtFree(VtSession *z)
{
	if(z == nil)
		return;
	vtLockFree(z->lk);
	vtSha1Free(z->inHash);
	vtLockFree(z->inLock);
	packetFree(z->part);
	vtSha1Free(z->outHash);
	vtLockFree(z->outLock);
	vtMemFree(z->uid);
	vtMemFree(z->sid);
	vtMemFree(z->vtbl);

	memset(z, 0, sizeof(VtSession));
	z->fd = -1;

	vtMemFree(z);
}
Exemple #19
0
static void
fileFree(File *f)
{
	sourceClose(f->source);
	vtLockFree(f->lk);
	sourceClose(f->msource);
	deCleanup(&f->dir);

	memset(f, ~0, sizeof(File));
	vtMemFree(f);
}
Exemple #20
0
int
vtHello(VtSession *z)
{
	Packet *p;
	uint8_t buf[10];
	char *sid;
	int crypto, codec;

	sid = nil;

	p = packetAlloc();
	if(!vtAddString(p, vtGetVersion(z)))
		goto Err;
	if(!vtAddString(p, vtGetUid(z)))
		goto Err;
	buf[0] = vtGetCryptoStrength(z);
	buf[1] = 0;
	buf[2] = 0;
	packetAppend(p, buf, 3);
	p = vtRPC(z, VtQHello, p);
	if(p == nil)
		return 0;
	if(!vtGetString(p, &sid))
		goto Err;
	if(!packetConsume(p, buf, 2))
		goto Err;
	if(packetSize(p) != 0) {
		vtSetError(EProtocolBotch);
		goto Err;
	}
	crypto = buf[0];
	codec = buf[1];

	USED(crypto);
	USED(codec);

	packetFree(p);

	vtLock(z->lk);
	z->sid = sid;
	z->auth.state = VtAuthOK;
	vtSha1Free(z->inHash);
	z->inHash = nil;
	vtSha1Free(z->outHash);
	z->outHash = nil;
	vtUnlock(z->lk);

	return 1;
Err:
	packetFree(p);
	vtMemFree(sid);
	return 0;
}
Exemple #21
0
void
fsClose(Fs *fs)
{
	vtRLock(fs->elk);
	periodicKill(fs->metaFlush);
	snapClose(fs->snap);
	if(fs->file){
		fileMetaFlush(fs->file, 0);
		if(!fileDecRef(fs->file))
			vtFatal("fsClose: files still in use: %r\n");
	}
	fs->file = nil;
	sourceClose(fs->source);
	cacheFree(fs->cache);
	if(fs->arch)
		archFree(fs->arch);
	vtMemFree(fs->name);
	vtRUnlock(fs->elk);
	vtLockFree(fs->elk);
	memset(fs, ~0, sizeof(Fs));
	vtMemFree(fs);
}
Exemple #22
0
static int
deeFill(DirEntryEnum *dee)
{
	int i, n;
	Source *meta, *source;
	MetaBlock mb;
	MetaEntry me;
	File *f;
	Block *b;
	DirEntry *de;

	/* clean up first */
	for(i=dee->i; i<dee->n; i++)
		deCleanup(dee->buf+i);
	vtMemFree(dee->buf);
	dee->buf = nil;
	dee->i = 0;
	dee->n = 0;

	f = dee->file;

	source = f->source;
	meta = f->msource;

	b = sourceBlock(meta, dee->boff, OReadOnly);
	if(b == nil)
		goto Err;
	if(!mbUnpack(&mb, b->data, meta->dsize))
		goto Err;

	n = mb.nindex;
	dee->buf = vtMemAlloc(n * sizeof(DirEntry));

	for(i=0; i<n; i++){
		de = dee->buf + i;
		meUnpack(&me, &mb, i);
		if(!deUnpack(de, &me))
			goto Err;
		dee->n++;
		if(!(de->mode & ModeDir))
		if(!dirEntrySize(source, de->entry, de->gen, &de->size))
			goto Err;
	}
	dee->boff++;
	blockPut(b);
	return 1;
Err:
	blockPut(b);
	return 0;
}
Exemple #23
0
/*
 * Walk through all the blocks in the write buffer.
 * Then we can look for ones we missed -- those are leaks.
 */
static void
checkEpochs(Fsck *chk)
{
	u32int e;
	uint nb;

	nb = chk->nblocks;
	chk->amap = vtMemAllocZ(nb/8+1);
	chk->emap = vtMemAllocZ(nb/8+1);
	chk->xmap = vtMemAllocZ(nb/8+1);
	chk->errmap = vtMemAllocZ(nb/8+1);

	for(e = chk->fs->ehi; e >= chk->fs->elo; e--){
		memset(chk->emap, 0, chk->nblocks/8+1);
		memset(chk->xmap, 0, chk->nblocks/8+1);
		checkEpoch(chk, e);
	}
	checkLeak(chk);
	vtMemFree(chk->amap);
	vtMemFree(chk->emap);
	vtMemFree(chk->xmap);
	vtMemFree(chk->errmap);
}
Exemple #24
0
void
archFree(Arch *a)
{
	/* kill slave */
	vtLock(a->lk);
	a->die = vtRendezAlloc(a->lk);
	vtWakeup(a->starve);
	while(a->ref > 1)
		vtSleep(a->die);
	vtUnlock(a->lk);
	vtRendezFree(a->starve);
	vtRendezFree(a->die);
	vtLockFree(a->lk);
	vtMemFree(a);
}
Exemple #25
0
static MetaChunk *
metaChunks(MetaBlock *mb)
{
	MetaChunk *mc;
	int oo, o, n, i;
	uchar *p;

	mc = vtMemAlloc(mb->nindex*sizeof(MetaChunk));
	p = mb->buf + MetaHeaderSize;
	for(i = 0; i<mb->nindex; i++){
		mc[i].offset = U16GET(p);
		mc[i].size = U16GET(p+2);
		mc[i].index = i;
		p += MetaIndexSize;
	}

	qsort(mc, mb->nindex, sizeof(MetaChunk), offsetCmp);

	/* check block looks ok */
	oo = MetaHeaderSize + mb->maxindex*MetaIndexSize;
	o = oo;
	n = 0;
	for(i=0; i<mb->nindex; i++){
		o = mc[i].offset;
		n = mc[i].size;
		if(o < oo)
			goto Err;
		oo += n;
	}
	if(o+n > mb->size)
		goto Err;
	if(mb->size - oo != mb->free)
		goto Err;

	return mc;
Err:
fprint(2, "metaChunks failed!\n");
oo = MetaHeaderSize + mb->maxindex*MetaIndexSize;
for(i=0; i<mb->nindex; i++){
fprint(2, "\t%d: %d %d\n", i, mc[i].offset, mc[i].offset + mc[i].size);
oo += mc[i].size;
}
fprint(2, "\tused=%d size=%d free=%d free2=%d\n", oo, mb->size, mb->free, mb->size - oo);
	vtSetError(EBadMeta);
	vtMemFree(mc);
	return nil;
}
Exemple #26
0
/* return number of directory entries remaining */
static int
fsRsearch1(File *f, char *s)
{
	int n, r;
	DirEntry de;
	DirEntryEnum *dee;
	File *ff;
	char *t;

	dee = deeOpen(f);
	if(dee == nil)
		return 0;

	n = 0;
	for(;;){
		r = deeRead(dee, &de);
		if(r <= 0)
			break;
		n++;
		if(de.mode & ModeSnapshot){
			if((ff = fileWalk(f, de.elem)) != nil)
				fileDecRef(ff);
			else if(strcmp(vtGetError(), ESnapOld) == 0){
				if(fileClri(f, de.elem, "adm"))
					n--;
			}
		}
		else if(de.mode & ModeDir){
			if((ff = fileWalk(f, de.elem)) != nil){
				t = smprint("%s/%s", s, de.elem);
				if(fsRsearch1(ff, t) == 0)
					if(fileRemove(ff, "adm"))
						n--;
				vtMemFree(t);
				fileDecRef(ff);
			}
		}
		deCleanup(&de);
		if(r < 0)
			break;
	}
	deeClose(dee);

	return n;
}
Exemple #27
0
static int
fsEsearch1(File *f, char *path, uint32_t savetime, uint32_t *plo)
{
	int n, r;
	DirEntry de;
	DirEntryEnum *dee;
	File *ff;
	Entry e, ee;
	char *t;

	dee = deeOpen(f);
	if(dee == nil)
		return 0;

	n = 0;
	for(;;){
		r = deeRead(dee, &de);
		if(r <= 0)
			break;
		if(de.mode & ModeSnapshot){
			if((ff = fileWalk(f, de.elem)) != nil){
				if(fileGetSources(ff, &e, &ee))
					if(de.mtime >= savetime && e.snap != 0)
						if(e.snap < *plo)
							*plo = e.snap;
				fileDecRef(ff);
			}
		}
		else if(de.mode & ModeDir){
			if((ff = fileWalk(f, de.elem)) != nil){
				t = smprint("%s/%s", path, de.elem);
				n += fsEsearch1(ff, t, savetime, plo);
				vtMemFree(t);
				fileDecRef(ff);
			}
		}
		deCleanup(&de);
		if(r < 0)
			break;
	}
	deeClose(dee);

	return n;
}
Exemple #28
0
void
sourceClose(Source *r)
{
    if(r == nil)
        return;
    vtLock(r->lk);
    r->ref--;
    if(r->ref) {
        vtUnlock(r->lk);
        return;
    }
    assert(r->ref == 0);
    vtUnlock(r->lk);
    if(r->parent)
        sourceClose(r->parent);
    vtLockFree(r->lk);
    memset(r, ~0, sizeof(*r));
    vtMemFree(r);
}
Exemple #29
0
char*
vtSetError(char* fmt, ...)
{
	Thread *p;
	char *s;
	va_list args;

	p = threadLookup();

	va_start(args, fmt);
	s = vsmprint(fmt, args);
	vtMemFree(p->error);
	p->error = s;
	va_end(args);
	if(ERROR)
		fprint(2, "vtSetError: %s\n", p->error);
	werrstr("%s", p->error);
	return p->error;
}
Exemple #30
0
void
fsCheck(Fsck *chk)
{
	Block *b;
	Super super;

	checkInit(chk);
	b = superGet(chk->cache, &super);
	if(b == nil){
		chk->print("could not load super block: %R");
		return;
	}
	blockPut(b);

	chk->hint = super.active;
	checkEpochs(chk);

	chk->smap = vtMemAllocZ(chk->nblocks/8+1);
	checkDirs(chk);
	vtMemFree(chk->smap);
}