Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include	"all.h"
2
 
3
Dentry*
4
getdir(Iobuf *p, int slot)
5
{
6
	Dentry *d;
7
 
8
	if(!p)
9
		return 0;
10
	d = (Dentry*)p->iobuf + slot%DIRPERBUF;
11
	return d;
12
}
13
 
14
void
15
accessdir(Iobuf *p, Dentry *d, int f)
16
{
17
	long t;
18
 
19
	if(p && !isro(p->dev)) {
20
		if(!(f & (FWRITE|FWSTAT)) && noatime)
21
			return;
22
		t = time(nil);
23
		if(f & (FREAD|FWRITE|FWSTAT)){
24
			d->atime = t;
25
			p->flags |= Bmod;
26
		}
27
		if(f & FWRITE) {
28
			d->mtime = t;
29
			d->qid.version++;
30
			p->flags |= Bmod;
31
		}
32
	}
33
}
34
 
35
void
36
dbufread(Iobuf *p, Dentry *d, long a)
37
{
38
	USED(p, d, a);
39
}
40
 
41
long
42
rel2abs(Iobuf *p, Dentry *d, long a, int tag, int putb)
43
{
44
	long addr, qpath;
45
	Device dev;
46
 
47
	if(a < 0) {
48
		print("dnodebuf: neg\n");
49
		return 0;
50
	}
51
	qpath = d->qid.path;
52
	dev = p->dev;
53
	if(a < NDBLOCK) {
54
		addr = d->dblock[a];
55
		if(!addr && tag) {
56
			addr = balloc(dev, tag, qpath);
57
			d->dblock[a] = addr;
58
			p->flags |= Bmod|Bimm;
59
		}
60
		if(putb)
61
			putbuf(p);
62
		return addr;
63
	}
64
	a -= NDBLOCK;
65
	if(a < INDPERBUF) {
66
		addr = d->iblock;
67
		if(!addr && tag) {
68
			addr = balloc(dev, Tind1, qpath);
69
			d->iblock = addr;
70
			p->flags |= Bmod|Bimm;
71
		}
72
		if(putb)
73
			putbuf(p);
74
		addr = indfetch(p, d, addr, a, Tind1, tag);
75
		return addr;
76
	}
77
	a -= INDPERBUF;
78
	if(a < INDPERBUF2) {
79
		addr = d->diblock;
80
		if(!addr && tag) {
81
			addr = balloc(dev, Tind2, qpath);
82
			d->diblock = addr;
83
			p->flags |= Bmod|Bimm;
84
		}
85
		if(putb)
86
			putbuf(p);
87
		addr = indfetch(p, d, addr, a/INDPERBUF, Tind2, Tind1);
88
		addr = indfetch(p, d, addr, a%INDPERBUF, Tind1, tag);
89
		return addr;
90
	}
91
	if(putb)
92
		putbuf(p);
93
	print("dnodebuf: trip indirect\n");
94
	return 0;
95
}
96
 
97
Iobuf*
98
dnodebuf(Iobuf *p, Dentry *d, long a, int tag)
99
{
100
	long addr;
101
 
102
	addr = rel2abs(p, d, a, tag, 0);
103
	if(addr)
104
		return getbuf(p->dev, addr, Bread);
105
	return 0;
106
}
107
 
108
/*
109
 * same as dnodebuf but it calls putpuf(p)
110
 * to reduce interference.
111
 */
112
Iobuf*
113
dnodebuf1(Iobuf *p, Dentry *d, long a, int tag)
114
{
115
	long addr;
116
	Device dev;
117
 
118
	dev = p->dev;
119
	addr = rel2abs(p, d, a, tag, 1);
120
	if(addr)
121
		return getbuf(dev, addr, Bread);
122
	return 0;
123
 
124
}
125
 
126
long
127
indfetch(Iobuf *p, Dentry *d, long addr, long a, int itag, int tag)
128
{
129
	Iobuf *bp;
130
 
131
	if(!addr)
132
		return 0;
133
	bp = getbuf(p->dev, addr, Bread);
134
	if(!bp || checktag(bp, itag, d->qid.path)) {
135
		if(!bp) {
136
			print("ind fetch bp = 0\n");
137
			return 0;
138
		}
139
		print("ind fetch tag\n");
140
		putbuf(bp);
141
		return 0;
142
	}
143
	addr = ((long*)bp->iobuf)[a];
144
	if(!addr && tag) {
145
		addr = balloc(p->dev, tag, d->qid.path);
146
		if(addr) {
147
			((long*)bp->iobuf)[a] = addr;
148
			bp->flags |= Bmod;
149
			if(localfs || tag == Tdir)
150
				bp->flags |= Bimm;
151
			settag(bp, itag, d->qid.path);
152
		}
153
	}
154
	putbuf(bp);
155
	return addr;
156
}
157
 
158
void
159
dtrunc(Iobuf *p, Dentry *d)
160
{
161
	int i;
162
 
163
	bfree(p->dev, d->diblock, 2);
164
	d->diblock = 0;
165
	bfree(p->dev, d->iblock, 1);
166
	d->iblock = 0;
167
	for(i=NDBLOCK-1; i>=0; i--) {
168
		bfree(p->dev, d->dblock[i], 0);
169
		d->dblock[i] = 0;
170
	}
171
	d->size = 0;
172
	p->flags |= Bmod|Bimm;
173
	accessdir(p, d, FWRITE);
174
}