xref: /plan9/sys/src/cmd/9nfs/xfile.c (revision 4de34a7edde43207e841ec91ecd12e6cf5f5ebe7)
19a747e4fSDavid du Colombier #include "all.h"
29a747e4fSDavid du Colombier 
39a747e4fSDavid du Colombier static Xfile *	xflfree;
49a747e4fSDavid du Colombier static Xfid *	xfdfree;
59a747e4fSDavid du Colombier 
69a747e4fSDavid du Colombier #define	FIDMOD	127	/* prime */
79a747e4fSDavid du Colombier 
89a747e4fSDavid du Colombier static Xfile	*xfiles[FIDMOD];
99a747e4fSDavid du Colombier static Lock	xlocks[FIDMOD];
109a747e4fSDavid du Colombier 
119a747e4fSDavid du Colombier Xfile *
xfile(Qid * qid,void * s,int new)129a747e4fSDavid du Colombier xfile(Qid *qid, void *s, int new)
139a747e4fSDavid du Colombier {
149a747e4fSDavid du Colombier 	int k;
159a747e4fSDavid du Colombier 	Xfile **hp, *f, *pf;
169a747e4fSDavid du Colombier 
17*4de34a7eSDavid du Colombier 	k = ((ulong)qid->path ^ (((u32int)(uintptr)s)<<24))%FIDMOD;
189a747e4fSDavid du Colombier 	hp = &xfiles[k];
199a747e4fSDavid du Colombier 
209a747e4fSDavid du Colombier 	lock(&xlocks[k]);
219a747e4fSDavid du Colombier 	for(f=*hp, pf=0; f; pf=f, f=f->next)
22*4de34a7eSDavid du Colombier 		if(f->qid.path == qid->path
23*4de34a7eSDavid du Colombier 		&& (u32int)(uintptr)f->s == (u32int)(uintptr)s)
249a747e4fSDavid du Colombier 			break;
259a747e4fSDavid du Colombier 	if(f && pf){
269a747e4fSDavid du Colombier 		pf->next = f->next;
279a747e4fSDavid du Colombier 		f->next = *hp;
289a747e4fSDavid du Colombier 		*hp = f;
299a747e4fSDavid du Colombier 	}
309a747e4fSDavid du Colombier 	if(new < 0 && f){
319a747e4fSDavid du Colombier 		*hp = f->next;
329a747e4fSDavid du Colombier 		f->next = xflfree;
339a747e4fSDavid du Colombier 		xflfree = f;
349a747e4fSDavid du Colombier 		f = 0;
359a747e4fSDavid du Colombier 	}
369a747e4fSDavid du Colombier 	if(new > 0 && !f){
379a747e4fSDavid du Colombier 		if(!(f = xflfree))	/* assign = */
389a747e4fSDavid du Colombier 			f = listalloc(1024/sizeof(Xfile), sizeof(Xfile));
399a747e4fSDavid du Colombier 		xflfree = f->next;
409a747e4fSDavid du Colombier 		memset(f, 0, sizeof(Xfile));
419a747e4fSDavid du Colombier 		f->next = *hp;
429a747e4fSDavid du Colombier 		*hp = f;
439a747e4fSDavid du Colombier 		f->qid = *qid;
449a747e4fSDavid du Colombier 		f->s = s;
459a747e4fSDavid du Colombier 	}
469a747e4fSDavid du Colombier 	unlock(&xlocks[k]);
479a747e4fSDavid du Colombier 	return f;
489a747e4fSDavid du Colombier }
499a747e4fSDavid du Colombier 
509a747e4fSDavid du Colombier Xfid *
xfid(char * uid,Xfile * xp,int new)519a747e4fSDavid du Colombier xfid(char *uid, Xfile *xp, int new)
529a747e4fSDavid du Colombier {
539a747e4fSDavid du Colombier 	Xfid *f, *pf;
549a747e4fSDavid du Colombier 
559a747e4fSDavid du Colombier 	for(f=xp->users, pf=0; f; pf=f, f=f->next)
569a747e4fSDavid du Colombier 		if(f->uid[0] == uid[0] && strcmp(f->uid, uid) == 0)
579a747e4fSDavid du Colombier 			break;
589a747e4fSDavid du Colombier 	if(f && pf){
599a747e4fSDavid du Colombier 		pf->next = f->next;
609a747e4fSDavid du Colombier 		f->next = xp->users;
619a747e4fSDavid du Colombier 		xp->users = f;
629a747e4fSDavid du Colombier 	}
639a747e4fSDavid du Colombier 	if(new < 0 && f){
649a747e4fSDavid du Colombier 		if(f->urfid)
659a747e4fSDavid du Colombier 			clunkfid(xp->s, f->urfid);
669a747e4fSDavid du Colombier 		if(f->opfid)
679a747e4fSDavid du Colombier 			clunkfid(xp->s, f->opfid);
689a747e4fSDavid du Colombier 		xp->users = f->next;
699a747e4fSDavid du Colombier 		f->next = xfdfree;
709a747e4fSDavid du Colombier 		xfdfree = f;
719a747e4fSDavid du Colombier 		f = 0;
729a747e4fSDavid du Colombier 	}
739a747e4fSDavid du Colombier 	if(new > 0 && !f){
749a747e4fSDavid du Colombier 		if(!(f = xfdfree))	/* assign = */
759a747e4fSDavid du Colombier 			f = listalloc(1024/sizeof(Xfid), sizeof(Xfid));
769a747e4fSDavid du Colombier 		xfdfree = f->next;
779a747e4fSDavid du Colombier 		memset(f, 0, sizeof(Xfid));
789a747e4fSDavid du Colombier 		f->next = xp->users;
799a747e4fSDavid du Colombier 		xp->users = f;
809a747e4fSDavid du Colombier 		f->xp = xp;
819a747e4fSDavid du Colombier 		f->uid = strstore(uid);
829a747e4fSDavid du Colombier 		f->urfid = 0;
839a747e4fSDavid du Colombier 		f->opfid = 0;
849a747e4fSDavid du Colombier 	}
859a747e4fSDavid du Colombier 	return f;
869a747e4fSDavid du Colombier }
879a747e4fSDavid du Colombier 
889a747e4fSDavid du Colombier int
xfpurgeuid(Session * s,char * uid)899a747e4fSDavid du Colombier xfpurgeuid(Session *s, char *uid)
909a747e4fSDavid du Colombier {
919a747e4fSDavid du Colombier 	Xfile **hp, *f;
929a747e4fSDavid du Colombier 	Xfid *xf;
939a747e4fSDavid du Colombier 	int k, count=0;
949a747e4fSDavid du Colombier 
959a747e4fSDavid du Colombier 	for(k=0; k<FIDMOD; k++){
969a747e4fSDavid du Colombier 		lock(&xlocks[k]);
979a747e4fSDavid du Colombier 		hp=&xfiles[k];
989a747e4fSDavid du Colombier 		for(f=*hp; f; f=f->next)
999a747e4fSDavid du Colombier 			if(f->s == s && (xf = xfid(uid, f, 0))){ /* assign = */
1009a747e4fSDavid du Colombier 				xfclear(xf);
1019a747e4fSDavid du Colombier 				++count;
1029a747e4fSDavid du Colombier 			}
1039a747e4fSDavid du Colombier 		unlock(&xlocks[k]);
1049a747e4fSDavid du Colombier 	}
1059a747e4fSDavid du Colombier 	return count;
1069a747e4fSDavid du Colombier }
107