#include "logfsos.h" #include "logfs.h" #include "local.h" char * logfsserveropen(LogfsServer *server, u32int fid, uchar mode, Qid *qid) { Fid *f; Entry *e; ulong modemask; if(server->trace > 1) print("logfsserveropen(%ud, %d)\n", fid, mode); f = logfsfidmapfindentry(server->fidmap, fid); if(f == nil) return logfsebadfid; if(f->openmode >= 0) return logfsefidopen; e = f->entry; SET(modemask); switch(mode & 3) { case OEXEC: modemask = DMEXEC; break; case OREAD: modemask = DMREAD; break; case OWRITE: modemask = DMWRITE; break; case ORDWR: modemask = DMWRITE | DMREAD; break; } if(e->qid.type & QTDIR) { if((modemask & DMWRITE) != 0 || (mode & (ORCLOSE | OTRUNC)) != 0) return Eperm; } else { if(mode & OTRUNC) modemask |= DMWRITE; if((mode & ORCLOSE) != 0 && !logfsuserpermcheck(server, e->parent, f, DMWRITE)) return Eperm; } if(!logfsuserpermcheck(server, e, f, modemask)) return Eperm; if((e->qid.type & QTDIR) == 0 && (mode & OTRUNC) != 0 && (e->perm & DMAPPEND) == 0 && e->u.file.length != 0) { LogMessage s; char *errmsg; s.type = LogfsLogTtrunc; s.path = e->qid.path; s.u.trunc.mtime = logfsnow(); s.u.trunc.cvers = e->u.file.cvers + 1; s.u.trunc.muid = logfsisfindidfromname(server->is, f->uname); errmsg = logfslog(server, 1, &s); if(errmsg) return errmsg; e->muid = s.u.trunc.muid; e->mtime = s.u.trunc.mtime; e->qid.vers++; e->u.file.cvers = s.u.trunc.cvers; /* * zap all data and extents */ logfsextentlistwalk(e->u.file.extent, logfsunconditionallymarkfreeanddirty, server); logfsextentlistreset(e->u.file.extent); e->u.file.length = 0; } f->openmode = mode; *qid = e->qid; return nil; }