Added pfsdoctor. Includes PFS3 v19 large partition and file size support.
[AROS.git] / rom / filesys / pfs3 / pfsdoctor / access.c
blob26d1541fd4e486fcc9011d5a69afac18d03b71f6
1 /* $Id$ */
2 /* $Log: access.c $
3 * Revision 2.6 1999/09/11 16:45:50 Michiel
4 * Bug (1024 byte blok supprort) in AccessTest fixed
6 * Revision 2.5 1999/07/28 09:24:56 Michiel
7 * Unneeded anodeblock searches removed
9 * Revision 2.4 1999/05/07 16:49:00 Michiel
10 * bugfixes etc
12 * Revision 2.3 1999/05/07 09:31:31 Michiel
13 * bugfix
15 * Revision 2.2 1999/05/04 04:27:13 Michiel
16 * debugged upto buildrext
18 * Revision 2.1 1999/04/30 12:17:58 Michiel
19 * Accepts OK disks, bitmapfix and hardlink fix works
21 * Revision 1.2 1999/04/22 15:26:49 Michiel
22 * compiled
23 * */
25 #include <exec/ports.h>
26 #include <stdlib.h>
27 #include "pfs3.h"
28 #include "doctor.h"
29 #include <string.h>
31 /**************************************
32 * Non-checking functions for access to structures on PFS3 disks
33 **************************************/
35 /* get a buildblock from the buildblock cache
37 cachedblock_t *GetBuildBlock(uint16 bloktype, uint32 seqnr)
39 struct buildblock *bbl;
41 for (bbl = HeadOf(&volume.buildblocks); bbl->next; bbl = bbl->next)
43 if (bbl->b.data->id == bloktype &&
44 bbl->b.data->indexblock.seqnr == seqnr)
46 return &bbl->b;
50 return NULL;
53 /* get reserved block
54 * anything, except deldir, root, boot, dir and rext
56 error_t GetResBlock(cachedblock_t *blok, uint16 bloktype, uint32 seqnr, bool fix)
58 cachedblock_t blk, *t;
59 uint32 blknr, *bp = NULL, index, offset;
60 error_t error = e_none;
62 // controleer build block lijst
63 t = GetBuildBlock(bloktype, seqnr);
64 if (t)
66 blok->blocknr = t->blocknr;
67 blok->mode = t->mode;
68 *blok->data = *t->data;
69 return e_none;
72 blk.data = calloc(1, SIZEOF_RESBLOCK);
73 index = seqnr/INDEX_PER_BLOCK;
74 offset = seqnr%INDEX_PER_BLOCK;
75 switch(bloktype)
77 case SBLKID:
79 if (seqnr > MAXSUPER)
81 free (blk.data);
82 return e_number_error;
85 bp = &rext.data->superindex[seqnr];
86 if (!*bp)
88 if (fix)
90 adderror("superindex block not found");
91 error = RepairSuperIndex(bp, seqnr);
92 if (error)
93 *bp = 0;
94 else
96 volume.writeblock((cachedblock_t *)&rext);
97 KillAnodeBitmap();
101 break;
103 case BMIBLKID:
105 bp = &rbl->idx.large.bitmapindex[seqnr];
106 if (!*bp)
108 if (fix)
110 adderror("bitmapindex block not found");
111 error = RepairBitmapIndex(bp, seqnr);
112 if (error)
113 *bp = 0;
114 else
115 c_WriteBlock((uint8 *)rbl, ROOTBLOCK + volume.firstblock, volume.blocksize);
118 break;
120 case IBLKID:
122 if (rbl->options & MODE_SUPERINDEX)
124 error = GetResBlock(&blk, SBLKID, index, fix);
125 if (error)
127 free (blk.data);
128 return error;
131 bp = &blk.data->indexblock.index[offset];
133 else
135 bp = &rbl->idx.small.indexblocks[seqnr];
137 if (!*bp)
139 if (fix)
141 adderror("anodeindex block not found");
142 error = RepairAnodeIndex(bp, seqnr);
143 if (error)
144 *bp = 0;
145 else
147 /* the anodebitmap, which is made per aib,
148 * could be too small
150 KillAnodeBitmap();
151 if (rbl->options & MODE_SUPERINDEX)
152 volume.writeblock((cachedblock_t *)&blk);
153 else
154 c_WriteBlock((uint8 *)rbl, ROOTBLOCK + volume.firstblock, volume.blocksize);
158 break;
160 case ABLKID:
162 error = GetResBlock(&blk, IBLKID, index, fix);
163 if (error)
165 free (blk.data);
166 return error;
169 bp = &blk.data->indexblock.index[offset];
170 if (!*bp)
172 if (fix)
174 adderror("anode block not found");
175 // RepairAnodeBlock already called from RepairAnodeTree
176 // Pointless to call it again here.
177 //if (error = RepairAnodeBlock(bp, seqnr))
178 // *bp = 0;
179 //else
180 // volume.writeblock((cachedblock_t *)&blk);
183 break;
185 case BMBLKID:
187 error = GetResBlock(&blk, BMIBLKID, index, fix);
188 if (error)
190 free (blk.data);
191 return error;
194 bp = &blk.data->indexblock.index[offset];
195 if (!*bp)
197 if (fix)
199 adderror("bitmap block not found");
200 error = RepairBitmapBlock(bp, seqnr);
201 if (error)
202 *bp = 0;
203 else
204 volume.writeblock((cachedblock_t *)&blk);
207 break;
210 blknr = *bp;
212 free (blk.data);
213 if (!blknr)
214 return e_not_found;
216 error = volume.getblock(blok, blknr);
217 if (error)
218 return error;
220 return e_none;
223 static c_anodeblock_t tablk = { 0 };
224 static ULONG tanodedata[MAXRESBLOCKSIZE / 4];
225 static anodeblock_t *tanodeblk = (anodeblock_t*)tanodedata;
227 bool GetAnode(canode_t *anode, uint32 anodenr, bool fix)
229 anodenr_t *split = (anodenr_t *)&anodenr;
231 if (!(tablk.data && tanodeblk->seqnr == split->seqnr))
233 tablk.data = tanodeblk;
234 if (GetResBlock((cachedblock_t *)&tablk, ABLKID, split->seqnr, fix))
236 tablk.data = NULL;
237 return false;
241 if (split->offset > ANODES_PER_BLOCK)
242 return false;
244 anode->nr = anodenr;
245 anode->clustersize = tablk.data->nodes[split->offset].clustersize;
246 anode->blocknr = tablk.data->nodes[split->offset].blocknr;
247 anode->next = tablk.data->nodes[split->offset].next;
248 return true;
251 bool SaveAnode(canode_t *anode, uint32 nr)
253 anodenr_t *split = (anodenr_t *)&nr;
254 c_anodeblock_t ablk;
255 uint32 buffer[MAXRESBLOCKSIZE/4];
257 tablk.data = NULL; /* kill anode read cache */
258 ablk.data = (anodeblock_t *)buffer;
259 if (GetResBlock((cachedblock_t *)&ablk, ABLKID, split->seqnr, false))
260 return false;
262 if (split->offset > ANODES_PER_BLOCK)
263 return false;
265 ablk.data->nodes[split->offset].clustersize = anode->clustersize;
266 ablk.data->nodes[split->offset].blocknr = anode->blocknr;
267 ablk.data->nodes[split->offset].next = anode->next;
268 volume.writeblock((cachedblock_t *)&ablk);
269 return true;
272 ULONG GetDEFileSize(struct direntry *direntry, struct extrafields *extra, ULONG *high)
274 *high = 0;
275 if (rbl->options & MODE_LARGEFILE) {
276 *high = extra->fsizex;
277 return direntry->fsize;
279 return direntry->fsize;
282 ULONG GetDDFileSize(struct deldirentry *dde, ULONG *high)
284 *high = 0;
285 if ((rbl->options & MODE_LARGEFILE) && dde->filename[0] <= DELENTRYFNSIZE) {
286 *high = dde->fsizex;
287 return dde->fsize;
289 return dde->fsize;