xref: /plan9-contrib/sys/src/cmd/disk/kfs/dentry.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
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 		p->flags |= Bmod;
21 		t = time();
22 		if(f & (FREAD|FWRITE))
23 			d->atime = t;
24 		if(f & FWRITE) {
25 			d->mtime = t;
26 			d->qid.version++;
27 		}
28 	}
29 }
30 
31 void
32 dbufread(Iobuf *p, Dentry *d, long a)
33 {
34 	USED(p, d, a);
35 }
36 
37 Iobuf*
38 dnodebuf(Iobuf *p, Dentry *d, long a, int tag)
39 {
40 	Iobuf *bp;
41 	long addr;
42 
43 	if(a < 0) {
44 		print("dnodebuf: neg\n");
45 		return 0;
46 	}
47 	bp = 0;
48 	if(a < NDBLOCK) {
49 		addr = d->dblock[a];
50 		if(addr)
51 			return getbuf(p->dev, addr, Bread);
52 		if(tag) {
53 			addr = balloc(p->dev, tag, d->qid.path);
54 			if(addr) {
55 				d->dblock[a] = addr;
56 				p->flags |= Bmod|Bimm;
57 				bp = getbuf(p->dev, addr, Bmod);
58 			}
59 		}
60 		return bp;
61 	}
62 	a -= NDBLOCK;
63 	if(a < INDPERBUF) {
64 		addr = d->iblock;
65 		if(!addr && tag) {
66 			addr = balloc(p->dev, Tind1, d->qid.path);
67 			d->iblock = addr;
68 			p->flags |= Bmod|Bimm;
69 		}
70 		addr = indfetch(p, d, addr, a, Tind1, tag);
71 		if(addr)
72 			bp = getbuf(p->dev, addr, Bread);
73 		return bp;
74 	}
75 	a -= INDPERBUF;
76 	if(a < INDPERBUF2) {
77 		addr = d->diblock;
78 		if(!addr && tag) {
79 			addr = balloc(p->dev, Tind2, d->qid.path);
80 			d->diblock = addr;
81 			p->flags |= Bmod|Bimm;
82 		}
83 		addr = indfetch(p, d, addr, a/INDPERBUF, Tind2, Tind1);
84 		addr = indfetch(p, d, addr, a%INDPERBUF, Tind1, tag);
85 		if(addr)
86 			bp = getbuf(p->dev, addr, Bread);
87 		return bp;
88 	}
89 	print("dnodebuf: trip indirect\n");
90 	return 0;
91 }
92 
93 long
94 indfetch(Iobuf *p, Dentry *d, long addr, long a, int itag, int tag)
95 {
96 	Iobuf *bp;
97 
98 	if(!addr)
99 		return 0;
100 	bp = getbuf(p->dev, addr, Bread);
101 	if(!bp || checktag(bp, itag, d->qid.path)) {
102 		if(!bp) {
103 			print("ind fetch bp = 0\n");
104 			return 0;
105 		}
106 		print("ind fetch tag\n");
107 		putbuf(bp);
108 		return 0;
109 	}
110 	addr = ((long*)bp->iobuf)[a];
111 	if(!addr && tag) {
112 		addr = balloc(p->dev, tag, d->qid.path);
113 		if(addr) {
114 			((long*)bp->iobuf)[a] = addr;
115 			bp->flags |= Bmod;
116 			if(localfs || tag == Tdir)
117 				bp->flags |= Bimm;
118 			settag(bp, itag, d->qid.path);
119 		}
120 	}
121 	putbuf(bp);
122 	return addr;
123 }
124 
125 void
126 dtrunc(Iobuf *p, Dentry *d)
127 {
128 	int i;
129 
130 	bfree(p->dev, d->diblock, 2);
131 	d->diblock = 0;
132 	bfree(p->dev, d->iblock, 1);
133 	d->iblock = 0;
134 	for(i=NDBLOCK-1; i>=0; i--) {
135 		bfree(p->dev, d->dblock[i], 0);
136 		d->dblock[i] = 0;
137 	}
138 	d->size = 0;
139 	p->flags |= Bmod|Bimm;
140 	accessdir(p, d, FWRITE);
141 }
142