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_tlsv12/sys/src/cmd/ext2srv/iobuf.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
#define	NIOBUF		100
10
#define	HIOB		(NIOBUF/3)
11
 
12
static Iobuf*	hiob[HIOB];		/* hash buckets */
13
static Iobuf	iobuf[NIOBUF];		/* buffer headers */
14
static Iobuf*	iohead;
15
static Iobuf*	iotail;
16
 
17
Iobuf*
18
getbuf(Xfs *dev, long addr)
19
{
20
	Iobuf *p, *h, **l, **f;
21
 
22
	l = &hiob[addr%HIOB];
23
	for(p = *l; p; p = p->hash) {
24
		if(p->addr == addr && p->dev == dev) {
25
			p->busy++;
26
			return p;
27
		}
28
	}
29
	/* Find a non-busy buffer from the tail */
30
	for(p = iotail; p && (p->busy > 0); p = p->prev)
31
		;
32
	if(!p)
33
		panic("all buffers busy");
34
	if(p->dirty){
35
		xwrite(p);
36
		p->dirty = 0;
37
	}
38
 
39
	if( xread(dev, p, addr) < 0)
40
		return 0;
41
	/* Delete from hash chain */
42
	f = &hiob[p->addr%HIOB];
43
	if( *f == p )
44
		*f = p->hash;
45
	else {
46
		for(h = *f; h ; h = h->hash)
47
			if( h->hash == p ){
48
				h->hash = p->hash;
49
				break;
50
			}
51
	}
52
	/* Fill and hash */
53
	p->hash = *l;
54
	*l = p;
55
	p->addr = addr;
56
	p->dev = dev;
57
	p->busy=1;
58
 
59
	return p;
60
}
61
void
62
putbuf(Iobuf *p)
63
{
64
	if(p->busy <= 0)
65
		panic("putbuf");
66
	p->busy--;
67
 
68
	/* Link onto head for lru */
69
	if(p == iohead)
70
		return;
71
	if( p == iotail ){
72
		p->prev->next = 0;
73
		iotail = p->prev;
74
	}else{
75
		p->prev->next = p->next;
76
		p->next->prev = p->prev;
77
	}
78
 
79
	p->prev = 0;
80
	p->next = iohead;
81
	iohead->prev = p;
82
	iohead = p;
83
}
84
void
85
dirtybuf(Iobuf *p)
86
{
87
	if(p->busy <=0)
88
		panic("dirtybuf");
89
	p->dirty = 1;
90
}
91
void
92
syncbuf(void)
93
{
94
	Iobuf *p;
95
 
96
	for(p=&iobuf[0] ; p<&iobuf[NIOBUF]; p++)
97
		if( p->dirty ){
98
			xwrite(p);
99
			p->dirty = 0;
100
		}
101
}
102
void
103
purgebuf(Xfs *dev)
104
{
105
	Iobuf *p;
106
 
107
	for(p=&iobuf[0]; p<&iobuf[NIOBUF]; p++)
108
		if(p->dev == dev)
109
			p->busy = 0;
110
 
111
	/* Blow hash chains */
112
	memset(hiob, 0, sizeof(hiob));
113
}
114
void
115
iobuf_init(void)
116
{
117
	Iobuf *p;
118
 
119
	iohead = iobuf;
120
	iotail = iobuf+NIOBUF-1;
121
 
122
	for(p = iobuf; p <= iotail; p++) {
123
		p->next = p+1;
124
		p->prev = p-1;
125
 
126
		p->iobuf = (char *)malloc(EXT2_MAX_BLOCK_SIZE);
127
		if(p->iobuf == 0)
128
			panic("iobuf_init");
129
	}
130
 
131
	iohead->prev = 0;
132
	iotail->next = 0;
133
}
134
int
135
xread(Xfs *dev, Iobuf *p, long addr)
136
{
137
	/*chat("xread %d,%d...", dev->dev, addr);*/
138
 
139
	seek(dev->dev, (vlong)addr*dev->block_size, 0);
140
	if(read(dev->dev, p->iobuf, dev->block_size) != dev->block_size){
141
		chat("xread %d, block=%d failed ...", dev->dev, addr);
142
		errno = Eio;
143
		return -1;
144
	}
145
	/*chat("xread ok...");*/
146
	return 0;
147
}
148
void 
149
xwrite(Iobuf *p)
150
{
151
	Xfs *dev;
152
	long addr;
153
 
154
	dev = p->dev;
155
	addr = p->addr;
156
	/*chat("xwrite %d,%d...", dev->dev, addr);*/
157
 
158
	seek(dev->dev, (vlong)addr*dev->block_size, 0);
159
	if(write(dev->dev, p->iobuf, dev->block_size) != dev->block_size){
160
		chat("xwrite %d, block=%d failed ...", dev->dev, addr);
161
		errno = Eio;
162
		return;
163
	}
164
	/*chat("xwrite ok...");*/
165
}
166
void
167
dumpbuf(void)
168
{
169
	Iobuf *p;
170
 
171
	for(p = iotail; p ; p = p->prev)
172
		if( p->busy )
173
			mchat("\nHi ERROR buf(%x, %d, %d)\n", p, p->addr, p->busy);	
174
}