xref: /plan9/sys/src/cmd/9nfs/xfile.c (revision 4de34a7edde43207e841ec91ecd12e6cf5f5ebe7)
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