revert between 56095 -> 55830 in arch
[AROS.git] / rom / filesys / pfs3 / fs / init.c
bloba89db90674e6deb74d73e8d5290da69f7b88f44c
1 /* $Id$ */
2 /* $Log: init.c $
3 * Revision 12.9 1999/09/11 17:05:14 Michiel
4 * bugfix version 18.4
6 * Revision 12.8 1999/05/14 11:31:34 Michiel
7 * Long filename support implemented; bugfixes
9 * Revision 12.7 1999/02/22 16:25:30 Michiel
10 * Changes for increasing deldir capacity
12 * Revision 12.6 1998/09/27 11:26:37 Michiel
13 * Memory allocation mask check removed (issue 00126)
14 * ErrorMsg param
16 * Revision 12.5 1998/09/03 07:12:14 Michiel
17 * versie 17.4
18 * bugfixes 118, 121, 123 and superindexblocks and td64 support
20 * Revision 12.4 1998/05/27 21:07:28 Mark
21 * Added second DMAMask failover to include MEMF_LOCAL
23 * Revision 12.3 1997/03/03 22:04:04 Michiel
24 * Release 16.21
26 * Revision 12.2 1996/03/07 10:05:24 Michiel
27 * format fix (wt)
29 * Revision 12.1 1995/11/15 15:50:20 Michiel
30 * Postponed operation handler 'DoPostponed' added
32 * Revision 11.17 1995/11/07 14:59:20 Michiel
33 * initialization of new datacache (version 16.2)
35 * Revision 11.16 1995/10/04 14:03:53 Michiel
36 * using new memorypool functions (from support.c 10.9)
38 * Revision 11.15 1995/09/01 11:19:39 Michiel
39 * ErrorMsg adaption (see disk.c and volume.c)
41 * Revision 11.14 1995/08/21 04:21:36 Michiel
42 * Initialise now creates the sleepport for MODE_SLEEP
44 * Revision 11.13 1995/07/17 12:22:34 Michiel
45 * AFS User adaptions
47 * Revision 11.12 1995/07/11 17:29:31 Michiel
48 * ErrorMsg () calls use messages.c variables now.
50 * Revision 11.11 1995/07/11 09:23:36 Michiel
51 * DELDIR stuff
53 * Revision 11.10 1995/07/07 14:39:17 Michiel
54 * AFSLITE stuff
56 * Revision 11.9 1995/06/16 10:01:02 Michiel
57 * added pool for buffer memory
59 * Revision 11.8 1995/06/15 18:56:09 Michiel
60 * pooled mem
62 * Revision 11.7 1995/05/20 12:12:12 Michiel
63 * Updated messages to reflect Ami-FileLock
64 * CUTDOWN version
65 * protection update
67 * Revision 11.6 1995/03/30 18:57:49 Michiel
68 * Initialization of notifyport added
69 * Myproc has come back (for diskchangeint)
71 * Revision 11.5 1995/02/28 18:34:03 Michiel
72 * MODE_HARDDISK, MDOE_SPLITTED_ANODES and MODE_DIR_EXTENSION added
74 * Revision 11.4 1995/02/15 16:43:39 Michiel
75 * Release version
76 * Using new headers (struct.h & blocks.h)
78 * Revision 11.3 1995/01/29 07:34:57 Michiel
79 * Datacache now is BufMemType
80 * Blockshift, directsize init added
82 * Revision 11.2 1995/01/15 05:25:29 Michiel
83 * now always sets removable to true to
84 * accommodate Syquest & Floptical
86 * Revision 11.1 1995/01/08 16:21:28 Michiel
87 * Compiled (new MODE_BIG version)
88 * added InitModules
90 * Revision 10.4 1994/11/15 17:52:30 Michiel
91 * *** empty log message ***
93 * Revision 10.3 1994/10/29 08:54:34 Michiel
94 * changed process references to msgport references
96 * Revision 10.2 1994/10/27 11:31:46 Michiel
97 * *** empty log message ***
99 * Revision 10.1 1994/10/24 11:04:22 Michiel
100 * first RCS revision
101 * */
103 #define __USE_SYSBASE
105 #include <exec/types.h>
106 #include <exec/memory.h>
107 #include <exec/devices.h>
108 #include <exec/interrupts.h>
109 #include <exec/execbase.h>
110 #include <exec/resident.h>
111 #include <devices/timer.h>
112 #include <devices/keyboard.h>
113 #include <dos/filehandler.h>
114 #include <resources/filesysres.h>
115 #include <clib/alib_protos.h>
117 #include <string.h>
118 #include "debug.h"
120 /* own includes */
121 #include "blocks.h"
122 #include "struct.h"
123 #include "versionhistory.doc"
124 #include "init_protos.h"
125 #include "volume_protos.h"
126 #include "anodes_protos.h"
127 #include "directory_protos.h"
128 #include "lru_protos.h"
129 #include "allocation_protos.h"
131 /* external globals
133 extern CONST UBYTE *version;
134 #if defined(__SASC)
135 extern void __asm ResetHandler(void);
136 #elif defined(__AROS__)
137 extern AROS_INTP(DiskChangeHandler);
138 extern AROS_INTP(ResetHandler);
139 #else
140 extern void ResetHandler(void);
141 #endif
143 /* prototypes
145 static BOOL OpenDiskDevice(struct FileSysStartupMsg * , struct MsgPort ** , struct IOExtTD **, BOOL *, globaldata *);
146 static BOOL init_device_unit_sema(struct FileSysStartupMsg *, globaldata *);
147 static BOOL OpenTimerDevice(struct MsgPort ** , struct timerequest ** , ULONG, globaldata * );
148 static BOOL TestRemovability(globaldata *);
149 static void InstallDiskChangeHandler(globaldata *);
150 static void InstallResetHandler(struct globaldata *);
151 #if !defined(__MORPHOS__) || defined(DISK_BASED_FILESYSTEM)
152 /* MorphOS ROM build uses other means to add the filesystem.resource entry */
153 static BOOL AddToFSResource(ULONG, BPTR, struct globaldata *);
154 #endif
155 #if VERSION23
156 static void DoPostponed (struct volumedata *volume, globaldata *g);
157 #endif
159 /**********************************************************************/
160 /* INITIALIZE */
161 /* INITIALIZE */
162 /* INITIALIZE */
163 /**********************************************************************/
165 #ifdef DEBUGMODE
166 BOOL Initialize(DSTR mountname, struct FileSysStartupMsg *fssm,
167 struct DeviceNode *devnode, globaldata *g)
169 return(TRUE);
171 #else
172 BOOL Initialize(DSTR mountname, struct FileSysStartupMsg *fssm,
173 struct DeviceNode *devnode, globaldata *g)
175 LONG i;
176 ULONG t;
178 ENTER("Initialize");
179 g->ErrorMsg = _NormalErrorMsg;
181 /* mountname can be something like "pfs:hello". I only need
182 ** the "pfs" part. <i> will be the mountnamelen.
183 ** sizeof(mountname) MUST be >0
186 for (i=1; i<*mountname+1 && mountname[i]!=':'; i++);
187 /* now mountname[i]==':' || i==*mountname+1 ==> i=sizeof(mnname) */
188 g->mountname = AllocMemR (i, 0, g);
189 g->mountname[0] = i-1;
190 CopyMem(mountname+1, g->mountname+1, i-1);
192 /* allocate messageport for notify */
193 g->notifyport = CreateMsgPort();
195 g->myproc = (struct Process *)FindTask(NULL);
196 g->msgport = devnode->dn_Task;
197 g->devnode = devnode;
198 g->startup = fssm;
199 g->dosenvec = (struct DosEnvec *)BADDR(fssm->fssm_Environ);
200 g->currentvolume = NULL;
203 * Assign memory functions; pooled or not depending
204 * on exec version (V16: always used LibPool functions
206 g->allocmemp = AllocPooledVec;
207 g->freememp = FreePooledVec;
208 g->allocbufmem = AllocPooledBuf;
209 g->freebufmem = FreePooledBuf;
211 if (!(g->mainPool = LibCreatePool (MEMF_CLEAR, 2*1024, 1*1024)))
213 ErrorMsg (AFS_ERROR_MEMORY_POOL, NULL, g);
214 return FALSE;
217 g->bufferPool = LibCreatePool (g->dosenvec->de_BufMemType, 20*1024, 16*1024);
218 if (g->bufferPool)
220 #if 0
221 Removed because of problems with Phase 5 boards
223 /* check if memory allocated is ok (First fail-over) */
224 if (((ULONG)LibAllocPooled(g->bufferPool, 8)) & ~g->dosenvec->de_Mask)
226 g->dosenvec->de_BufMemType |= MEMF_24BITDMA;
227 LibDeletePool (g->bufferPool);
228 g->bufferPool = LibCreatePool (g->dosenvec->de_BufMemType, 20*1024, 16*1024);
230 /* check if memory allocated is ok (Second fail-over) */
231 if (((ULONG)LibAllocPooled(g->bufferPool, 8)) & ~g->dosenvec->de_Mask)
233 g->dosenvec->de_BufMemType |= MEMF_LOCAL;
234 LibDeletePool (g->bufferPool);
235 g->bufferPool = LibCreatePool (g->dosenvec->de_BufMemType, 20*1024, 16*1024);
237 #endif
240 if (!g->bufferPool)
242 ErrorMsg (AFS_ERROR_MEMORY_POOL, NULL, g);
243 return FALSE;
246 g->blocksize = g->dosenvec->de_SizeBlock << 2;
247 t = BLOCKSIZE;
248 for (i=-1; t; i++)
249 t >>= 1;
250 g->blockshift = i;
251 g->directsize = 16*1024>>i;
253 #if ACCESS_DETECT
254 g->tdmode = ACCESS_UNDETECTED;
255 #else
256 #define DE(x) g->dosenvec->de_##x
257 g->tdmode = ACCESS_STD;
258 if ((DE(HighCyl)+1)*DE(BlocksPerTrack)*DE(Surfaces) >= (1UL << (32-BLOCKSHIFT))) {
259 #if TD64
260 g->tdmode = ACCESS_TD64;
261 #elif NSD
262 g->tdmode = ACCESS_NSD;
263 #elif SCSIDIRECT
264 g->tdmode = ACCESS_DS;
265 #endif
267 #undef DE
268 #endif
270 if (!(g->geom = AllocMemP (sizeof(struct DriveGeometry), g)))
271 return FALSE;
273 NewList((struct List *)&g->volumes); /* %9.1 */
274 NewList((struct List *)&g->idlelist);
276 if (!OpenDiskDevice(fssm, &g->port, &g->request, &g->trackdisk, g) )
277 return FALSE;
279 DB(Trace(4,"Init","result = %ld",(ULONG)g->trackdisk));
281 if (!init_device_unit_sema(fssm, g))
282 return FALSE;
284 /* mode now always big */
285 g->harddiskmode = TRUE;
287 /* data cache */
288 g->dc.size = DATACACHELEN;
289 g->dc.mask = DATACACHEMASK;
290 g->dc.roving = 0;
291 g->dc.ref = AllocMemR (DATACACHELEN * sizeof(struct reftable), MEMF_CLEAR, g);
292 g->dc.data = AllocMemR (DATACACHELEN * BLOCKSIZE, g->dosenvec->de_BufMemType, g);
293 if (!g->dc.ref || !g->dc.data)
294 return FALSE;
296 /* check memory against mask */
297 if (((IPTR)g->dc.data) & ~g->dosenvec->de_Mask)
298 ErrorMsg (AFS_WARNING_MEMORY_MASK, NULL, g);
300 if (!OpenTimerDevice(&g->timeport, &g->trequest, UNIT_VBLANK, g) )
301 return FALSE;
303 g->removable = TestRemovability(g);
304 if(g->removable)
305 InstallDiskChangeHandler(g);
307 InstallResetHandler(g);
309 #if !defined(__MORPHOS__) || defined(DISK_BASED_FILESYSTEM)
310 AddToFSResource (g->dosenvec->de_DosType, ((struct DosList *)devnode)->dol_misc.dol_handler.dol_SegList, g);
311 #endif
313 #if EXTRAPACKETS
314 g->sleepport = CreateMsgPort();
315 #endif
317 DB(Trace(1,"Initialize","Removable = %ld", (ULONG)g->removable));
318 EXIT("initialize");
320 return TRUE;
323 /* added from HDVersion7.0B 11-4-94 */
324 static BOOL TestRemovability(globaldata *g)
326 #if 0
328 struct DriveGeometry *geom = g->geom;
329 struct IOExtTD *request = g->request;
330 BOOL result;
332 if(g->trackdisk)
334 request->iotd_Req.io_Data = g->geom;
335 request->iotd_Req.io_Command = TD_GETGEOMETRY;
336 request->iotd_Req.io_Length = sizeof(struct DriveGeometry);
338 if(DoIO((struct IORequest *)request) == 0)
339 result = geom->dg_Flags & DGF_REMOVABLE;
340 else
341 result = 1; /* trackdisk assumed to be removable */
343 else
345 struct DosEnvec *env = g->dosenvec;
347 if( (env->de_Surfaces <= 2) && (env->de_LowCyl == 0) )
348 result = 1; /* to accomodate things like the diskspare.device */
349 else
350 result = 0; /* disk is assumed to be NOT removable by default */
353 return(result);
355 #else
356 return 1; /* to accomodate SyQuest, Floptical etc */
357 #endif
360 /* added from HDVersion7.0B 11-4-94 */
361 static void InstallDiskChangeHandler(struct globaldata *g)
363 struct IOExtTD *request;
364 struct Interrupt *di;
365 UBYTE *intname;
366 static const UBYTE *intext = "_interrupt";
368 intname = AllocMemR (g->mountname[0]+strlen(intext)+1, MEMF_PUBLIC, g);
369 CopyMem(g->mountname+1,intname,g->mountname[0]);
370 CopyMem((APTR)intext,intname+g->mountname[0],strlen(intext)+1);
371 DB(Trace(1,"Installdiskchangehandler","intname: %s\n",intname));
373 di = g->diskinterrupt = AllocMemR (sizeof(struct Interrupt), MEMF_PUBLIC|MEMF_CLEAR, g);
374 di->is_Node.ln_Type = NT_INTERRUPT;
375 di->is_Node.ln_Name = intname;
376 di->is_Data = (APTR)g;
377 di->is_Code = (VOID_FUNC)DiskChangeHandler;
379 g->diskchangesigbit = AllocSignal(-1);
380 g->diskchangesignal = 1 << g->diskchangesigbit;
382 /* make special request structure for inthandler */
383 request = g->handlrequest = (struct IOExtTD *)
384 AllocMemR (sizeof(struct IOExtTD), MEMF_PUBLIC, g);
385 CopyMem(g->request, request, sizeof(*request));
387 request->iotd_Req.io_Length = sizeof(struct Interrupt);
388 request->iotd_Req.io_Data = (APTR)di;
389 request->iotd_Req.io_Command = TD_ADDCHANGEINT;
390 SendIO((struct IORequest *)request);
393 void UninstallDiskChangeHandler(struct globaldata *g)
395 struct IOExtTD *request = g->handlrequest;
397 if (!g->diskinterrupt)
398 return;
399 request->iotd_Req.io_Length = sizeof(struct Interrupt);
400 request->iotd_Req.io_Data = (APTR)g->diskinterrupt;
401 request->iotd_Req.io_Command = TD_REMCHANGEINT;
402 DoIO ((struct IORequest *)request);
403 FreeVec (request);
404 FreeVec (g->diskinterrupt->is_Node.ln_Name);
405 FreeVec (g->diskinterrupt);
406 FreeSignal (g->diskchangesigbit);
409 static void InstallResetHandler(struct globaldata *g)
411 static const char handlername[] = "_resethandler";
412 struct Interrupt *ri;
413 ri = AllocMemR( sizeof(*ri) + g->mountname[0] + sizeof(handlername), MEMF_PUBLIC, g);
414 if (ri)
416 LONG sigbit = AllocSignal(-1);
417 if (sigbit != -1)
419 ri->is_Node.ln_Type = NT_INTERRUPT;
420 ri->is_Node.ln_Pri = -32; /* Lowest possible priority, after everything else */
421 ri->is_Node.ln_Name = (char *) (ri + 1);
422 ri->is_Data = (APTR) g;
423 ri->is_Code = (void (*)(void)) ResetHandler;
424 CopyMem(g->mountname + 1, ri->is_Node.ln_Name, g->mountname[0]);
425 CopyMem((APTR)handlername, ri->is_Node.ln_Name + g->mountname[0], sizeof(handlername));
426 #if defined(__MORPHOS__) && defined(SYSTEM_PRIVATE)
427 AddResetHandler(ri);
428 g->resethandlerinterrupt = ri;
429 g->resethandlersigbit = sigbit;
430 g->resethandlersignal = 1L << sigbit;
431 ri = 0;
432 sigbit = -1;
433 #else
435 struct MsgPort mp;
436 struct IOStdReq *ioreq;
437 memset(&mp, 0, sizeof(mp));
438 mp.mp_Node.ln_Type = NT_MSGPORT;
439 mp.mp_Flags = PA_SIGNAL;
440 mp.mp_SigBit = sigbit;
441 mp.mp_SigTask = FindTask(0);
442 NewList(&mp.mp_MsgList);
444 ioreq = CreateIORequest(&mp, sizeof(*ioreq));
445 if (ioreq)
447 if (OpenDevice("keyboard.device", 0, (APTR) ioreq, 0) == 0)
449 ioreq->io_Command = KBD_ADDRESETHANDLER;
450 ioreq->io_Data = ri;
451 ioreq->io_Length = sizeof(struct Interrupt);
452 if (DoIO((APTR) ioreq) == 0)
454 g->resethandlerioreq = ioreq;
455 g->resethandlerinterrupt = ri;
456 g->resethandlersigbit = sigbit;
457 g->resethandlersignal = 1L << sigbit;
458 SetSignal(0, g->resethandlersignal);
459 ioreq->io_Message.mn_ReplyPort = 0;
460 ioreq = 0;
461 ri = 0;
462 sigbit = -1;
465 DeleteIORequest(ioreq);
468 #endif
469 FreeSignal(sigbit);
471 FreeVec(ri);
475 void HandshakeResetHandler(struct globaldata *g)
477 struct Interrupt *ri = g->resethandlerinterrupt;
478 if (ri)
480 #if defined(__MORPHOS__) && defined(SYSTEM_PRIVATE)
481 FinishResetHandler(ri);
482 #else
483 struct IOStdReq *ioreq = g->resethandlerioreq;
484 struct MsgPort mp;
486 memset(&mp, 0, sizeof(mp));
487 mp.mp_Node.ln_Type = NT_MSGPORT;
488 mp.mp_Flags = PA_SIGNAL;
489 mp.mp_SigBit = g->resethandlersigbit;
490 mp.mp_SigTask = FindTask(0);
491 NewList(&mp.mp_MsgList);
493 ioreq->io_Message.mn_ReplyPort = &mp;
494 ioreq->io_Command = KBD_RESETHANDLERDONE;
495 ioreq->io_Data = ri;
496 ioreq->io_Length = sizeof(struct Interrupt);
497 DoIO((APTR) ioreq);
499 ioreq->io_Message.mn_ReplyPort = 0;
500 SetSignal(0, g->resethandlersignal);
501 #endif
505 void UninstallResetHandler(struct globaldata *g)
507 struct Interrupt *ri = g->resethandlerinterrupt;
508 g->resethandlerinterrupt = 0;
509 if (ri)
511 #if defined(__MORPHOS__) && defined(SYSTEM_PRIVATE)
512 RemResetHandler(ri);
513 #else
514 struct IOStdReq *ioreq = g->resethandlerioreq;
515 struct MsgPort mp;
516 memset(&mp, 0, sizeof(mp));
517 mp.mp_Node.ln_Type = NT_MSGPORT;
518 mp.mp_Flags = PA_SIGNAL;
519 mp.mp_SigBit = g->resethandlersigbit;
520 mp.mp_SigTask = FindTask(0);
521 NewList(&mp.mp_MsgList);
523 ioreq->io_Message.mn_ReplyPort = &mp;
524 ioreq->io_Command = KBD_REMRESETHANDLER;
525 ioreq->io_Data = ri;
526 ioreq->io_Length = sizeof(struct Interrupt);
527 DoIO((APTR) ioreq);
528 CloseDevice((APTR) ioreq);
529 DeleteIORequest((APTR) ioreq);
530 #endif
531 FreeVec(ri);
532 FreeSignal(g->resethandlersigbit);
536 #endif
538 /* OpenDiskDevice
540 ** Used by L2.InitUnit()
542 ** Opens the diskdevice specified by 'startup' and generates the corresponding
543 ** messageport and requeststructure which are returned in 'port' and 'request'
545 ** in startup
546 ** out port, request, trackdisk
548 static BOOL OpenDiskDevice(struct FileSysStartupMsg *startup, struct MsgPort **port,
549 struct IOExtTD **request, BOOL *trackdisk, globaldata *g)
551 UBYTE name[FNSIZE];
553 *port = CreateMsgPort();
554 if(*port)
556 *request = (struct IOExtTD *)CreateIORequest(*port, sizeof(struct IOExtTD));
557 if(*request)
559 BCPLtoCString(name, (UBYTE *)BADDR(startup->fssm_Device));
560 *trackdisk = (strcmp(name, "trackdisk.device") == 0) || (strcmp(name, "diskspare.device") == 0);
562 #if KS13WRAPPER_DEBUG
563 DebugPutStr("Opening device..\n");
564 DebugPutStr(name);
565 DebugPutStr("\n");
566 #endif
568 if(OpenDevice(name, startup->fssm_Unit, (struct IORequest *)*request,
569 startup->fssm_Flags) == 0)
570 return TRUE;
571 DeleteIORequest(*request);
572 *request = 0;
574 DeleteMsgPort(*port);
575 *port = 0;
577 return FALSE;
580 static BOOL init_device_unit_sema(struct FileSysStartupMsg *startup, globaldata *g)
582 struct {
583 struct SignalSemaphore ss;
584 char name[1];
585 } *sema;
586 sema = AllocVec(sizeof(*sema) + 4 + ((UBYTE *)BADDR(startup->fssm_Device))[0] + 14, MEMF_PUBLIC);
587 if (sema)
589 strcpy(sema->name, "PFS_");
590 BCPLtoCString(&sema->name[4], (UBYTE *)BADDR(startup->fssm_Device));
591 strcat(sema->name, "/");
592 stcu_d(&sema->name[strlen(sema->name)], startup->fssm_Unit);
594 Forbid();
595 g->device_unit_lock_sema = FindSemaphore(sema->name);
596 if (g->device_unit_lock_sema)
598 FreeVec(sema);
600 else
602 memset(&sema->ss, 0, sizeof(sema->ss));
603 InitSemaphore(&sema->ss);
604 sema->ss.ss_Link.ln_Name = sema->name;
605 sema->ss.ss_Link.ln_Pri = -128;
606 sema->ss.ss_Link.ln_Type = NT_SIGNALSEM;
607 if (g->g_SysBase->LibNode.lib_Version < 36) {
608 Enqueue(&g->g_SysBase->SemaphoreList, &sema->ss);
609 } else {
610 AddSemaphore(&sema->ss);
612 g->device_unit_lock_sema = &sema->ss;
614 Permit();
615 g->device_unit_lock_count = 0;
616 return TRUE;
618 return FALSE;
621 void lock_device_unit(struct globaldata *g)
623 if (g->device_unit_lock_count++ == 0)
624 ObtainSemaphore(g->device_unit_lock_sema);
627 void unlock_device_unit(struct globaldata *g)
629 if (g->device_unit_lock_count)
631 if (--g->device_unit_lock_count == 0)
632 ReleaseSemaphore(g->device_unit_lock_sema);
637 static BOOL OpenTimerDevice(struct MsgPort **port, struct timerequest **request,
638 ULONG unit, globaldata *g)
640 *port = CreateMsgPort();
641 if(*port)
643 *request = (struct timerequest *)
644 CreateIORequest(*port, sizeof(struct timerequest));
645 if(*request)
647 if(!OpenDevice(TIMERNAME, unit, (struct IORequest *)*request, 0))
648 return(TRUE);
651 return(FALSE);
654 #if !defined(__MORPHOS__) || defined(DISK_BASED_FILESYSTEM)
655 /* AddToFSResource
657 ** function supplied by Nicola Salmoria
659 static BOOL AddToFSResource(ULONG dostype, BPTR seglist, struct globaldata *g)
661 struct FileSysResource *FileSysResBase;
663 FileSysResBase = (struct FileSysResource *)OpenResource(FSRNAME);
664 if (FileSysResBase)
666 struct FileSysEntry *fse,*nfse;
668 Forbid();
670 fse = (struct FileSysEntry *)FileSysResBase->fsr_FileSysEntries.lh_Head;
671 while ((nfse = (struct FileSysEntry *)fse->fse_Node.ln_Succ))
673 /* if filesystem already in resource, return */
674 if (fse->fse_DosType == dostype)
676 DB(Trace(4,"ADDTORESOURCE","Already there\n"));
677 break;
680 fse = nfse;
683 if (!nfse && (fse = AllocMem(sizeof(struct FileSysEntry), MEMF_PUBLIC | MEMF_CLEAR)))
685 fse->fse_Node.ln_Name = (UBYTE *)&version[6];
686 fse->fse_DosType = dostype;
687 fse->fse_Version = ((LONG)VERNUM) << 16 | REVNUM;
688 fse->fse_PatchFlags = 0x180;
689 fse->fse_SegList = seglist;
690 fse->fse_GlobalVec = (BPTR)(SIPTR)-1;
692 AddHead(&FileSysResBase->fsr_FileSysEntries,&fse->fse_Node);
695 Permit();
698 return TRUE;
700 #endif
703 /* Reconfigure the filesystem from a rootblock
704 ** GetDriveGeometry already called by GetCurrentRoot, which does
705 ** g->firstblock and g->lastblock.
706 ** rootblockextension must have been loaded
708 void InitModules (struct volumedata *volume, BOOL formatting, globaldata *g)
710 rootblock_t *rootblock = volume->rootblk;
712 g->rootblock = rootblock;
713 g->uip = 0;
714 g->harddiskmode = (rootblock->options & MODE_HARDDISK) != 0;
715 g->anodesplitmode = (rootblock->options & MODE_SPLITTED_ANODES) != 0;
716 g->dirextension = (rootblock->options & MODE_DIR_EXTENSION) != 0;
717 #if DELDIR
718 g->deldirenabled = (rootblock->options & MODE_DELDIR) &&
719 g->dirextension && (volume->rblkextension->blk.deldirsize > 0);
720 #endif
721 g->supermode = (rootblock->options & MODE_SUPERINDEX) != 0;
722 g->fnsize = (volume->rblkextension) ? (volume->rblkextension->blk.fnsize) : 32;
723 if (!g->fnsize) g->fnsize = 32;
724 g->largefile = (rootblock->options & MODE_LARGEFILE) && g->dirextension && LARGE_FILE_SIZE;
726 InitAnodes (volume, formatting, g);
727 InitAllocation (volume, g);
729 #if VERSION23
730 if (!formatting)
731 DoPostponed (volume, g);
732 #endif
736 #if VERSION23
737 static void DoPostponed (struct volumedata *volume, globaldata *g)
739 struct crootblockextension *rext;
740 struct anodechain *achain;
741 struct postponed_op *postponed;
743 rext = volume->rblkextension;
744 if (rext)
746 postponed = &rext->blk.tobedone;
748 switch (postponed->operation_id)
750 case PP_FREEBLOCKS_FREE:
752 /* we assume we have enough memory at startup.. */
753 achain = GetAnodeChain (postponed->argument1, g);
754 FreeBlocksAC (achain, postponed->argument2, freeanodes, g);
755 break;
757 case PP_FREEBLOCKS_KEEP:
759 /* we assume we have enough memory at startup.. */
760 achain = GetAnodeChain (postponed->argument1, g);
761 alloc_data.clean_blocksfree -= postponed->argument3;
762 alloc_data.alloc_available -= postponed->argument3;
763 FreeBlocksAC (achain, postponed->argument2, keepanodes, g);
764 break;
766 case PP_FREEANODECHAIN:
768 FreeAnodesInChain (postponed->argument1, g);
769 break;
772 postponed->operation_id = 0;
773 postponed->argument1 = 0;
774 postponed->argument2 = 0;
775 postponed->argument3 = 0;
778 #endif