1 #include "all.h"
2
3 static Xfile * xflfree;
4 static Xfid * xfdfree;
5
6 #define FIDMOD 127 /* prime */
7
8 static Xfile *xfiles[FIDMOD];
9 static Lock xlocks[FIDMOD];
10
11 Xfile *
xfile(Qid * qid,void * s,int new)12 xfile(Qid *qid, void *s, int new)
13 {
14 int k;
15 Xfile **hp, *f, *pf;
16
17 k = ((ulong)qid->path ^ (((u32int)(uintptr)s)<<24))%FIDMOD;
18 hp = &xfiles[k];
19
20 lock(&xlocks[k]);
21 for(f=*hp, pf=0; f; pf=f, f=f->next)
22 if(f->qid.path == qid->path
23 && (u32int)(uintptr)f->s == (u32int)(uintptr)s)
24 break;
25 if(f && pf){
26 pf->next = f->next;
27 f->next = *hp;
28 *hp = f;
29 }
30 if(new < 0 && f){
31 *hp = f->next;
32 f->next = xflfree;
33 xflfree = f;
34 f = 0;
35 }
36 if(new > 0 && !f){
37 if(!(f = xflfree)) /* assign = */
38 f = listalloc(1024/sizeof(Xfile), sizeof(Xfile));
39 xflfree = f->next;
40 memset(f, 0, sizeof(Xfile));
41 f->next = *hp;
42 *hp = f;
43 f->qid = *qid;
44 f->s = s;
45 }
46 unlock(&xlocks[k]);
47 return f;
48 }
49
50 Xfid *
xfid(char * uid,Xfile * xp,int new)51 xfid(char *uid, Xfile *xp, int new)
52 {
53 Xfid *f, *pf;
54
55 for(f=xp->users, pf=0; f; pf=f, f=f->next)
56 if(f->uid[0] == uid[0] && strcmp(f->uid, uid) == 0)
57 break;
58 if(f && pf){
59 pf->next = f->next;
60 f->next = xp->users;
61 xp->users = f;
62 }
63 if(new < 0 && f){
64 if(f->urfid)
65 clunkfid(xp->s, f->urfid);
66 if(f->opfid)
67 clunkfid(xp->s, f->opfid);
68 xp->users = f->next;
69 f->next = xfdfree;
70 xfdfree = f;
71 f = 0;
72 }
73 if(new > 0 && !f){
74 if(!(f = xfdfree)) /* assign = */
75 f = listalloc(1024/sizeof(Xfid), sizeof(Xfid));
76 xfdfree = f->next;
77 memset(f, 0, sizeof(Xfid));
78 f->next = xp->users;
79 xp->users = f;
80 f->xp = xp;
81 f->uid = strstore(uid);
82 f->urfid = 0;
83 f->opfid = 0;
84 }
85 return f;
86 }
87
88 int
xfpurgeuid(Session * s,char * uid)89 xfpurgeuid(Session *s, char *uid)
90 {
91 Xfile **hp, *f;
92 Xfid *xf;
93 int k, count=0;
94
95 for(k=0; k<FIDMOD; k++){
96 lock(&xlocks[k]);
97 hp=&xfiles[k];
98 for(f=*hp; f; f=f->next)
99 if(f->s == s && (xf = xfid(uid, f, 0))){ /* assign = */
100 xfclear(xf);
101 ++count;
102 }
103 unlock(&xlocks[k]);
104 }
105 return count;
106 }
107