]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/disk/kfs/devmulti.c
fix real cause of iso name truncation
[plan9front.git] / sys / src / cmd / disk / kfs / devmulti.c
1 #include "all.h"
2
3 enum{
4         MAXWREN = 7,
5 };
6
7 static char WMAGIC[] =  "kfs wren device\n";
8 static char MMAGIC[] =  "kfs multi-wren device %4d/%4d\n";
9
10 typedef struct Wren     Wren;
11
12 struct Wren{
13         QLock;
14         Device  dev;
15         ulong   nblocks;
16         int     fd;
17 };
18
19 static char     *wmagic = WMAGIC;
20 static Wren     *wrens;
21 static int      maxwren;
22 char            *wrenfile;
23 int             nwren;
24 int             badmagic;
25
26 static Wren *
27 wren(Device dev)
28 {
29         int i;
30
31         for(i = 0; i < maxwren; i++)
32                 if(devcmp(dev, wrens[i].dev) == 0)
33                         return &wrens[i];
34         panic("can't find wren for %D", dev);
35         return 0;
36 }
37
38 /*
39  * find out the length of a file
40  * given the mesg version of a stat buffer
41  * we call this because convM2D is different
42  * for the file system than in the os
43  */
44 uvlong
45 statlen(char *ap)
46 {
47         uchar *p;
48         ulong ll, hl;
49
50         p = (uchar*)ap;
51         p += 3*NAMELEN+5*4;
52         ll = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
53         hl = p[4] | (p[5]<<8) | (p[6]<<16) | (p[7]<<24);
54         return ll | ((uvlong) hl << 32);
55 }
56
57 static void
58 wrenpartinit(Device dev, int k)
59 {
60         char buf[MAXBUFSIZE], d[DIRREC];
61         char file[128], magic[64];
62         Wren *w;
63         int fd, i, nmagic;
64
65         if(wrens == 0)
66                 wrens = ialloc(MAXWREN * sizeof *wrens);
67         w = &wrens[maxwren];
68         if(nwren > 0)
69                 sprint(file, "%s%d", wrenfile, k);
70         else
71                 strcpy(file, wrenfile);
72         fd = open(file, ORDWR);
73         if(fd < 0)
74                 panic("can't open %s", file);
75         if(fstat(fd, d) < 0)
76                 panic("can't stat %s\n", file);
77         seek(fd, 0, 0);
78         i = read(fd, buf, sizeof buf);
79         if(i < sizeof buf)
80                 panic("can't read %s", file);
81         badmagic = 0;
82         RBUFSIZE = 1024;
83         sprint(magic, wmagic, k, nwren);
84         nmagic = strlen(magic);
85         if(strncmp(buf+256, magic, nmagic) == 0){
86                 RBUFSIZE = atol(buf+256+nmagic);
87                 if(RBUFSIZE % 512){
88                         fprint(2, "kfs: bad buffersize(%d): assuming 1k blocks\n", RBUFSIZE);
89                         RBUFSIZE = 1024;
90                 }
91         }else
92                 badmagic = 1;
93         w->dev = dev;
94         w->nblocks = statlen(d)/RBUFSIZE;
95         if(k > 0)
96                 w->nblocks -= 1;        /* don't count magic */
97         w->fd = fd;
98         maxwren++;
99 }
100
101 void
102 wreninit(Device dev)
103 {
104         int i;
105
106         if(nwren > 0)
107                 wmagic = MMAGIC;
108         i = 0;
109         do{
110                 wrenpartinit(dev, i);
111         }while(++i < nwren);
112 }
113
114 static void
115 wrenpartream(Device dev, int k)
116 {
117         Wren *w;
118         char buf[MAXBUFSIZE], magic[64];
119         int fd, i;
120
121         if(RBUFSIZE % 512)
122                 panic("kfs: bad buffersize(%d): restart a multiple of 512\n", RBUFSIZE);
123         print("kfs: reaming the file system using %d byte blocks\n", RBUFSIZE);
124         w = wren(dev)+k;
125         fd = w->fd;
126         memset(buf, 0, sizeof buf);
127         sprint(magic, wmagic, k, nwren);
128         sprint(buf+256, "%s%d\n", magic, RBUFSIZE);
129         qlock(w);
130         i = seek(fd, 0, 0) < 0 || write(fd, buf, RBUFSIZE) != RBUFSIZE;
131         qunlock(w);
132         if(i < 0)
133                 panic("can't ream disk");
134 }
135
136 void
137 wrenream(Device dev)
138 {
139         int i;
140
141         i = 0;
142         do{
143                 wrenpartream(dev, i);
144         }while(++i < nwren);
145 }
146
147 static int
148 wrentag(char *p, int tag, long qpath)
149 {
150         Tag *t;
151
152         t = (Tag*)(p+BUFSIZE);
153         return t->tag != tag || (qpath&~QPDIR) != t->path;
154 }
155
156 int
157 wrencheck(Device dev)
158 {
159         char buf[MAXBUFSIZE];
160
161         if(badmagic)
162                 return 1;
163         if(RBUFSIZE > sizeof buf)
164                 panic("bufsize too big");
165         if(wrenread(dev, wrensuper(dev), buf) || wrentag(buf, Tsuper, QPSUPER)
166         || wrenread(dev, wrenroot(dev), buf) || wrentag(buf, Tdir, QPROOT))
167                 return 1;
168         if(((Dentry *)buf)[0].mode & DALLOC)
169                 return 0;
170         return 1;
171 }
172
173 long
174 wrensize(Device dev)
175 {
176         Wren *w;
177         int i, nb;
178
179         w = wren(dev);
180         nb = 0;
181         i = 0;
182         do{
183                 nb += w[i].nblocks;
184         }while(++i < nwren);
185         return nb;
186 }
187
188 long
189 wrensuper(Device dev)
190 {
191         USED(dev);
192         return 1;
193 }
194
195 long
196 wrenroot(Device dev)
197 {
198         USED(dev);
199         return 2;
200 }
201
202 int
203 wrenread(Device dev, long addr, void *b)
204 {
205         Wren *w;
206         int fd, i;
207
208         w = wren(dev);
209         for(i=0; i<nwren; i++){
210                 if(addr < w->nblocks)
211                         break;
212                 addr -= w->nblocks;
213                 ++w;
214         }
215         if(i > 0)
216                 addr++;
217         fd = w->fd;
218         qlock(w);
219         i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || read(fd, b, RBUFSIZE) != RBUFSIZE;
220         qunlock(w);
221         return i;
222 }
223
224 int
225 wrenwrite(Device dev, long addr, void *b)
226 {
227         Wren *w;
228         int fd, i;
229
230         w = wren(dev);
231         for(i=0; i<nwren; i++){
232                 if(addr < w->nblocks)
233                         break;
234                 addr -= w->nblocks;
235                 ++w;
236         }
237         if(i > 0)
238                 addr++;
239         fd = w->fd;
240         qlock(w);
241         i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || write(fd, b, RBUFSIZE) != RBUFSIZE;
242         qunlock(w);
243         return i;
244 }