Blame


1 0c98da8b 2005-07-13 devnull #include <u.h>
2 0c98da8b 2005-07-13 devnull #include <libc.h>
3 0c98da8b 2005-07-13 devnull #include <diskfs.h>
4 0c98da8b 2005-07-13 devnull #include <venti.h>
5 0c98da8b 2005-07-13 devnull
6 0c98da8b 2005-07-13 devnull extern void vtlibthread(void);
7 0c98da8b 2005-07-13 devnull
8 0c98da8b 2005-07-13 devnull typedef struct DiskVenti DiskVenti;
9 0c98da8b 2005-07-13 devnull struct DiskVenti
10 0c98da8b 2005-07-13 devnull {
11 0c98da8b 2005-07-13 devnull Disk disk;
12 0c98da8b 2005-07-13 devnull VtEntry e;
13 0c98da8b 2005-07-13 devnull VtCache *c;
14 0c98da8b 2005-07-13 devnull };
15 0c98da8b 2005-07-13 devnull
16 d3285dcb 2005-12-16 devnull extern int nfilereads;
17 6519f895 2007-11-05 rsc extern void _nfilereads_darwin_sucks(void);
18 0c98da8b 2005-07-13 devnull
19 0c98da8b 2005-07-13 devnull /*
20 0c98da8b 2005-07-13 devnull * This part is like file.c but doesn't require storing the root block
21 0c98da8b 2005-07-13 devnull * in the cache permanently and doesn't care about locking since
22 0c98da8b 2005-07-13 devnull * all the blocks are read-only. Perhaps at some point this functionality
23 0c98da8b 2005-07-13 devnull * should go into libvac in some form.
24 0c98da8b 2005-07-13 devnull */
25 0c98da8b 2005-07-13 devnull static int
26 0c98da8b 2005-07-13 devnull vtfileindices(VtEntry *e, u32int bn, int *index)
27 0c98da8b 2005-07-13 devnull {
28 0c98da8b 2005-07-13 devnull int i, np;
29 0c98da8b 2005-07-13 devnull
30 0c98da8b 2005-07-13 devnull memset(index, 0, VtPointerDepth*sizeof(int));
31 0c98da8b 2005-07-13 devnull
32 0c98da8b 2005-07-13 devnull np = e->psize/VtScoreSize;
33 0c98da8b 2005-07-13 devnull memset(index, 0, sizeof(index));
34 0c98da8b 2005-07-13 devnull for(i=0; bn > 0; i++){
35 0c98da8b 2005-07-13 devnull if(i >= VtPointerDepth){
36 0c98da8b 2005-07-13 devnull werrstr("bad block number %lud", (ulong)bn);
37 0c98da8b 2005-07-13 devnull return -1;
38 0c98da8b 2005-07-13 devnull }
39 0c98da8b 2005-07-13 devnull index[i] = bn % np;
40 0c98da8b 2005-07-13 devnull bn /= np;
41 0c98da8b 2005-07-13 devnull }
42 0c98da8b 2005-07-13 devnull return i;
43 0c98da8b 2005-07-13 devnull }
44 0c98da8b 2005-07-13 devnull
45 e77222a4 2006-05-04 devnull VtBlock *_vtfileblock(VtCache*, VtEntry*, u32int); /* avoid auto-inline by putting later in file */
46 0c98da8b 2005-07-13 devnull static void
47 0c98da8b 2005-07-13 devnull diskventiblockput(Block *b)
48 0c98da8b 2005-07-13 devnull {
49 0c98da8b 2005-07-13 devnull vtblockput(b->priv);
50 0c98da8b 2005-07-13 devnull free(b);
51 0c98da8b 2005-07-13 devnull }
52 0c98da8b 2005-07-13 devnull
53 0c98da8b 2005-07-13 devnull static Block*
54 0c98da8b 2005-07-13 devnull diskventiread(Disk *dd, u32int len, u64int offset)
55 0c98da8b 2005-07-13 devnull {
56 0c98da8b 2005-07-13 devnull DiskVenti *d = (DiskVenti*)dd;
57 0c98da8b 2005-07-13 devnull VtBlock *vb;
58 0c98da8b 2005-07-13 devnull Block *b;
59 0c98da8b 2005-07-13 devnull int frag;
60 0c98da8b 2005-07-13 devnull
61 0c98da8b 2005-07-13 devnull nfilereads++;
62 0c98da8b 2005-07-13 devnull vb = _vtfileblock(d->c, &d->e, offset/d->e.dsize);
63 0c98da8b 2005-07-13 devnull if(vb == nil)
64 0c98da8b 2005-07-13 devnull return nil;
65 0c98da8b 2005-07-13 devnull
66 0c98da8b 2005-07-13 devnull b = mallocz(sizeof(Block), 1);
67 0c98da8b 2005-07-13 devnull if(b == nil){
68 0c98da8b 2005-07-13 devnull vtblockput(vb);
69 0c98da8b 2005-07-13 devnull return nil;
70 0c98da8b 2005-07-13 devnull }
71 0c98da8b 2005-07-13 devnull
72 0c98da8b 2005-07-13 devnull b->priv = vb;
73 0c98da8b 2005-07-13 devnull b->_close = diskventiblockput;
74 0c98da8b 2005-07-13 devnull frag = offset%d->e.dsize;
75 0c98da8b 2005-07-13 devnull b->data = (uchar*)vb->data + frag;
76 0c98da8b 2005-07-13 devnull b->len = d->e.dsize - frag;
77 0c98da8b 2005-07-13 devnull if(b->len > len)
78 0c98da8b 2005-07-13 devnull b->len = len;
79 0c98da8b 2005-07-13 devnull return b;
80 0c98da8b 2005-07-13 devnull }
81 0c98da8b 2005-07-13 devnull
82 e77222a4 2006-05-04 devnull VtBlock*
83 e77222a4 2006-05-04 devnull _vtfileblock(VtCache *c, VtEntry *e, u32int bn)
84 e77222a4 2006-05-04 devnull {
85 cd27286e 2006-05-05 devnull VtBlock *b;
86 e77222a4 2006-05-04 devnull int i, d, index[VtPointerDepth+1], t;
87 e77222a4 2006-05-04 devnull uchar score[VtScoreSize];
88 e77222a4 2006-05-04 devnull
89 e77222a4 2006-05-04 devnull i = vtfileindices(e, bn, index);
90 e77222a4 2006-05-04 devnull if(i < 0)
91 e77222a4 2006-05-04 devnull return nil;
92 e77222a4 2006-05-04 devnull d = (e->type&VtTypeDepthMask);
93 e77222a4 2006-05-04 devnull if(i > d){
94 e77222a4 2006-05-04 devnull werrstr("bad address %d > %d (%x %x)", i, d, e->type, e->flags);
95 e77222a4 2006-05-04 devnull return nil;
96 e77222a4 2006-05-04 devnull }
97 e77222a4 2006-05-04 devnull
98 e77222a4 2006-05-04 devnull /*fprint(2, "vtread %V\n", e->score); */
99 75d04888 2009-05-25 rsc b = vtcacheglobal(c, e->score, e->type, d == 0 ? e->dsize : e->psize);
100 e77222a4 2006-05-04 devnull for(i=d-1; i>=0 && b; i--){
101 e77222a4 2006-05-04 devnull t = VtDataType+i;
102 e77222a4 2006-05-04 devnull /*fprint(2, "vtread %V\n", b->data+index[i]*VtScoreSize); */
103 e77222a4 2006-05-04 devnull memmove(score, b->data+index[i]*VtScoreSize, VtScoreSize);
104 e77222a4 2006-05-04 devnull vtblockput(b);
105 75d04888 2009-05-25 rsc b = vtcacheglobal(c, score, t, i == 0 ? e->dsize : e->psize);
106 e77222a4 2006-05-04 devnull }
107 e77222a4 2006-05-04 devnull return b;
108 e77222a4 2006-05-04 devnull }
109 e77222a4 2006-05-04 devnull
110 0c98da8b 2005-07-13 devnull static void
111 0c98da8b 2005-07-13 devnull diskventiclose(Disk *dd)
112 0c98da8b 2005-07-13 devnull {
113 0c98da8b 2005-07-13 devnull DiskVenti *d = (DiskVenti*)dd;
114 0c98da8b 2005-07-13 devnull free(d);
115 0c98da8b 2005-07-13 devnull }
116 0c98da8b 2005-07-13 devnull
117 0c98da8b 2005-07-13 devnull Disk*
118 0c98da8b 2005-07-13 devnull diskopenventi(VtCache *c, uchar score[VtScoreSize])
119 0c98da8b 2005-07-13 devnull {
120 0c98da8b 2005-07-13 devnull DiskVenti *d;
121 0c98da8b 2005-07-13 devnull VtEntry e;
122 0c98da8b 2005-07-13 devnull VtRoot root;
123 0c98da8b 2005-07-13 devnull VtBlock *b;
124 0c98da8b 2005-07-13 devnull
125 75d04888 2009-05-25 rsc if((b = vtcacheglobal(c, score, VtRootType, VtRootSize)) == nil)
126 0c98da8b 2005-07-13 devnull goto Err;
127 0c98da8b 2005-07-13 devnull if(vtrootunpack(&root, b->data) < 0)
128 0c98da8b 2005-07-13 devnull goto Err;
129 0c98da8b 2005-07-13 devnull if(root.blocksize < 512 || (root.blocksize&(root.blocksize-1))){
130 0c98da8b 2005-07-13 devnull werrstr("bad blocksize %d", root.blocksize);
131 0c98da8b 2005-07-13 devnull goto Err;
132 0c98da8b 2005-07-13 devnull }
133 0c98da8b 2005-07-13 devnull vtblockput(b);
134 0c98da8b 2005-07-13 devnull
135 75d04888 2009-05-25 rsc if((b = vtcacheglobal(c, root.score, VtDirType, VtEntrySize)) == nil)
136 0c98da8b 2005-07-13 devnull goto Err;
137 0c98da8b 2005-07-13 devnull if(vtentryunpack(&e, b->data, 0) < 0)
138 0c98da8b 2005-07-13 devnull goto Err;
139 0c98da8b 2005-07-13 devnull vtblockput(b);
140 0c98da8b 2005-07-13 devnull b = nil;
141 0c98da8b 2005-07-13 devnull if((e.type&VtTypeBaseMask) != VtDataType){
142 0c98da8b 2005-07-13 devnull werrstr("not a single file");
143 0c98da8b 2005-07-13 devnull goto Err;
144 0c98da8b 2005-07-13 devnull }
145 0c98da8b 2005-07-13 devnull
146 0c98da8b 2005-07-13 devnull d = mallocz(sizeof(DiskVenti), 1);
147 0c98da8b 2005-07-13 devnull if(d == nil)
148 0c98da8b 2005-07-13 devnull goto Err;
149 0c98da8b 2005-07-13 devnull
150 0c98da8b 2005-07-13 devnull d->disk._read = diskventiread;
151 0c98da8b 2005-07-13 devnull d->disk._close = diskventiclose;
152 0c98da8b 2005-07-13 devnull d->e = e;
153 0c98da8b 2005-07-13 devnull d->c = c;
154 0c98da8b 2005-07-13 devnull return &d->disk;
155 0c98da8b 2005-07-13 devnull
156 0c98da8b 2005-07-13 devnull Err:
157 0c98da8b 2005-07-13 devnull if(b)
158 0c98da8b 2005-07-13 devnull vtblockput(b);
159 6519f895 2007-11-05 rsc
160 6519f895 2007-11-05 rsc _nfilereads_darwin_sucks(); /* force Darwin ld to pull in file.o */
161 0c98da8b 2005-07-13 devnull return nil;
162 0c98da8b 2005-07-13 devnull }
163 0c98da8b 2005-07-13 devnull