12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- #include "logfsos.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;
- }
|