1 78a779a3 2008-07-20 rsc #include <u.h>
2 78a779a3 2008-07-20 rsc #include <libc.h>
3 78a779a3 2008-07-20 rsc #include <auth.h>
4 78a779a3 2008-07-20 rsc #include <fcall.h>
5 78a779a3 2008-07-20 rsc #include "dat.h"
6 78a779a3 2008-07-20 rsc #include "fns.h"
8 78a779a3 2008-07-20 rsc static Xfile* clean(Xfile*);
10 78a779a3 2008-07-20 rsc #define FIDMOD 127 /* prime */
12 78a779a3 2008-07-20 rsc static Xdata* xhead;
13 78a779a3 2008-07-20 rsc static Xfile* xfiles[FIDMOD];
14 78a779a3 2008-07-20 rsc static Xfile* freelist;
17 78a779a3 2008-07-20 rsc getxdata(char *name)
21 78a779a3 2008-07-20 rsc Xdata *xf, *fxf;
24 78a779a3 2008-07-20 rsc if(name[0] == 0)
25 78a779a3 2008-07-20 rsc name = deffile;
26 78a779a3 2008-07-20 rsc if(name == 0)
27 78a779a3 2008-07-20 rsc error(Enofile);
28 78a779a3 2008-07-20 rsc flag = (access(name, 6) == 0) ? ORDWR : OREAD;
29 78a779a3 2008-07-20 rsc fd = open(name, flag);
31 78a779a3 2008-07-20 rsc error(Enonexist);
33 78a779a3 2008-07-20 rsc if(waserror()){
38 78a779a3 2008-07-20 rsc if((dir = dirfstat(fd)) == nil)
39 78a779a3 2008-07-20 rsc error("I/O error");
40 78a779a3 2008-07-20 rsc if((dir->qid.type & ~QTTMP) != QTFILE)
41 78a779a3 2008-07-20 rsc error("attach name not a plain file");
42 78a779a3 2008-07-20 rsc for(fxf=0,xf=xhead; xf; xf=xf->next){
43 78a779a3 2008-07-20 rsc if(xf->name == 0){
48 78a779a3 2008-07-20 rsc if(xf->qid.path != dir->qid.path || xf->qid.vers != dir->qid.vers)
50 78a779a3 2008-07-20 rsc if(xf->type != dir->type || xf->fdev != dir->dev)
53 78a779a3 2008-07-20 rsc chat("incref=%d, \"%s\", dev=%d...", xf->ref, xf->name, xf->dev);
60 78a779a3 2008-07-20 rsc fxf = ealloc(sizeof(Xfs));
61 78a779a3 2008-07-20 rsc fxf->next = xhead;
64 78a779a3 2008-07-20 rsc chat("alloc \"%s\", dev=%d...", name, fd);
65 78a779a3 2008-07-20 rsc fxf->ref = 1;
66 78a779a3 2008-07-20 rsc fxf->name = strcpy(ealloc(strlen(name)+1), name);
67 78a779a3 2008-07-20 rsc fxf->qid = dir->qid;
68 78a779a3 2008-07-20 rsc fxf->type = dir->type;
69 78a779a3 2008-07-20 rsc fxf->fdev = dir->dev;
70 78a779a3 2008-07-20 rsc fxf->dev = fd;
77 78a779a3 2008-07-20 rsc putxdata(Xdata *d)
79 78a779a3 2008-07-20 rsc if(d->ref <= 0)
80 78a779a3 2008-07-20 rsc panic(0, "putxdata");
82 78a779a3 2008-07-20 rsc chat("decref=%d, \"%s\", dev=%d...", d->ref, d->name, d->dev);
83 78a779a3 2008-07-20 rsc if(d->ref == 0){
84 78a779a3 2008-07-20 rsc chat("purgebuf...");
86 78a779a3 2008-07-20 rsc close(d->dev);
87 78a779a3 2008-07-20 rsc free(d->name);
93 78a779a3 2008-07-20 rsc refxfs(Xfs *xf, int delta)
95 78a779a3 2008-07-20 rsc xf->ref += delta;
96 78a779a3 2008-07-20 rsc if(xf->ref == 0){
98 78a779a3 2008-07-20 rsc putxdata(xf->d);
100 78a779a3 2008-07-20 rsc free(xf->ptr);
106 78a779a3 2008-07-20 rsc xfile(int fid, int flag)
108 78a779a3 2008-07-20 rsc int k = fid%FIDMOD;
109 78a779a3 2008-07-20 rsc Xfile **hp=&xfiles[k], *f, *pf;
111 78a779a3 2008-07-20 rsc for(f=*hp,pf=0; f; pf=f,f=f->next)
112 78a779a3 2008-07-20 rsc if(f->fid == fid)
114 78a779a3 2008-07-20 rsc if(f && pf){
115 78a779a3 2008-07-20 rsc pf->next = f->next;
116 78a779a3 2008-07-20 rsc f->next = *hp;
119 78a779a3 2008-07-20 rsc switch(flag){
121 78a779a3 2008-07-20 rsc panic(0, "xfile");
124 78a779a3 2008-07-20 rsc error("unassigned fid");
130 78a779a3 2008-07-20 rsc *hp = f->next;
132 78a779a3 2008-07-20 rsc f->next = freelist;
133 78a779a3 2008-07-20 rsc freelist = f;
138 78a779a3 2008-07-20 rsc return clean(f);
139 78a779a3 2008-07-20 rsc if(f = freelist) /* assign = */
140 78a779a3 2008-07-20 rsc freelist = f->next;
142 78a779a3 2008-07-20 rsc f = ealloc(sizeof(Xfile));
143 78a779a3 2008-07-20 rsc f->next = *hp;
146 78a779a3 2008-07-20 rsc f->fid = fid;
147 78a779a3 2008-07-20 rsc f->flags = 0;
148 78a779a3 2008-07-20 rsc f->qid = (Qid){0,0,0};
154 78a779a3 2008-07-20 rsc static Xfile *
155 78a779a3 2008-07-20 rsc clean(Xfile *f)
158 78a779a3 2008-07-20 rsc refxfs(f->xf, -1);
162 78a779a3 2008-07-20 rsc free(f->ptr);
166 78a779a3 2008-07-20 rsc f->flags = 0;
167 78a779a3 2008-07-20 rsc f->qid = (Qid){0,0,0};