Added a test for MUIA_Listview_SelectChange.
[AROS.git] / rom / filesys / pfs3 / fs / format.c
blob20d706da892b1f83ad1e750385204e9bab0ed667
1 /* $Id$ */
2 /* $Log: format.c $
3 * Revision 11.29 1999/05/14 11:21:33 Michiel
4 * Bigger reserved area (2x)
5 * MODE_LONGFN
7 * Revision 11.28 1999/03/09 10:26:35 Michiel
8 * 00136, 00137: 1024 byte sector support
9 * 00114: reserved roving
10 * 00110: release number define
12 * Revision 11.27 1999/02/22 16:27:09 Michiel
13 * Changes for increasing deldir capacity
15 * Revision 11.26 1998/10/05 16:30:48 Michiel
16 * fixed version number error in requester
18 * Revision 11.25 1998/09/27 11:26:37 Michiel
19 * fixed supermode related bugs
21 * Revision 11.24 1998/09/03 07:12:14 Michiel
22 * versie 17.4
23 * bugfixes 118, 121, 123 and superindexblocks and td64 support
25 * Revision 11.23 1998/06/13 01:46:22 Michiel
26 * show format requester longer
27 * fixed bug 117
28 * patched bug 118
30 * Revision 11.22 1998/05/29 19:31:18 Michiel
31 * datestamp initially 1
33 * Revision 11.21 1998/05/27 20:16:13 Michiel
34 * MODE_DATESTAMP added
36 * Revision 11.20 1996/03/07 10:09:48 Michiel
37 * format bugs fixed
39 * Revision 11.19 1995/12/28 13:47:48 Michiel
40 * rext->afsversion bugfix
41 * small changes
43 * Revision 11.18 1995/11/15 15:47:45 Michiel
44 * Creation of rootblock extension added (MakeRBlkExtension)
46 * Revision 11.17 1995/10/20 10:12:08 Michiel
47 * Anode reserved area adaptions (16.3)
49 * Revision 11.16 1995/10/03 09:59:05 Michiel
50 * MakeDeldir --> g->dirty
52 * Revision 11.15 1995/08/21 04:24:13 Michiel
53 * better checks for out of memory
55 * Revision 11.14 1995/08/04 04:13:52 Michiel
56 * deldirblock protection now is DELENTRY_PROT
57 * CUTDOWN/AFSLITE protection: limited number of reserved blocks
59 * Revision 11.13 1995/07/21 06:59:31 Michiel
60 * DELDIR adaptions
62 * Revision 11.12 1995/07/11 17:29:31 Michiel
63 * ErrorMsg () calls use messages.c variables now.
65 * Revision 11.11 1995/07/11 09:23:36 Michiel
66 * DELDIR stuff
68 * Revision 11.10 1995/07/07 14:39:17 Michiel
69 * AFSLITE stuff
71 * Revision 11.9 1995/06/20 11:56:58 Michiel
72 * Error induced softprotect uit
74 * Revision 11.8 1995/06/16 10:02:42 Michiel
75 * using Allec & FreeBufMem
77 * Revision 11.7 1995/06/15 18:56:53 Michiel
78 * pooled mem
80 * Revision 11.6 1995/05/20 12:12:12 Michiel
81 * Updated messages to reflect Ami-FileLock
82 * CUTDOWN version
83 * protection update
85 * Revision 11.5 1995/04/13 13:18:06 Michiel
86 * Extra options added to rootblock
88 * Revision 11.4 1995/02/15 16:43:39 Michiel
89 * Release version
90 * Using new headers (struct.h & blocks.h)
92 * Revision 11.3 1995/02/13 03:38:14 Michiel
93 * Added 10 reserved blocks.
95 * Revision 11.2 1995/01/18 04:29:34 Michiel
96 * Bugfixes. Now ready for beta release.
98 * Revision 11.1 1995/01/08 16:20:16 Michiel
99 * New diskformat. Compiled.
101 * Revision 10.2 1994/11/15 17:52:30 Michiel
102 * __USE_SYSBASE moved..
104 * Revision 10.1 1994/10/24 11:16:28 Michiel
105 * first RCS revision
106 * */
109 * General includes
112 #define __USE_SYSBASE
114 #include <exec/types.h>
115 #include <exec/memory.h>
116 #include <exec/devices.h>
117 #include <exec/io.h>
118 #include <dos/filehandler.h>
119 #include <intuition/intuition.h>
120 #include <proto/intuition.h>
121 #include "debug.h"
122 #include <math.h>
123 #include <string.h>
126 * Own includes
128 #include "blocks.h"
129 #include "struct.h"
130 #include "format_protos.h"
131 #include "disk_protos.h"
132 #include "directory_protos.h"
133 #include "allocation_protos.h"
134 #include "volume_protos.h"
135 #include "anodes_protos.h"
136 #include "init_protos.h"
137 #include "update_protos.h"
138 #include "lru_protos.h"
139 #include "versionhistory.doc"
142 * Contents
144 static void ShowVersion (globaldata *g);
145 static ULONG MakeBootBlock(globaldata *g);
146 static rootblock_t *MakeRootBlock (DSTR diskname, globaldata *g);
147 static void MakeBitmap (globaldata *g);
148 static void MakeRootDir (globaldata *g);
149 static ULONG CalcNumReserved (globaldata *g, ULONG resblocksize);
150 static void MakeReservedBitmap (struct rootblock **rbl, ULONG numreserved, globaldata *g);
151 static crootblockextension_t *MakeFormatRBlkExtension (struct rootblock *rbl, globaldata *g);
153 /**********************************************************************/
154 /* FORMAT */
155 /* FORMAT */
156 /* FORMAT */
157 /**********************************************************************/
159 BOOL FDSFormat (DSTR diskname, LONG disktype, SIPTR *error, globaldata *g)
161 struct rootblock *rootblock;
162 struct volumedata *volume;
163 struct crootblockextension *rext;
164 ULONG i;
166 ENTER("FDSFormat");
168 #if DELDIR
169 g->deldirenabled = FALSE;
170 #endif
172 /* remove error-induced soft protect */
173 if (g->softprotect < 0)
174 return DOSFALSE;
176 if (g->softprotect && g->protectkey == ~0)
177 g->softprotect = g->protectkey = 0;
179 /* update dos envec and geom */
180 GetDriveGeometry (g);
181 ShowVersion (g);
183 /* issue 00118: disk cannot exceed MAX_DISK_SIZE */
184 if (g->geom->dg_TotalSectors > MAXDISKSIZE)
185 return DOSFALSE;
187 if (MakeBootBlock (g) != 0)
188 return DOSFALSE;
190 if (!(rootblock = MakeRootBlock (diskname, g)))
191 return DOSFALSE;
193 /* make volumedata BEFORE rext ! (bug 00135) */
194 g->currentvolume = volume = MakeVolumeData (rootblock, g);
196 /* add extension */
197 if (!(rext = MakeFormatRBlkExtension (rootblock, g)))
198 return DOSFALSE; // rootblock extension could not be created
200 volume->rblkextension = rext;
201 rootblock->options |= MODE_EXTENSION;
202 InitModules (volume, TRUE, g);
204 MakeBitmap (g);
206 do {
207 i = AllocAnode (0, g);
208 } while (i<ANODE_ROOTDIR-1);
210 MakeRootDir (g);
212 #if DELDIR
213 /* add deldir */
214 SetDeldir(2, g);
215 rootblock->options |= MODE_DELDIR | MODE_SUPERDELDIR;
216 g->dirty = TRUE;
217 #endif
219 UpdateDisk (g);
220 FreeVolumeResources (volume, g);
221 g->currentvolume = NULL;
223 return DOSTRUE;
228 * Protection and cutdown check
230 static void ShowVersion (globaldata *g)
232 /* data needed for requester */
233 struct EasyStruct req =
235 sizeof(struct EasyStruct),
237 "Professional File System 3 V" RELEASE,
238 NULL,
239 "OK"
242 ULONG iflags = IDCMP_INACTIVEWINDOW | IDCMP_MOUSEBUTTONS | IDCMP_INTUITICKS;
243 ULONG regnr = 0;
244 struct Window *window;
245 ULONG rec_idcmp, retval, tick;
247 if (SysBase->LibNode.lib_Version < 37)
248 return;
250 req.es_TextFormat = (STRPTR)FORMAT_MESSAGE;
253 * Show copyright message
255 tick = 0;
256 window = BuildEasyRequestArgs (NULL, &req, iflags, &regnr);
257 while ( (retval = SysReqHandler (window, &rec_idcmp, TRUE )) != 0 )
259 if (retval == -1)
261 if (rec_idcmp & IDCMP_INTUITICKS)
263 tick++;
264 rec_idcmp = 0;
265 if (tick == 60)
266 break;
268 else
270 break;
274 FreeSysRequest (window);
280 * creates & writes the two bootblocks
282 static ULONG MakeBootBlock (globaldata *g)
284 struct bootblock *bbl;
285 ULONG error;
287 if (!(bbl = AllocBufmem (2 * BLOCKSIZE, g)))
288 return ERROR_NO_FREE_STORE;
290 memset (bbl, 0, 2*BLOCKSIZE);
291 bbl->disktype = ID_PFS_DISK;
292 error = RawWrite ((UBYTE *)bbl, 2, BOOTBLOCK1, g);
293 FreeBufmem (bbl, g);
294 return error;
298 * creates rootblock (does not write)
299 * including reserved bitmap
300 * (will be written by Update and freed by FreeVolumeRes.)
302 static rootblock_t *MakeRootBlock (DSTR diskname, globaldata *g)
304 struct rootblock *rbl;
305 struct DateStamp time;
306 ULONG numreserved;
307 ULONG rescluster;
309 /* allocate max size possible */
310 if (!(rbl = AllocBufmem (BLOCKSIZE, g)))
311 return NULL;
313 memset (rbl, 0, BLOCKSIZE);
314 DateStamp (&time);
316 rbl->disktype = ID_PFS_DISK;
317 #ifdef SIZEFIELD
318 rbl->options = MODE_HARDDISK | MODE_SPLITTED_ANODES | MODE_DIR_EXTENSION |
319 MODE_SIZEFIELD | MODE_DATESTAMP | MODE_EXTROVING |
320 MODE_LONGFN;
321 rbl->disksize = g->geom->dg_TotalSectors;
322 #else
323 rbl->options = MODE_HARDDISK | MODE_SPLITTED_ANODES | MODE_DIR_EXTENSION |
324 MODE_DATESTAMP | MODE_EXTROVING | MODE_LONGFN;
325 #endif
327 // determine reserved blocksize
328 ULONG resblocksize = 1024;
329 if (g->geom->dg_TotalSectors > MAXSMALLDISK)
331 rbl->options |= MODE_SUPERINDEX;
332 g->supermode = 1;
333 if (g->geom->dg_TotalSectors > MAXDISKSIZE1K) {
334 rbl->disktype = ID_PFS2_DISK;
335 resblocksize = 2048;
336 if (g->geom->dg_TotalSectors > MAXDISKSIZE2K) {
337 resblocksize = 4096;
342 if (!InitLRU(g, resblocksize)) {
343 FreeBufmem(rbl, g);
344 return NULL;
347 rbl->reserved_blksize = resblocksize;
348 rescluster = resblocksize/g->geom->dg_SectorSize;
350 #if LARGE_FILE_SIZE
351 rbl->options |= MODE_LARGEFILE;
352 rbl->disktype = ID_PFS2_DISK;
353 #endif
355 rbl->datestamp = 1;
356 rbl->creationday = (UWORD)time.ds_Days;
357 rbl->creationminute = (UWORD)time.ds_Minute;
358 rbl->creationtick = (UWORD)time.ds_Tick;
359 rbl->protection = 0xf0;
360 numreserved = CalcNumReserved (g, resblocksize);
361 rbl->firstreserved = 2;
362 rbl->lastreserved = rescluster*numreserved + rbl->firstreserved - 1;
363 rbl->reserved_free = numreserved;
364 rbl->blocksfree = g->geom->dg_TotalSectors - rescluster*numreserved - rbl->firstreserved;
365 rbl->alwaysfree = rbl->blocksfree/20;
366 // rbl->roving_ptr = 0;
368 memcpy(rbl->diskname, diskname, min(*diskname+1, DNSIZE));
369 MakeReservedBitmap(&rbl, numreserved, g); // sets reserved_free & rblkcluster too
370 return rbl;
373 /* Create rootblockextension. Needed for AFS 2.3 options.
375 BOOL MakeRBlkExtension (globaldata *g)
377 struct volumedata *volume = g->currentvolume;
378 ULONG blocknr;
380 if (!(blocknr = AllocReservedBlock (g)))
381 return FALSE;
383 volume->rootblk->extension = blocknr;
384 if (!(volume->rblkextension = MakeFormatRBlkExtension(volume->rootblk, g))) {
385 FreeReservedBlock (blocknr, g);
386 return FALSE;
389 volume->rootblk->options |= MODE_EXTENSION;
390 volume->rootblockchangeflag = TRUE;
391 return TRUE;
394 static crootblockextension_t *MakeFormatRBlkExtension (struct rootblock *rbl, globaldata *g)
396 crootblockextension_t *rext;
398 if (!(rext = AllocBufmem (sizeof(struct cachedblock) + rbl->reserved_blksize, g)))
399 return FALSE;
401 memset (rext, 0, sizeof(struct cachedblock) + rbl->reserved_blksize);
403 rext->volume = g->currentvolume;
404 rext->blocknr = rbl->extension;
405 // rext->oldblocknr = 0;
406 rext->changeflag = TRUE;
407 rext->blk.id = EXTENSIONID;
408 // rext->blk.ext_options = 0;
409 rext->blk.pfs2version = (VERNUM<<16) + REVNUM;
410 rext->blk.root_date[0] = rbl->creationday;
411 rext->blk.root_date[1] = rbl->creationminute;
412 rext->blk.root_date[2] = rbl->creationtick;
413 // rext->blk.volume_date[0] = 0; /* volume date, initially 0: see gurubook */
414 // rext->blk.volume_date[1] = 0;
415 // rext->blk.volume_date[2] = 0;
416 // rext->blk.tobedone currently zero
417 // rext->reserved_roving initially zero
418 rext->blk.fnsize = g->fnsize = 32;
420 g->dirty = TRUE;
421 return rext;
424 static void MakeBitmap (globaldata *g)
426 ULONG i;
428 /* use no_bmb as calculated by InitAllocation */
429 for (i=0;i<alloc_data.no_bmb;i++)
430 NewBitmapBlock (i,g);
433 static void MakeRootDir (globaldata *g)
435 struct cdirblock *blk;
436 ULONG blocknr, anodenr;
438 blocknr = AllocReservedBlock (g);
439 anodenr = AllocAnode (0, g);
440 blk = MakeDirBlock (blocknr, anodenr, anodenr, 0, g);
441 (void)blk; // Unused
444 static const ULONG schijf[][2] =
446 {20480,20},
447 {51200,30},
448 {512000,40},
449 {1048567,50},
450 {10000000,70},
451 {0xffffffff,80}
454 // returns number of reserved blocks needed
455 static ULONG CalcNumReserved (globaldata *g, ULONG resblocksize)
457 ULONG temp, taken, i;
459 // temp is the number of reserved blocks if the whole disk is
460 // taken. taken is the actual number of reserved blocks we take.
461 temp = g->geom->dg_TotalSectors * (g->geom->dg_SectorSize/512);
462 temp /= (resblocksize/512);
463 taken = 0;
465 for (i=0; temp > schijf[i][0]; i++)
467 taken += schijf[i][0]/schijf[i][1];
468 temp -= schijf[i][0];
470 taken += temp/schijf[i][1];
471 taken += 10;
472 taken = min(MAXNUMRESERVED, taken);
473 taken = (taken + 31) & ~0x1f; /* multiple of 32 */
475 return taken;
478 /* makes reserved bitmap and allocates rootblockextension */
479 static void MakeReservedBitmap (struct rootblock **rbl, ULONG numreserved, globaldata *g)
481 struct bitmapblock *bmb;
482 struct rootblock *newrootblock;
483 ULONG *bitmap, numblocks, i, last, cluster, rescluster;
485 /* calculate number of 1024 byte blocks */
486 numblocks = 1;
487 for(i=125; i<numreserved/32; i+=256)
488 numblocks++;
490 // convert to number of reserved blocks and allocate
491 numblocks = (1024*numblocks + (*rbl)->reserved_blksize - 1) / ((*rbl)->reserved_blksize);
492 (*rbl)->reserved_free -= numblocks;
494 // convert to number of sectors
495 rescluster = ((*rbl)->reserved_blksize) / BLOCKSIZE;
496 cluster = (*rbl)->rblkcluster = rescluster * numblocks;
498 /* reallocate rootblock */
499 newrootblock = AllocBufmemR(cluster << BLOCKSHIFT, g);
500 memset (newrootblock, 0, cluster << BLOCKSHIFT);
501 memcpy (newrootblock, *rbl, BLOCKSIZE);
502 FreeBufmem(*rbl, g);
503 *rbl = newrootblock;
504 bmb = (bitmapblock_t *)(*rbl+1); /* bitmap directly behind rootblock */
506 /* init bitmapblock header */
507 bmb->id = BMBLKID;
508 bmb->seqnr = 0;
510 /* fill bitmap */
511 bitmap = bmb->bitmap;
512 for (i = 0; i<numreserved/32; i++)
513 *bitmap++ = ~0;
515 /* the last border */
516 last = 0;
517 for (i=0; i < numreserved%32; i++)
518 last |= 0x80000000>>i;
519 *bitmap = last;
521 /* allocate taken blocks + rootblock extension (de + 1)
522 * The reserved area starts with the rootblock.
523 * Convert numblocks from 1K blocks to actual reserved area blocks
524 * */
525 for (i=0; i < numblocks + 1; i++)
526 bmb->bitmap[i/32] ^= 0x80000000>>(i%32);
528 /* rootblock extension position */
529 (*rbl)->extension = (*rbl)->firstreserved + cluster;
530 (*rbl)->reserved_free--;