1 #include "logfsos.h" 2 #include "logfs.h" 3 #include "local.h" 4 5 char * 6 logfsserveropen(LogfsServer *server, u32int fid, uchar mode, Qid *qid) 7 { 8 Fid *f; 9 Entry *e; 10 ulong modemask; 11 12 if(server->trace > 1) 13 print("logfsserveropen(%ud, %d)\n", fid, mode); 14 f = logfsfidmapfindentry(server->fidmap, fid); 15 if(f == nil) 16 return logfsebadfid; 17 if(f->openmode >= 0) 18 return logfsefidopen; 19 e = f->entry; 20 SET(modemask); 21 switch(mode & 3) { 22 case OEXEC: 23 modemask = DMEXEC; 24 break; 25 case OREAD: 26 modemask = DMREAD; 27 break; 28 case OWRITE: 29 modemask = DMWRITE; 30 break; 31 case ORDWR: 32 modemask = DMWRITE | DMREAD; 33 break; 34 } 35 if(e->qid.type & QTDIR) { 36 if((modemask & DMWRITE) != 0 || (mode & (ORCLOSE | OTRUNC)) != 0) 37 return Eperm; 38 } 39 else { 40 if(mode & OTRUNC) 41 modemask |= DMWRITE; 42 if((mode & ORCLOSE) != 0 && !logfsuserpermcheck(server, e->parent, f, DMWRITE)) 43 return Eperm; 44 } 45 if(!logfsuserpermcheck(server, e, f, modemask)) 46 return Eperm; 47 if((e->qid.type & QTDIR) == 0 && (mode & OTRUNC) != 0 && (e->perm & DMAPPEND) == 0 && e->u.file.length != 0) { 48 LogMessage s; 49 char *errmsg; 50 s.type = LogfsLogTtrunc; 51 s.path = e->qid.path; 52 s.u.trunc.mtime = logfsnow(); 53 s.u.trunc.cvers = e->u.file.cvers + 1; 54 s.u.trunc.muid = logfsisfindidfromname(server->is, f->uname); 55 errmsg = logfslog(server, 1, &s); 56 if(errmsg) 57 return errmsg; 58 e->muid = s.u.trunc.muid; 59 e->mtime = s.u.trunc.mtime; 60 e->qid.vers++; 61 e->u.file.cvers = s.u.trunc.cvers; 62 /* 63 * zap all data and extents 64 */ 65 logfsextentlistwalk(e->u.file.extent, logfsunconditionallymarkfreeanddirty, server); 66 logfsextentlistreset(e->u.file.extent); 67 e->u.file.length = 0; 68 } 69 f->openmode = mode; 70 *qid = e->qid; 71 return nil; 72 } 73