Charles.Forsyth20060303a828770d19 years agoHistory
82 lines · 2.2 KB · C
RawDownload
#include "lib9.h"#include "logfs.h"#include "local.h" char *logfsservercreate(LogfsServer *server, u32int fid, char *name, u32int perm, uchar mode, Qid *qid){	Fid *f;	char *uid;	ulong newpath;	char *errmsg;	Entry *e, *xe, *pe;	Path *pp;	LogMessage s; 	if(server->trace > 1)		print("logfsservercreate(%ud, %s, 0%uo, %.2ux)\n", fid, name, perm, mode);	f = logfsfidmapfindentry(server->fidmap, fid);	if(f == nil)		return logfsebadfid;	if(f->openmode >= 0)		return logfsefidopen;	pe = f->entry;	if((pe->qid.type & QTDIR) == 0)		return Enotdir;	if((perm & DMDIR) != 0 && ((mode & OTRUNC) != 0 || (mode &  3) != OREAD))		return Eperm;	if(!logfsuserpermcheck(server, pe, f, DMWRITE))		return Eperm;	/*	 * illegal names	 */	if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0)		return Eperm;	for(xe = pe->u.dir.list; xe; xe = xe->next)		if(strcmp(xe->name, name) == 0)			return Eexist;	newpath = ++server->path;	while(logfspathmapfindentry(server->pathmap, newpath))		newpath++;	/* shouldn't happen */	uid = logfsisfindidfromname(server->is, f->uname);	errmsg = logfsentrynew(server, 1, newpath,		pe, name, uid, f->entry->gid, logfsnow(), uid, perm, 0, 0, &e);	if(errmsg)		return errmsg;	errmsg = logfspathmapnewentry(server->pathmap, newpath, e, &pp);	/* pp is guaranteed to be non-null */	if(errmsg) {		logfsfreemem(e);		return errmsg;	}	s.type = LogfsLogTcreate;	s.path = e->parent->qid.path;		s.u.create.perm = e->perm;	s.u.create.newpath = e->qid.path;	s.u.create.mtime = e->mtime;	/* TODO - check with forsyth whether cvers is needed in dirs */	s.u.create.cvers = (e->qid.type & QTDIR) ? 0 : e->u.file.cvers;	s.u.create.name = e->name;	s.u.create.uid = e->uid;	s.u.create.gid = e->gid;	errmsg = logfslog(server, 1, &s);	if(errmsg) {		logfsfreemem(e);		logfspathmapdeleteentry(server->pathmap, newpath);		return errmsg;	}	server->path = newpath;	e->inuse++;	e->qid.vers++;	e->next = pe->u.dir.list;	pe->u.dir.list = e;	f->openmode = mode;	/*	 * TODO why does forsyth increment inuse for dir? - we're moving the fid onto the new file	 * so a decrement seems better	 */	logfsentryclunk(pe);	f->entry = e;	*qid = e->qid;	return nil;}