3 * Revision 11.29 1999/05/14 11:21:33 Michiel
4 * Bigger reserved area (2x)
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
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
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
39 * Revision 11.19 1995/12/28 13:47:48 Michiel
40 * rext->afsversion bugfix
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
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
68 * Revision 11.10 1995/07/07 14:39:17 Michiel
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
80 * Revision 11.6 1995/05/20 12:12:12 Michiel
81 * Updated messages to reflect Ami-FileLock
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
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
112 #define __USE_SYSBASE
114 #include <exec/types.h>
115 #include <exec/memory.h>
116 #include <exec/devices.h>
118 #include <dos/filehandler.h>
119 #include <intuition/intuition.h>
120 #include <proto/intuition.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"
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 /**********************************************************************/
157 /**********************************************************************/
159 BOOL
FDSFormat (DSTR diskname
, LONG disktype
, SIPTR
*error
, globaldata
*g
)
161 struct rootblock
*rootblock
;
162 struct volumedata
*volume
;
163 struct crootblockextension
*rext
;
169 g
->deldirenabled
= FALSE
;
172 /* remove error-induced soft protect */
173 if (g
->softprotect
< 0)
176 if (g
->softprotect
&& g
->protectkey
== ~0)
177 g
->softprotect
= g
->protectkey
= 0;
179 /* update dos envec and geom */
180 GetDriveGeometry (g
);
183 /* issue 00118: disk cannot exceed MAX_DISK_SIZE */
184 if (g
->geom
->dg_TotalSectors
> MAXDISKSIZE
)
187 if (MakeBootBlock (g
) != 0)
190 if (!(rootblock
= MakeRootBlock (diskname
, g
)))
193 /* make volumedata BEFORE rext ! (bug 00135) */
194 g
->currentvolume
= volume
= MakeVolumeData (rootblock
, g
);
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
);
207 i
= AllocAnode (0, g
);
208 } while (i
<ANODE_ROOTDIR
-1);
215 rootblock
->options
|= MODE_DELDIR
| MODE_SUPERDELDIR
;
220 FreeVolumeResources (volume
, g
);
221 g
->currentvolume
= NULL
;
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
,
242 ULONG iflags
= IDCMP_INACTIVEWINDOW
| IDCMP_MOUSEBUTTONS
| IDCMP_INTUITICKS
;
244 struct Window
*window
;
245 ULONG rec_idcmp
, retval
, tick
;
247 if (SysBase
->LibNode
.lib_Version
< 37)
250 req
.es_TextFormat
= (STRPTR
)FORMAT_MESSAGE
;
253 * Show copyright message
256 window
= BuildEasyRequestArgs (NULL
, &req
, iflags
, ®nr
);
257 while ( (retval
= SysReqHandler (window
, &rec_idcmp
, TRUE
)) != 0 )
261 if (rec_idcmp
& IDCMP_INTUITICKS
)
274 FreeSysRequest (window
);
280 * creates & writes the two bootblocks
282 static ULONG
MakeBootBlock (globaldata
*g
)
284 struct bootblock
*bbl
;
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
);
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
;
309 /* allocate max size possible */
310 if (!(rbl
= AllocBufmem (BLOCKSIZE
, g
)))
313 memset (rbl
, 0, BLOCKSIZE
);
316 rbl
->disktype
= ID_PFS_DISK
;
318 rbl
->options
= MODE_HARDDISK
| MODE_SPLITTED_ANODES
| MODE_DIR_EXTENSION
|
319 MODE_SIZEFIELD
| MODE_DATESTAMP
| MODE_EXTROVING
|
321 rbl
->disksize
= g
->geom
->dg_TotalSectors
;
323 rbl
->options
= MODE_HARDDISK
| MODE_SPLITTED_ANODES
| MODE_DIR_EXTENSION
|
324 MODE_DATESTAMP
| MODE_EXTROVING
| MODE_LONGFN
;
327 // determine reserved blocksize
328 ULONG resblocksize
= 1024;
329 if (g
->geom
->dg_TotalSectors
> MAXSMALLDISK
)
331 rbl
->options
|= MODE_SUPERINDEX
;
333 if (g
->geom
->dg_TotalSectors
> MAXDISKSIZE1K
) {
334 rbl
->disktype
= ID_PFS2_DISK
;
336 if (g
->geom
->dg_TotalSectors
> MAXDISKSIZE2K
) {
342 if (!InitLRU(g
, resblocksize
)) {
347 rbl
->reserved_blksize
= resblocksize
;
348 rescluster
= resblocksize
/g
->geom
->dg_SectorSize
;
351 rbl
->options
|= MODE_LARGEFILE
;
352 rbl
->disktype
= ID_PFS2_DISK
;
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
373 /* Create rootblockextension. Needed for AFS 2.3 options.
375 BOOL
MakeRBlkExtension (globaldata
*g
)
377 struct volumedata
*volume
= g
->currentvolume
;
380 if (!(blocknr
= AllocReservedBlock (g
)))
383 volume
->rootblk
->extension
= blocknr
;
384 if (!(volume
->rblkextension
= MakeFormatRBlkExtension(volume
->rootblk
, g
))) {
385 FreeReservedBlock (blocknr
, g
);
389 volume
->rootblk
->options
|= MODE_EXTENSION
;
390 volume
->rootblockchangeflag
= 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
)))
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;
424 static void MakeBitmap (globaldata
*g
)
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
);
444 static const ULONG schijf
[][2] =
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);
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];
472 taken
= min(MAXNUMRESERVED
, taken
);
473 taken
= (taken
+ 31) & ~0x1f; /* multiple of 32 */
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 */
487 for(i
=125; i
<numreserved
/32; i
+=256)
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
);
504 bmb
= (bitmapblock_t
*)(*rbl
+1); /* bitmap directly behind rootblock */
506 /* init bitmapblock header */
511 bitmap
= bmb
->bitmap
;
512 for (i
= 0; i
<numreserved
/32; i
++)
515 /* the last border */
517 for (i
=0; i
< numreserved
%32; i
++)
518 last
|= 0x80000000>>i
;
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
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
--;