Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_fixcpp/sys/src/cmd/ext2srv/xfile.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <fcall.h>
4
#include <thread.h>
5
#include <9p.h>
6
#include "dat.h"
7
#include "fns.h"
8
 
9
 
10
static Xfs	*xhead;
11
static Xfile *freelist;
12
static Lock	xlock, freelock;
13
 
14
int	client;
15
 
16
Xfs *
17
getxfs(char *name)
18
{
19
	int fd;
20
	Dir *dir;
21
	Xfs *xf, *fxf;
22
 
23
	if(name==0 || name[0]==0)
24
		name = deffile;
25
	if(name == 0){
26
		errno = Enofilsys;
27
		return 0;
28
	}
29
	fd = open(name, rdonly ? OREAD : ORDWR);
30
	if(fd < 0){
31
		errno = Enonexist;
32
		return 0;
33
	}
34
	if((dir = dirfstat(fd)) == 0){
35
		errno = Eio;
36
		close(fd);
37
		return 0;
38
	}
39
	lock(&xlock);
40
	for(fxf=0, xf=xhead; xf; xf=xf->next){
41
		if(xf->ref == 0){
42
			if(fxf == 0)
43
				fxf = xf;
44
			continue;
45
		}
46
		if(xf->qid.path != dir->qid.path || xf->qid.vers != dir->qid.vers)
47
			continue;
48
		if(strcmp(xf->name, name) != 0 || xf->dev < 0)
49
			continue;
50
		chat("incref \"%s\", dev=%d...", xf->name, xf->dev);
51
		++xf->ref;
52
		unlock(&xlock);
53
		close(fd);
54
		free(dir);
55
		return xf;
56
	}
57
	if(fxf==0){
58
		fxf = malloc(sizeof(Xfs));
59
		if(fxf==0){
60
			unlock(&xlock);
61
			close(fd);
62
			free(dir);
63
			errno = Enomem;
64
			return 0;
65
		}
66
		fxf->next = xhead;
67
		xhead = fxf;
68
	}
69
	chat("alloc \"%s\", dev=%d...", name, fd);
70
	fxf->name = strdup(name);
71
	fxf->ref = 1;
72
	fxf->qid = dir->qid;
73
	fxf->dev = fd;
74
	fxf->fmt = 0;
75
	fxf->ptr = 0;
76
	free(dir);
77
	if( ext2fs(fxf)<0 ){ 
78
		xhead = fxf->next;
79
		free(fxf);
80
		unlock(&xlock);
81
		return 0;
82
	}
83
	unlock(&xlock);
84
	return fxf;
85
}
86
 
87
void
88
refxfs(Xfs *xf, int delta)
89
{
90
	lock(&xlock);
91
	xf->ref += delta;
92
	if(xf->ref == 0){
93
		/*mchat("free \"%s\", dev=%d...", xf->name, xf->dev);
94
		dumpbuf();*/
95
		CleanSuper(xf);
96
		syncbuf();
97
		free(xf->name);
98
		purgebuf(xf);
99
		if(xf->dev >= 0){
100
			close(xf->dev);
101
			xf->dev = -1;
102
		}
103
	}
104
	unlock(&xlock);
105
}
106
 
107
Xfile *
108
xfile(Fid *fid, int flag)
109
{
110
	Xfile *f;
111
 
112
	f = (Xfile*)fid->aux;
113
	switch(flag){
114
	default:
115
		panic("xfile");
116
	case Asis:
117
		return (f && f->xf && f->xf->dev < 0) ? 0 : f;
118
	case Clean:
119
		if (f) chat("Clean and fid->aux already exists\n");
120
		break;
121
	case Clunk:
122
		if(f){
123
			clean(f);
124
			lock(&freelock);
125
			f->next = freelist;
126
			freelist = f;
127
			unlock(&freelock);
128
			fid->aux = 0;
129
		}
130
		return 0;
131
	}
132
	if(f)
133
		return clean(f);
134
	lock(&freelock);
135
	if(f = freelist){	/* assign = */
136
		freelist = f->next;
137
		unlock(&freelock);
138
	} else {
139
		unlock(&freelock);
140
		f = malloc(sizeof(Xfile));
141
	}
142
	fid->aux = f;
143
	f->fid = fid->fid;
144
	f->client = client;
145
	f->xf = 0;
146
	f->ptr = 0;
147
	f->root = 0;
148
	return f;
149
}
150
Xfile *
151
clean(Xfile *f)
152
{
153
	if(f->xf && f->root){
154
		refxfs(f->xf, -1);
155
		f->xf = 0;
156
	}
157
	f->xf = 0;
158
	f->root = 0;
159
	f->dirindex = 0;
160
	return f;
161
}