3 * Revision 12.9 1999/09/11 17:05:14 Michiel
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)
16 * Revision 12.5 1998/09/03 07:12:14 Michiel
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
26 * Revision 12.2 1996/03/07 10:05:24 Michiel
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
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
53 * Revision 11.10 1995/07/07 14:39:17 Michiel
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
62 * Revision 11.7 1995/05/20 12:12:12 Michiel
63 * Updated messages to reflect Ami-FileLock
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
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)
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
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>
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"
133 extern CONST UBYTE
*version
;
135 extern void __asm
ResetHandler(void);
136 #elif defined(__AROS__)
137 extern AROS_INTP(DiskChangeHandler
);
138 extern AROS_INTP(ResetHandler
);
140 extern void ResetHandler(void);
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
*);
156 static void DoPostponed (struct volumedata
*volume
, globaldata
*g
);
159 /**********************************************************************/
163 /**********************************************************************/
166 BOOL
Initialize(DSTR mountname
, struct FileSysStartupMsg
*fssm
,
167 struct DeviceNode
*devnode
, globaldata
*g
)
172 BOOL
Initialize(DSTR mountname
, struct FileSysStartupMsg
*fssm
,
173 struct DeviceNode
*devnode
, globaldata
*g
)
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
;
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
);
217 g
->bufferPool
= LibCreatePool (g
->dosenvec
->de_BufMemType
, 20*1024, 16*1024);
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);
242 ErrorMsg (AFS_ERROR_MEMORY_POOL
, NULL
, g
);
246 g
->blocksize
= g
->dosenvec
->de_SizeBlock
<< 2;
251 g
->directsize
= 16*1024>>i
;
254 g
->tdmode
= ACCESS_UNDETECTED
;
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
))) {
260 g
->tdmode
= ACCESS_TD64
;
262 g
->tdmode
= ACCESS_NSD
;
264 g
->tdmode
= ACCESS_DS
;
270 if (!(g
->geom
= AllocMemP (sizeof(struct DriveGeometry
), g
)))
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
) )
279 DB(Trace(4,"Init","result = %ld",(ULONG
)g
->trackdisk
));
281 if (!init_device_unit_sema(fssm
, g
))
284 /* mode now always big */
285 g
->harddiskmode
= TRUE
;
288 g
->dc
.size
= DATACACHELEN
;
289 g
->dc
.mask
= DATACACHEMASK
;
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
)
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
) )
303 g
->removable
= TestRemovability(g
);
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
);
314 g
->sleepport
= CreateMsgPort();
317 DB(Trace(1,"Initialize","Removable = %ld", (ULONG
)g
->removable
));
323 /* added from HDVersion7.0B 11-4-94 */
324 static BOOL
TestRemovability(globaldata
*g
)
328 struct DriveGeometry
*geom
= g
->geom
;
329 struct IOExtTD
*request
= g
->request
;
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
;
341 result
= 1; /* trackdisk assumed to be removable */
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 */
350 result
= 0; /* disk is assumed to be NOT removable by default */
356 return 1; /* to accomodate SyQuest, Floptical etc */
360 /* added from HDVersion7.0B 11-4-94 */
361 static void InstallDiskChangeHandler(struct globaldata
*g
)
363 struct IOExtTD
*request
;
364 struct Interrupt
*di
;
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
)
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
);
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
);
416 LONG sigbit
= AllocSignal(-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)
428 g
->resethandlerinterrupt
= ri
;
429 g
->resethandlersigbit
= sigbit
;
430 g
->resethandlersignal
= 1L << sigbit
;
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
));
447 if (OpenDevice("keyboard.device", 0, (APTR
) ioreq
, 0) == 0)
449 ioreq
->io_Command
= KBD_ADDRESETHANDLER
;
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;
465 DeleteIORequest(ioreq
);
475 void HandshakeResetHandler(struct globaldata
*g
)
477 struct Interrupt
*ri
= g
->resethandlerinterrupt
;
480 #if defined(__MORPHOS__) && defined(SYSTEM_PRIVATE)
481 FinishResetHandler(ri
);
483 struct IOStdReq
*ioreq
= g
->resethandlerioreq
;
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
;
496 ioreq
->io_Length
= sizeof(struct Interrupt
);
499 ioreq
->io_Message
.mn_ReplyPort
= 0;
500 SetSignal(0, g
->resethandlersignal
);
505 void UninstallResetHandler(struct globaldata
*g
)
507 struct Interrupt
*ri
= g
->resethandlerinterrupt
;
508 g
->resethandlerinterrupt
= 0;
511 #if defined(__MORPHOS__) && defined(SYSTEM_PRIVATE)
514 struct IOStdReq
*ioreq
= g
->resethandlerioreq
;
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
;
526 ioreq
->io_Length
= sizeof(struct Interrupt
);
528 CloseDevice((APTR
) ioreq
);
529 DeleteIORequest((APTR
) ioreq
);
532 FreeSignal(g
->resethandlersigbit
);
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'
546 ** out port, request, trackdisk
548 static BOOL
OpenDiskDevice(struct FileSysStartupMsg
*startup
, struct MsgPort
**port
,
549 struct IOExtTD
**request
, BOOL
*trackdisk
, globaldata
*g
)
553 *port
= CreateMsgPort();
556 *request
= (struct IOExtTD
*)CreateIORequest(*port
, sizeof(struct IOExtTD
));
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");
568 if(OpenDevice(name
, startup
->fssm_Unit
, (struct IORequest
*)*request
,
569 startup
->fssm_Flags
) == 0)
571 DeleteIORequest(*request
);
574 DeleteMsgPort(*port
);
580 static BOOL
init_device_unit_sema(struct FileSysStartupMsg
*startup
, globaldata
*g
)
583 struct SignalSemaphore ss
;
586 sema
= AllocVec(sizeof(*sema
) + 4 + ((UBYTE
*)BADDR(startup
->fssm_Device
))[0] + 14, MEMF_PUBLIC
);
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
);
595 g
->device_unit_lock_sema
= FindSemaphore(sema
->name
);
596 if (g
->device_unit_lock_sema
)
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
);
610 AddSemaphore(&sema
->ss
);
612 g
->device_unit_lock_sema
= &sema
->ss
;
615 g
->device_unit_lock_count
= 0;
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();
643 *request
= (struct timerequest
*)
644 CreateIORequest(*port
, sizeof(struct timerequest
));
647 if(!OpenDevice(TIMERNAME
, unit
, (struct IORequest
*)*request
, 0))
654 #if !defined(__MORPHOS__) || defined(DISK_BASED_FILESYSTEM)
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
);
666 struct FileSysEntry
*fse
,*nfse
;
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"));
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
);
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
;
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;
718 g
->deldirenabled
= (rootblock
->options
& MODE_DELDIR
) &&
719 g
->dirextension
&& (volume
->rblkextension
->blk
.deldirsize
> 0);
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
);
731 DoPostponed (volume
, g
);
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
;
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
);
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
);
766 case PP_FREEANODECHAIN
:
768 FreeAnodesInChain (postponed
->argument1
, g
);
772 postponed
->operation_id
= 0;
773 postponed
->argument1
= 0;
774 postponed
->argument2
= 0;
775 postponed
->argument3
= 0;