Blame


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"
7 78a779a3 2008-07-20 rsc
8 78a779a3 2008-07-20 rsc static Xfile* clean(Xfile*);
9 78a779a3 2008-07-20 rsc
10 78a779a3 2008-07-20 rsc #define FIDMOD 127 /* prime */
11 78a779a3 2008-07-20 rsc
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;
15 78a779a3 2008-07-20 rsc
16 78a779a3 2008-07-20 rsc Xdata*
17 78a779a3 2008-07-20 rsc getxdata(char *name)
18 78a779a3 2008-07-20 rsc {
19 78a779a3 2008-07-20 rsc int fd;
20 78a779a3 2008-07-20 rsc Dir *dir;
21 78a779a3 2008-07-20 rsc Xdata *xf, *fxf;
22 78a779a3 2008-07-20 rsc int flag;
23 78a779a3 2008-07-20 rsc
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);
30 78a779a3 2008-07-20 rsc if(fd < 0)
31 78a779a3 2008-07-20 rsc error(Enonexist);
32 78a779a3 2008-07-20 rsc dir = nil;
33 78a779a3 2008-07-20 rsc if(waserror()){
34 78a779a3 2008-07-20 rsc close(fd);
35 78a779a3 2008-07-20 rsc free(dir);
36 78a779a3 2008-07-20 rsc nexterror();
37 78a779a3 2008-07-20 rsc }
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){
44 78a779a3 2008-07-20 rsc if(fxf == 0)
45 78a779a3 2008-07-20 rsc fxf = xf;
46 78a779a3 2008-07-20 rsc continue;
47 78a779a3 2008-07-20 rsc }
48 78a779a3 2008-07-20 rsc if(xf->qid.path != dir->qid.path || xf->qid.vers != dir->qid.vers)
49 78a779a3 2008-07-20 rsc continue;
50 78a779a3 2008-07-20 rsc if(xf->type != dir->type || xf->fdev != dir->dev)
51 78a779a3 2008-07-20 rsc continue;
52 78a779a3 2008-07-20 rsc xf->ref++;
53 78a779a3 2008-07-20 rsc chat("incref=%d, \"%s\", dev=%d...", xf->ref, xf->name, xf->dev);
54 78a779a3 2008-07-20 rsc close(fd);
55 78a779a3 2008-07-20 rsc poperror();
56 78a779a3 2008-07-20 rsc free(dir);
57 78a779a3 2008-07-20 rsc return xf;
58 78a779a3 2008-07-20 rsc }
59 78a779a3 2008-07-20 rsc if(fxf==0){
60 78a779a3 2008-07-20 rsc fxf = ealloc(sizeof(Xfs));
61 78a779a3 2008-07-20 rsc fxf->next = xhead;
62 78a779a3 2008-07-20 rsc xhead = fxf;
63 78a779a3 2008-07-20 rsc }
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;
71 78a779a3 2008-07-20 rsc free(dir);
72 78a779a3 2008-07-20 rsc poperror();
73 78a779a3 2008-07-20 rsc return fxf;
74 78a779a3 2008-07-20 rsc }
75 78a779a3 2008-07-20 rsc
76 78a779a3 2008-07-20 rsc static void
77 78a779a3 2008-07-20 rsc putxdata(Xdata *d)
78 78a779a3 2008-07-20 rsc {
79 78a779a3 2008-07-20 rsc if(d->ref <= 0)
80 78a779a3 2008-07-20 rsc panic(0, "putxdata");
81 78a779a3 2008-07-20 rsc d->ref--;
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...");
85 78a779a3 2008-07-20 rsc purgebuf(d);
86 78a779a3 2008-07-20 rsc close(d->dev);
87 78a779a3 2008-07-20 rsc free(d->name);
88 78a779a3 2008-07-20 rsc d->name = 0;
89 78a779a3 2008-07-20 rsc }
90 78a779a3 2008-07-20 rsc }
91 78a779a3 2008-07-20 rsc
92 78a779a3 2008-07-20 rsc void
93 78a779a3 2008-07-20 rsc refxfs(Xfs *xf, int delta)
94 78a779a3 2008-07-20 rsc {
95 78a779a3 2008-07-20 rsc xf->ref += delta;
96 78a779a3 2008-07-20 rsc if(xf->ref == 0){
97 78a779a3 2008-07-20 rsc if(xf->d)
98 78a779a3 2008-07-20 rsc putxdata(xf->d);
99 78a779a3 2008-07-20 rsc if(xf->ptr)
100 78a779a3 2008-07-20 rsc free(xf->ptr);
101 78a779a3 2008-07-20 rsc free(xf);
102 78a779a3 2008-07-20 rsc }
103 78a779a3 2008-07-20 rsc }
104 78a779a3 2008-07-20 rsc
105 78a779a3 2008-07-20 rsc Xfile*
106 78a779a3 2008-07-20 rsc xfile(int fid, int flag)
107 78a779a3 2008-07-20 rsc {
108 78a779a3 2008-07-20 rsc int k = fid%FIDMOD;
109 78a779a3 2008-07-20 rsc Xfile **hp=&xfiles[k], *f, *pf;
110 78a779a3 2008-07-20 rsc
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)
113 78a779a3 2008-07-20 rsc break;
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;
117 78a779a3 2008-07-20 rsc *hp = f;
118 78a779a3 2008-07-20 rsc }
119 78a779a3 2008-07-20 rsc switch(flag){
120 78a779a3 2008-07-20 rsc default:
121 78a779a3 2008-07-20 rsc panic(0, "xfile");
122 78a779a3 2008-07-20 rsc case Asis:
123 78a779a3 2008-07-20 rsc if(f == 0)
124 78a779a3 2008-07-20 rsc error("unassigned fid");
125 78a779a3 2008-07-20 rsc return f;
126 78a779a3 2008-07-20 rsc case Clean:
127 78a779a3 2008-07-20 rsc break;
128 78a779a3 2008-07-20 rsc case Clunk:
129 78a779a3 2008-07-20 rsc if(f){
130 78a779a3 2008-07-20 rsc *hp = f->next;
131 78a779a3 2008-07-20 rsc clean(f);
132 78a779a3 2008-07-20 rsc f->next = freelist;
133 78a779a3 2008-07-20 rsc freelist = f;
134 78a779a3 2008-07-20 rsc }
135 78a779a3 2008-07-20 rsc return 0;
136 78a779a3 2008-07-20 rsc }
137 78a779a3 2008-07-20 rsc if(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;
141 78a779a3 2008-07-20 rsc else
142 78a779a3 2008-07-20 rsc f = ealloc(sizeof(Xfile));
143 78a779a3 2008-07-20 rsc f->next = *hp;
144 78a779a3 2008-07-20 rsc *hp = f;
145 78a779a3 2008-07-20 rsc f->xf = 0;
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};
149 78a779a3 2008-07-20 rsc f->len = 0;
150 78a779a3 2008-07-20 rsc f->ptr = 0;
151 78a779a3 2008-07-20 rsc return f;
152 78a779a3 2008-07-20 rsc }
153 78a779a3 2008-07-20 rsc
154 78a779a3 2008-07-20 rsc static Xfile *
155 78a779a3 2008-07-20 rsc clean(Xfile *f)
156 78a779a3 2008-07-20 rsc {
157 78a779a3 2008-07-20 rsc if(f->xf){
158 78a779a3 2008-07-20 rsc refxfs(f->xf, -1);
159 78a779a3 2008-07-20 rsc f->xf = 0;
160 78a779a3 2008-07-20 rsc }
161 78a779a3 2008-07-20 rsc if(f->len){
162 78a779a3 2008-07-20 rsc free(f->ptr);
163 78a779a3 2008-07-20 rsc f->len = 0;
164 78a779a3 2008-07-20 rsc }
165 78a779a3 2008-07-20 rsc f->ptr = 0;
166 78a779a3 2008-07-20 rsc f->flags = 0;
167 78a779a3 2008-07-20 rsc f->qid = (Qid){0,0,0};
168 78a779a3 2008-07-20 rsc return f;
169 78a779a3 2008-07-20 rsc }