void fileinit(Chan *cp) { File *f; Tlock *t; loop: lock(&cp->flock); f = cp->flist; if(!f) { unlock(&cp->flock); return; } cp->flist = f->next; unlock(&cp->flock); qlock(f); if(t = f->tlock) { t->time = 0; f->tlock = 0; } if(f->open & FREMOV) doremove(f, 0); freewp(f->wpath); f->open = 0; f->cp = 0; qunlock(f); goto loop; }
int doclri(File *f) { Iobuf *p, *p1; Dentry *d, *d1; int err; err = 0; p = 0; p1 = 0; if(f->fs->dev->type == Devro) { err = Eronly; goto out; } /* * check on parent directory of file to be deleted */ if(f->wpath == 0 || f->wpath->addr == f->addr) { err = Ephase; goto out; } p1 = getbuf(f->fs->dev, f->wpath->addr, Brd); d1 = getdir(p1, f->wpath->slot); if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) { err = Ephase; goto out; } accessdir(p1, d1, FWRITE, 0); putbuf(p1); p1 = 0; /* * check on file to be deleted */ p = getbuf(f->fs->dev, f->addr, Brd); d = getdir(p, f->slot); /* * do it */ memset(d, 0, sizeof(Dentry)); settag(p, Tdir, QPNONE); freewp(f->wpath); freefp(f); out: if(p1) putbuf(p1); if(p) putbuf(p); return err; }
void f_clone(Chan *cp, Oldfcall *in, Oldfcall *ou) { File *f1, *f2; int fid, fid1; if(CHAT(cp)) { print("c_clone %d\n", cp->chan); print(" old fid = %d\n", in->fid); print(" new fid = %d\n", in->newfid); } fid = in->fid; fid1 = in->newfid; f1 = 0; f2 = 0; if(fid < fid1) { f1 = filep(cp, fid, 0); f2 = filep(cp, fid1, 1); } else if(fid1 < fid) { f2 = filep(cp, fid1, 1); f1 = filep(cp, fid, 0); } if(!f1 || !f2) { ou->err = Efid; goto out; } f2->fs = f1->fs; f2->addr = f1->addr; f2->open = f1->open & ~FREMOV; f2->uid = f1->uid; f2->slot = f1->slot; f2->qid = f1->qid; freewp(f2->wpath); f2->wpath = getwp(f1->wpath); out: ou->fid = fid; if(f1) qunlock(f1); if(f2) qunlock(f2); }
void fileinit(Chan *cp) { File *f, *prev; Tlock *t; int h; loop: lock(&flock); for (h=0; h < nelem(flist); h++) for (prev=0, f = flist[h]; f; prev=f, f=f->next) { if(f->cp != cp) continue; if(prev) { prev->next = f->next; f->next = flist[h]; flist[h] = f; } flist[h] = f->next; unlock(&flock); qlock(f); if(t = f->tlock) { if(t->file == f) t->time = 0; /* free the lock */ f->tlock = 0; } if(f->open & FREMOV) doremove(f, 0); freewp(f->wpath); f->open = 0; authfree(f->auth); f->auth = 0; f->cp = 0; qunlock(f); goto loop; } unlock(&flock); }
void f_clunk(Chan *cp, Oldfcall *in, Oldfcall *ou) { File *f; Tlock *t; int32_t tim; if(CHAT(cp)) { print("c_clunk %d\n", cp->chan); print(" fid = %d\n", in->fid); } f = filep(cp, in->fid, 0); if(!f) { print("%p\n", f); ou->err = Efid; goto out; } if(t = f->tlock) { tim = time(0); if(t->time < tim || t->file != f) ou->err = Ebroken; t->time = 0; /* free the lock */ f->tlock = 0; } if(f->open & FREMOV) ou->err = doremove(f, 0); f->open = 0; freewp(f->wpath); freefp(f); out: if(f) qunlock(f); ou->fid = in->fid; }
void f_attach(Chan *cp, Oldfcall *in, Oldfcall *ou) { Iobuf *p; Dentry *d; File *f; int u; Filsys *fs; int32_t raddr; if(CHAT(cp)) { print("c_attach %d\n", cp->chan); print(" fid = %d\n", in->fid); print(" uid = %s\n", in->uname); print(" arg = %s\n", in->aname); } ou->qid = QID9P1(0,0); ou->fid = in->fid; if(!in->aname[0]) /* default */ strncpy(in->aname, filesys[0].name, sizeof(in->aname)); p = 0; f = filep(cp, in->fid, 1); if(!f) { ou->err = Efid; goto out; } u = -1; if(cp != cons.chan){ if(authorize(cp, in, ou) == 0 || strcmp(in->uname, "adm") == 0){ ou->err = Eauth; goto out; } u = strtouid(in->uname); if(u < 0){ ou->err = Ebadu; goto out; } } fs = fsstr(in->aname); if(fs == 0) { ou->err = Ebadspc; goto out; } raddr = getraddr(fs->dev); p = getbuf(fs->dev, raddr, Bread); d = getdir(p, 0); if(!d || checktag(p, Tdir, QPROOT) || !(d->mode & DALLOC)) { ou->err = Ealloc; goto out; } f->uid = u; if(iaccess(f, d, DREAD)) { ou->err = Eaccess; goto out; } accessdir(p, d, FREAD); mkqid(&f->qid, d, 1); f->fs = fs; f->addr = raddr; f->slot = 0; f->open = 0; freewp(f->wpath); f->wpath = 0; mkqid9p1(&ou->qid, &f->qid); out: if(p) putbuf(p); if(f) { qunlock(f); if(ou->err) freefp(f); } }