PFS3-experimental sync. Large partition/filesize support is mostly complete now.
[AROS.git] / rom / filesys / pfs3 / fs / struct.h
blobee462fd043ae2bc62f169f6a22231b483c1c6fd4
1 /* $Id$
2 * $Log: struct.h $
3 * Revision 2.16 1999/05/14 11:31:34 Michiel
4 * Long filename support implemented; bugfixes
6 * Revision 2.15 1999/03/09 10:41:34 Michiel
7 * Deldir extension en bitwise reserved roving
9 * Revision 2.14 1998/10/02 07:22:45 Michiel
10 * final release 4.2 version
12 * Revision 2.13 1998/09/27 11:26:37 Michiel
13 * Removed ErrorMsg (now is a function)
15 * Revision 2.12 1998/09/03 07:12:14 Michiel
16 * versie 17.4
17 * bugfixes 118, 121, 123 and superindexblocks and td64 support
19 * Revision 2.11 1998/05/31 16:27:42 Michiel
20 * added ACTION_IS_PFS2
21 * moved freeblocktype from allocprotos
23 * Revision 2.10 1998/05/27 20:16:13 Michiel
24 * AFS --> PFS2
26 * Revision 2.9 1998/05/22 20:48:29 Michiel
27 * Idle handle, anode_data_s uitbreiding
29 * Revision 2.8 1995/12/29 11:01:05 Michiel
30 * rolloverinfo structure and directscsi stuff added
32 * Revision 2.7 1995/11/15 15:54:48 Michiel
33 * IsTail() bug fixed
34 * volumedata->rblkextension added
36 * Revision 2.6 1995/11/07 17:28:46 Michiel
37 * struct allocation_data: reservedtobefreed cache, rtbf_index, res_alert, tbf_resneed
38 * macros (IsUpdateNeeded, ReservedAreaIsLocked and limits)
40 * Revision 2.5 1995/10/20 10:12:38 Michiel
41 * Anode reserved area adaptions (16.3)
42 * --> andata.reserved, 'RESERVEDANODES' added; AllocAnode macro removed
44 * Revision 2.4 1995/10/11 23:27:26 Michiel
45 * new diskcache stuff (see disk.c r14)
47 * Revision 2.3 1995/10/05 09:18:18 Michiel
48 * rovingbit added to alloc_data
50 * Revision 2.2 1995/10/03 12:06:33 Michiel
51 * merge fix
53 * Revision 1.12 1995/09/01 11:27:01 Michiel
54 * ErrorMsg adaption (see disk.c and volume.c)
56 * Revision 1.11 1995/08/21 04:21:10 Michiel
57 * added some extra packets
59 * Revision 1.10 1995/07/28 08:26:17 Michiel
60 * dieing field
62 * Revision 1.9 1995/07/21 07:00:57 Michiel
63 * importing messages.h
64 * DELDIR stuff
66 * Revision 1.8 1995/07/11 09:24:38 Michiel
67 * DELDIR stuff
69 * Revision 1.7 1995/06/23 17:33:00 Michiel
70 * added 'action' to globaldata
72 * Revision 1.6 1995/06/23 06:42:42 Michiel
73 * Soft-Protection after ErrorMsg
74 * Pooled allocation stuff
75 * muFS stuff
77 * Revision 1.5 1995/06/04 06:12:33 Michiel
78 * added demo stuff
80 * Revision 1.4 1995/03/30 10:49:35 Michiel
81 * notifyobject, notifylist and notifyport added
83 * Revision 1.3 1995/03/24 16:34:27 Michiel
84 * g->myproc is back (needed for changeint)
85 * softlinkdir added
87 * Revision 1.2 1995/02/28 18:28:10 Michiel
88 * changed // to C comment and added originalsize
90 * Revision 1.1 1995/02/15 16:46:16 Michiel
91 * Initial revision
95 #ifndef _STRUCT_H
96 #define _STRUCT_H 1
98 #ifndef _STRING_H
99 #include <string.h>
100 #endif
101 #ifndef DOS_DOSEXTENS_H
102 #include <dos/dosextens.h>
103 #endif
104 #ifndef DEVICES_TRACKDISK_H
105 #include <devices/trackdisk.h>
106 #endif
107 #ifndef PROTO_EXEC_H
108 #include <proto/exec.h>
109 #endif
110 #ifndef PROTO_DOS_H
111 #include <proto/dos.h>
112 #endif
113 #ifndef _STDDEFH
114 #include <stddef.h>
115 #endif
116 #if MULTIUSER
117 #ifndef LIBRARIES_MULTIUSER_H
118 #include <libraries/multiuser.h>
119 #endif
120 #endif
121 #ifndef DEVICES_SCSIDISK_H
122 #include <devices/scsidisk.h>
123 #endif
127 /****************************************************************************/
128 /* Useful macros to handle various compiler dependecies */
129 /****************************************************************************/
131 #if defined(__GNUC__)
132 #define __READONLY__ __attribute__((section(".rodata")))
133 #if __GNUC__ > 2
134 #define __USED__ __attribute__((used))
135 #else
136 #define __USED__
137 #endif
138 #else
139 #define __READONLY__
140 #define __USED__
141 #endif
143 /****************************************************************************/
144 /* For SAS/C use amiga.lib assembly memory pool routines */
145 /****************************************************************************/
146 #ifdef __SASC
147 void * __asm AsmCreatePool(register __d0 ULONG,
148 register __d1 ULONG,
149 register __d2 ULONG,
150 register __a6 struct ExecBase *);
151 void __asm AsmDeletePool(register __a0 void *,
152 register __a6 struct ExecBase *);
153 void * __asm AsmAllocPooled(register __a0 void *,
154 register __d0 ULONG,
155 register __a6 struct ExecBase *);
156 void __asm AsmFreePooled(register __a0 void *,
157 register __a1 void *,
158 register __d0 ULONG,
159 register __a6 struct ExecBase *);
160 #define LibCreatePool(a,b,c) AsmCreatePool(a,b,c,SysBase)
161 #define LibDeletePool(p) AsmDeletePool(p,SysBase)
162 #define LibAllocPooled(p,s) AsmAllocPooled(p,s,SysBase)
163 #define LibFreePooled(p,m,s) AsmFreePooled(p,m,s,SysBase)
164 /* Workaround for old NDK */
165 #ifndef CONST
166 #define CONST const
167 #endif
168 #if INCLUDE_VERSION < 44
169 typedef CONST unsigned char *CONST_STRPTR;
170 #endif
171 #endif
173 /****************************************************************************/
174 /* MorphOS specific global headers */
175 /****************************************************************************/
177 #ifdef __MORPHOS__
178 #include <clib/macros.h>
179 #define min(a,b) MIN(a,b)
180 #define max(a,b) MAX(a,b)
181 #undef NewList
182 #define NewList(l) NEWLIST(l)
183 #undef Insert
184 #define Insert(l,n,ln) INSERT(l,n,ln)
185 #undef AddHead
186 #define AddHead(l,n) ADDHEAD(l,n)
187 #undef AddTail
188 #define AddTail(l,n) ADDTAIL(l,n)
189 #undef Remove
190 #define Remove(n) REMOVE(n)
191 #undef RemHead
192 #define RemHead(l) REMHEAD(l)
193 #undef RemTail
194 #define RemTail(l) REMTAIL(l)
195 #define memcpy(d,s,n) CopyMem(s,d,n)
196 #endif
198 /****************************************************************************/
199 /* AROS specific global headers */
200 /****************************************************************************/
202 #ifdef __AROS__
203 #include <proto/alib.h>
204 #include <clib/macros.h>
205 #define min(a,b) MIN(a,b)
206 #define max(a,b) MAX(a,b)
207 #undef IsMinListEmpty
208 #define __saveds
209 #define COUNT UWORD
210 #define UCOUNT WORD
211 #endif
213 /****************************************************************************/
214 /* New actions (packets) */
215 /****************************************************************************/
217 #define ACTION_KILL_EMPTY 3000
218 #define ACTION_SLEEP 2200
219 #define ACTION_UPDATE_ANODE 2201
220 #define ACTION_PFS2_INFO 2202
221 #define ACTION_PFS2_CONFIG 2203
222 #define ACTION_REMOVE_DIRENTRY 2204
223 //#if ROLLOVER
224 #define ACTION_CREATE_ROLLOVER 2205
225 #define ACTION_SET_ROLLOVER 2206
226 #define ACTION_IS_PFS2 2211
227 #define ACTION_ADD_IDLE_SIGNAL 2220
228 #define ACTION_SET_DELDIR 2221
229 #define ACTION_SET_FNSIZE 2222
230 //#endif
232 /****************************************************************************/
233 /* muFS related defines */
234 /****************************************************************************/
236 #if MULTIUSER
237 #define MUFS(x) x
238 #else
239 #define MUFS(x)
240 #endif
242 /* flags that allow SetProtect, SetOwner, SetDate, SetComment etc */
243 #define muRel_PROPERTY_ACCESS (muRelF_ROOT_UID|muRelF_UID_MATCH|muRelF_NO_OWNER)
245 /****************************************************************************/
246 /* CACHE related defines */
247 /****************************************************************************/
249 /* Locking. Dirblocks used during a operation have to be locked
250 * with LOCK() (happens in LoadDirBlock() and UpdateLE())
251 * UNLOCKALL() unlocks all blocks..
253 #define LOCK(blk) ((blk)->used = g->locknr)
254 #define UNLOCKALL() (g->locknr++)
255 #define ISLOCKED(blk) ((blk)->used == g->locknr)
257 /* Cache hashing table mask values for dir and anode */
258 #define HASHM_DIR 0x1f
259 #define HASHM_ANODE 0x7
262 /****************************************************************************/
263 /* general defines */
264 /****************************************************************************/
266 #define WITH(x) x;
267 typedef unsigned char *DSTR; /* pascal string: length, than characters */
268 typedef enum {false, true} bool;
270 /*****************************************************************************/
271 /* Rollover info structure */
272 /*****************************************************************************/
274 /* used by ACTION_SET_ROLLOVER */
275 #if defined(__GNUC__) || defined(__VBCC__)
276 /* Force SAS/C compatible alignment rules for this structure */
277 #pragma pack(2)
278 #endif
279 struct rolloverinfo
281 BOOL set; /* 0 -> read; 1 -> write */
282 ULONG realsize;
283 ULONG virtualsize;
284 ULONG rollpointer;
286 #if defined(__GNUC__) || defined(__VBCC__)
287 #pragma pack()
288 #endif
291 /*****************************************************************************/
292 /* Allocation data */
293 /*****************************************************************************/
296 * The global allocation data
298 * the number of blocks really free can be found in rootblock->blocksfree
299 * rootblock fields:
300 * ULONG blocksfree // total blocks free
301 * ULONG alwaysfree // blocks to be kept always free
302 * ULONG rovingptr // roving 'normal' alloc pointer
303 * ULONG reserved_free // number of free reserved blocks
305 * volumedata fields:
306 * ULONG numblocks // total number of blocks
307 * struct MinList bmblks
308 * struct MinList bmindex
310 * andata field indexperblock is also used
312 * res_rovingptr: roving 'reserved' alloc pointer
314 * clean_blocksfree: directly available blocks (inc alwaysfree!). Updated by UpdateFreeList.
315 * increased only by Update(), UpdateFreeList() and FlushBlock()
316 * decreased by AllocateBlocks(), AllocReserved()
318 * alloc_available: number of eventually available blocks (exc alwaysfree!).
319 * increased by FreeBlocks(), FreeReservedBlock()
320 * decreased by AllocateBlocks()
322 * rootblock->blocksfree: only updated by Update(). Real number of blocks free (inc alwaysfree).
324 * reserved bitmap: behind rootblock. [0] = #free.
327 /* cache grootte */
328 #define RTBF_CACHE_SIZE 512
329 #define TBF_CACHE_SIZE 256
331 /* update thresholds */
332 #define RTBF_THRESHOLD 256
333 #define RTBF_CHECK_TH 128
334 #define RTBF_POSTPONED_TH 48
335 #define TBF_THRESHOLD 252
336 #define RESFREE_THRESHOLD 10
338 /* indices in tobefreed array */
339 #define TBF_BLOCKNR 0
340 #define TBF_SIZE 1
342 /* buffer for AllocReservedBlockSave */
343 #define RESERVED_BUFFER 10
345 /* check for reserved block allocation lock */
346 #define ReservedAreaIsLocked (alloc_data.res_alert)
348 /* checks if update is needed now */
349 #define IsUpdateNeeded(rtbf_threshold) \
350 ((alloc_data.rtbf_index > rtbf_threshold) || \
351 (g->rootblock->reserved_free < RESFREE_THRESHOLD + 5 + alloc_data.tbf_resneed)) \
353 /* keep or free anodes when freeing blocks */
354 enum freeblocktype {keepanodes, freeanodes};
356 struct allocation_data_s
358 ULONG clean_blocksfree; /* number of blocks directly allocatable */
359 ULONG alloc_available; /* cleanblocksfree + blockstobefreed - alwaysfree */
360 ULONG longsperbmb; /* longwords per bitmapblock */
361 ULONG no_bmb; /* number of bitmap blocks */
362 ULONG bitmapstart; /* blocknr at which bitmap starts */
363 ULONG tobefreed[TBF_CACHE_SIZE][2]; /* tobefreed array */
364 ULONG tobefreed_index;
365 ULONG tbf_resneed; /* max reserved blks needed for tbf cache */
366 struct bitmapblock *res_bitmap; /* reserved block bitmap pointer */
367 ULONG res_roving; /* reserved roving pointer (0 at startup) */
368 UWORD rovingbit; /* bitnumber (within LW) of main roving pointer */
369 ULONG numreserved; /* total # reserved blocks (== lastreserved+1) */
370 ULONG *reservedtobefreed; /* tbf cache for flush reserved blocks */
371 ULONG rtbf_size; /* size of the allocated cache */
372 ULONG rtbf_index; /* current index in reserved tobefreed cache */
373 BOOL res_alert; /* TRUE if low on available reserved blocks */
376 /*****************************************************************************/
377 /* anode data */
378 /*****************************************************************************/
381 * The global anode data
383 * Other used globaldata fields:
384 * (*)getanodeblock()
385 * (*)allocanode()
387 struct anode_data_s
389 UWORD curranseqnr; /* current anode seqnr for anode allocation */
390 UWORD indexperblock; /* ALSO used by allocation (for bitmapindex blocks) */
391 ULONG maxanodeseqnr; /* max anode seqnr */
392 UWORD anodesperblock; /* number of anodes that fit in one block */
393 UWORD reserved; /* offset of first reserved anode within an anodeblock */
394 ULONG *anblkbitmap; /* anodeblock full-flag bitmap */
395 ULONG anblkbitmapsize; /* size of anblkbitmap */
396 ULONG maxanseqnr; /* current maximum anodeblock seqnr */
401 * anodecache structures
403 struct anodechainnode
405 struct anodechainnode *next;
406 struct canode an;
409 struct anodechain
411 struct anodechain *next;
412 struct anodechain *prev;
413 ULONG refcount; /* will be discarded if refcount becomes 0 */
414 struct anodechainnode head;
417 /* number of reserved anodes per anodeblock */
418 #define RESERVEDANODES 6
420 /*****************************************************************************/
421 /* LRU data */
422 /*****************************************************************************/
424 /* the LRU global data */
425 struct lru_data_s
427 struct MinList LRUqueue;
428 struct MinList LRUpool;
429 ULONG poolsize;
430 struct lru_cachedblock *LRUarray;
431 UWORD reserved_blksize;
435 /*****************************************************************************/
436 /* the diskcache */
437 /*****************************************************************************/
439 /* the cache is filled in a round robin manner, using 'roving' for
440 * the roundrobin pointer. Cache checking is done in the same manner;
441 * making the cache large will make it slow!
444 struct diskcache
446 struct reftable *ref; /* reference table; one entry per slot */
447 UBYTE *data; /* the data (one slot per block) */
448 UWORD size; /* cache capacity in blocks (order of 2) */
449 UWORD mask; /* size expressed in a bitmask */
450 UWORD roving; /* round robin roving pointer */
453 struct reftable
455 ULONG blocknr; /* blocknr of cached block; 0 = empty slot */
456 UBYTE dirty; /* dirty flag (TRUE/FALSE) */
457 UBYTE pad;
460 #define DATACACHELEN 32
461 #define DATACACHEMASK 0x1f
463 #define MarkDataDirty(i) (g->dc.ref[i].dirty = 1)
465 /*****************************************************************************/
466 /* globaldata structure */
467 /*****************************************************************************/
469 #define ACCESS_UNDETECTED 0
470 #define ACCESS_STD 1
471 #define ACCESS_DS 2
472 #define ACCESS_TD64 3
473 #define ACCESS_NSD 4
475 /* ALL globals are defined here */
476 struct globaldata
478 struct Process *myproc; /* our process (needed for diskchange interrupt) */
479 struct Interrupt *diskinterrupt; /* diskint & signal also used by interrupt. Don't change! */
480 ULONG diskchangesignal;
481 struct ExecBase *g_SysBase;
482 struct IntuitionBase *g_IntuitionBase;
483 struct Library *g_UtilityBase;
484 struct DosLibrary *g_DOSBase;
485 struct muBase *g_muBase;
486 struct MsgPort *msgport; /* communication port to DOS (normally == g->devnode->dn_Task) */
487 struct MsgPort *port; /* for communication with diskdevice */
488 struct IOExtTD *request; /* request structure for diskdevice */
489 struct IOExtTD *handlrequest; /* copy of request for diskchangehndl */
490 struct MsgPort *timeport;
491 struct timerequest *trequest;
492 struct MsgPort *notifyport; /* the replies to notification msgs come here */
493 struct MsgPort *sleepport; /* for update anode and unsleep packets */
494 struct DosPacket *action; /* the current handled dospacket */
496 struct DeviceNode *devnode; /* <4A> from startup msg */
497 struct FileSysStartupMsg *startup; /* idem */
498 struct DosEnvec *dosenvec; /* the fssm devlist */
499 struct DriveGeometry *geom; /* adapted according to DosEnvec!! (GetGeometry()) */
500 DSTR mountname; /* <4A> DSTR mountname */
502 /* partition info (volume dependent) %7 */
503 ULONG firstblock; /* first and last block of partition */
504 ULONG lastblock;
505 ULONG maxtransfer;
506 struct diskcache dc; /* cache to make '196 byte mode' faster */
508 /* LRU stuff */
509 BOOL uip; /* update in progress flag */
510 UWORD locknr; /* prevents blocks from being flushed */
512 /* The DOS packet interpreter */
513 void (*DoCommand)(struct DosPacket *, struct globaldata *);
515 /* Volume stuff */
516 struct MinList volumes; /* Volume list. Normally only one volume */
517 struct volumedata *currentvolume;
518 ULONG changecount; /* diskchange counter. Should be initialized by NewVolume */
519 ULONG inhibitcount;
521 /* disktype: ID_PFS_DISK/NO_DISK_PRESENT/UNREADABLE_DISK
522 * (only valid if currentvolume==NULL)
524 ULONG disktype;
526 /* state of currentvolume (ID_WRITE_PROTECTED/VALIDATED/VALIDATING) */
527 ULONG diskstate;
529 BOOL dieing; /* TRUE if ACTION_DIE called */
530 BYTE softprotect; /* 1 if 'ACTION_WRITE_PROTECTED' */
531 /* -1 if protection failed */
532 ULONG protectkey; /* key to unprotect */
533 /* ~0 als protected wegens error */
534 UWORD timeout; /* DosToHandlerInterface timeout value */
535 BOOL dirty; /* Global dirty flag */
536 BOOL timeron; /* change is being timed */
537 BOOL postpone; /* repeat timer when finished */
538 BOOL removable; /* Is volume removable? */
539 BOOL trackdisk; /* Is the device trackdisk? */
540 LONG (*ErrorMsg)(CONST_STRPTR, APTR, ULONG, struct globaldata *); /* The error message routine */
542 struct rootblock *rootblock; /* shortcut of currentvolume->rootblk */
543 UBYTE harddiskmode; /* flag: harddisk mode? */
544 UBYTE anodesplitmode; /* flag: anodesplit mode? */
545 UBYTE dirextension; /* flag: dirextension? */
546 UBYTE deldirenabled; /* flag: deldir enabled? */
547 UBYTE sleepmode; /* flag: sleepmode? */
548 UBYTE supermode; /* flag: supermode? (104 bmi blocks) */
549 UBYTE tdmode; /* ACCESS_x mode */
550 UBYTE largefile; /* >4G file size support */
551 ULONG blocksize; /* g->dosenvec->de_SizeBlock << 2 */
552 UWORD blockshift; /* 2 log van block size */
553 UWORD fnsize; /* filename size (18+) */
554 ULONG directsize; /* number of blocks after which direct */
555 /* access is preferred (config) */
557 char *unparsed; /* rest of path after a softlinkdir */
558 BOOL protchecked; /* checked protection? */
560 struct muExtOwner *user; /* task which called filesystem (muFS) */
561 BOOL muFS_ready; /* is the muFS server ready? */
563 void *mainPool; /* pool for pooled alloc (V39) */
564 void *bufferPool; /* pool for buffer alloc (V39) */
566 struct Task *sleeptask; /* task to send alarm messages to */
567 ULONG alarmsignal; /* ... and the signal to use */
568 struct MinList idlelist; /* list of tasks to notify when idle */
570 /* SCSIDIRECT stuff */
571 UBYTE sense[20]; /* area for scsi sense data */
572 struct SCSICmd scsicmd; /* scsi command structure */
574 // int (*allocate)(ULONG, ULONG, struct globaldata *);
575 // void (*free)(ULONG, ULONG, struct globaldata *);
576 // ULONG (*allocreserved)(ULONG, ULONG, struct globaldata *);
577 // void (*freereserved)(ULONG, struct globaldata *);
578 struct canodeblock *(*getanodeblock)(UWORD, struct globaldata *);
579 // ULONG (*allocanode)(APTR);
580 void *(*allocmemp)(ULONG, struct globaldata *);
581 void (*freememp)(void *, struct globaldata *);
582 void *(*allocbufmem)(ULONG, struct globaldata *);
583 void (*freebufmem)(void *, struct globaldata *);
585 struct anode_data_s glob_anodedata;
586 struct lru_data_s glob_lrudata;
587 struct allocation_data_s glob_allocdata;
589 BOOL updateok;
591 struct SignalSemaphore *device_unit_lock_sema;
592 LONG device_unit_lock_count;
594 #if !defined(__MORPHOS__) || !defined(SYSTEM_PRIVATE)
595 struct IOStdReq *resethandlerioreq;
596 #endif
597 LONG diskchangesigbit;
598 LONG resethandlersigbit;
599 ULONG resethandlersignal;
600 struct Interrupt *resethandlerinterrupt;
603 typedef struct globaldata globaldata;
605 /*****************************************************************************/
606 /* Library base macros */
607 /*****************************************************************************/
608 #define SysBase g->g_SysBase
609 #define IntuitionBase g->g_IntuitionBase
610 #define UtilityBase g->g_UtilityBase
611 #define DOSBase g->g_DOSBase
612 #define muBase g->g_muBase
614 /*****************************************************************************/
615 /* defined function macros */
616 /*****************************************************************************/
618 #define GetAnodeBlock(a, b) (g->getanodeblock)(a,b)
619 //#define AllocAnode(a) (g->allocanode)(a)
620 //#define AllocReservedBlock(a,b) (g->allocreserved)(a,b)
621 //#define FreeReservedBlock(a,b) (g->freereserved)(a,b)
623 //#define AllocateBlocks(a,b,c) (g->allocate)(a, b, c)
624 //#define FreeBlocks(a,b,c) (g->free)(a,b,c)
626 #define AllocMemP(size,g) ((g->allocmemp)(size,g))
627 #define FreeMemP(mem,g) ((g->freememp)(mem,g))
628 #define AllocBufmem(size,g) ((g->allocbufmem)(size,g))
629 #define FreeBufmem(mem,g) ((g->freebufmem)(mem,g))
631 /*****************************************************************************/
632 /* local globdata additions */
633 /*****************************************************************************/
635 #define alloc_data (g->glob_allocdata)
636 #define andata (g->glob_anodedata)
637 #define lru_data (g->glob_lrudata)
640 /*****************************************************************************/
641 /* volumedata */
642 /*****************************************************************************/
644 struct volumedata
646 struct volumedata *next; /* volumechain */
647 struct volumedata *prev;
648 struct DeviceList *devlist; /* <4A> device dos list */
649 struct rootblock *rootblk; /* the cached rootblock. Also in g. */
651 #if VERSION23
652 struct crootblockextension *rblkextension; /* extended rblk, NULL if disabled*/
653 #endif
655 struct MinList fileentries; /* all locks and open files */
656 struct MinList anblks[HASHM_ANODE+1]; /* anode block hash table */
657 struct MinList dirblks[HASHM_DIR+1]; /* dir block hash table */
658 struct MinList indexblks; /* cached index blocks */
659 struct MinList bmblks; /* cached bitmap blocks */
660 struct MinList superblks; /* cached super blocks */
661 struct MinList deldirblks; /* cached deldirblocks */
662 struct MinList bmindexblks; /* cached bitmap index blocks */
663 struct MinList anodechainlist; /* list of cached anodechains */
664 struct MinList notifylist; /* list of notifications */
666 BOOL rootblockchangeflag; /* indicates if rootblock dirty */
667 WORD numsofterrors; /* number of soft errors on this disk */
668 WORD diskstate; /* normally ID_VALIDATED */
669 ULONG numblocks; /* total number of blocks */
670 UWORD bytesperblock; /* blok size (datablocks) */
671 UWORD rescluster; /* reserved blocks cluster */
675 * Notify list. This is volume dependent, so part of volume
676 * structure
678 struct notifyobject
680 struct notifyobject *next;
681 struct notifyobject *prev;
682 struct NotifyRequest *req;
683 ULONG parentanodenr; /* anodenr of (parsed part of) notification object's path */
684 ULONG anodenr; /* anodenr of notification object itself (dirs only) */
685 UBYTE *namemem; /* memory used for 'unparsed' */
686 UBYTE *unparsed; /* (CSTR!) unparsed part of nr_FullName pathpart (intl uppercase) */
687 UBYTE *objectname; /* (DSTR!) name of object (without path intl uppercase) */
692 * Idlehandle.
694 struct idlehandle
696 struct idlehandle *next;
697 struct idlehandle *previous;
698 struct Task *task;
699 UWORD cleansignal; /* idle after read access */
700 UWORD dirtysignal; /* idle after write access */
703 /*****************************************************************************/
704 /* LRU macro functions */
705 /*****************************************************************************/
707 /* Cached blocks are in two lists. This gets the outer list (the lru chain) from
708 * the inner list
710 #define LRU_CHAIN(b) \
711 ((struct lru_cachedblock *)(((UBYTE *)(b))-offsetof(struct lru_cachedblock, cblk)))
712 #define LRU_CANODEBLOCK(blk) ((struct lru_canodeblock *)((ULONG *)blk - 2))
713 #define LRU_CDIRBLOCK(blk) ((struct lru_cdirblock *)((ULONG *)blk - 2))
714 #define LRU_NODE(blk) ((struct MinNode *)((ULONG *)blk - 2))
716 /* Make a block the most recently used one. The block
717 * should already be in the chain!
718 * Argument blk = struct cachedblock *
720 #define MakeLRU(blk) \
722 MinRemove(LRU_CHAIN(blk)); \
723 MinAddHead(&g->glob_lrudata.LRUqueue, LRU_CHAIN(blk)); \
726 /* Free a block from the LRU chain and add it to
727 * the pool
728 * Argument blk = struct cachedblock *
730 #define FreeLRU(blk) \
732 MinRemove(LRU_CHAIN(blk)); \
733 memset(blk, 0, SIZEOF_CACHEDBLOCK); \
734 MinAddHead(&g->glob_lrudata.LRUpool, LRU_CHAIN(blk)); \
738 * Hashing macros
740 #define ReHash(blk, list, mask) \
742 MinRemove(blk); \
743 MinAddHead(&list[(blk->blocknr/2)&mask], blk); \
746 #define Hash(blk, list, mask) \
747 MinAddHead(&list[(blk->blocknr/2)&mask], blk)
750 /*****************************************************************************/
751 /* other macro definitions */
752 /*****************************************************************************/
754 #define IsSoftLink(oi) ((IPTR)(oi).file.direntry>2 && ((oi).file.direntry->type==ST_SOFTLINK))
755 #define IsRealDir(oi) ((IPTR)(oi).file.direntry>2 && ((oi).file.direntry->type==ST_USERDIR))
756 #define IsDir(oi) ((IPTR)(oi).file.direntry>2 && ((oi).file.direntry->type)>0)
757 #define IsFile(oi) ((IPTR)(oi).file.direntry>2 && ((oi).file.direntry->type)<=0)
758 #define IsVolume(oi) ((oi).volume.root==0)
759 #if DELDIR
760 #define IsDelDir(oi) ((oi).deldir.special==SPECIAL_DELDIR)
761 #define IsDelFile(oi) ((oi).deldir.special==SPECIAL_DELFILE)
762 #endif /* DELDIR */
763 #if ROLLOVER
764 #define IsRollover(oi) ((IPTR)(oi).file.direntry>2 && ((oi).file.direntry->type==ST_ROLLOVERFILE))
765 #endif /* ROLLOVER */
766 #define ISCURRENTVOLUME(v) (g->currentvolume && \
767 dstricmp(g->currentvolume->rootblk->diskname, v) == 0)
768 #define IsSameOI(oi1, oi2) ((oi1.file.direntry == oi2.file.direntry) && \
769 (oi1.file.dirblock == oi2.file.dirblock))
771 // CHK(x) voorkomt indirectie van null pointer
772 // IsRoot(fi) checked of *oi bij de rootdir hoort
773 // IsRootA(fi) checked of oi bij de rootdir hoort
774 #define N(x) ((x)?(&(x)):NULL)
775 #define IsRoot(oi) (((oi)==NULL) || ((oi)->volume.root == 0))
776 #define IsRootA(oi) ((oi).volume.root == 0)
778 // voor VolumeRequest:
779 #define VR_URGENT 0
780 #define VR_PLEASE 1
782 /**********************************************************************/
783 /* Lists */
784 /**********************************************************************/
785 #define MinAddHead(list, node) AddHead((struct List *)(list), (struct Node *)(node))
786 #define MinAddTail(list, node) AddTail((struct List *)(list), (struct Node *)(node))
787 #define MinInsert(list, node, listnode) Insert((struct List *)list, (struct Node *)node, (struct Node *)listnode)
788 #define MinRemove(node) Remove((struct Node *)node)
789 #define HeadOf(list) ((void *)((list)->mlh_Head))
790 #define IsHead(node) (!((node)->prev->prev))
791 #define IsTail(node) (!((node)->next->next))
792 #define IsMinListEmpty(x) ( ((x)->mlh_TailPred) == (struct MinNode *)(x) )
794 /**********************************************************************/
795 /* File administration */
796 /**********************************************************************/
798 #if LARGE_FILE_SIZE
799 /* >4G file size support */
800 typedef QUAD FSIZE;
801 typedef QUAD SFSIZE;
802 /* Limit to useful sane size, not real max for now */
803 #define MAX_FILE_SIZE 0x7fffffffff
804 #else
805 typedef ULONG FSIZE;
806 typedef LONG SFSIZE;
807 #define MAX_FILE_SIZE 0xffffffff
808 #endif
810 /* FileInfo
812 ** Fileinfo wordt door FindFile opgeleverd. Bevat pointers die wijzen naar
813 ** gecachede directoryblokken. Deze blokken mogen dus alleen uit de cache
814 ** verwijderd worden als deze verwijzingen verwijderd zijn. Op 't ogenblik
815 ** is het verwijderen van fileinfo's uit in gebruik zijnde fileentries
816 ** niet toegestaan. Een fileinfo gevuld met {NULL, xxx} is een volumeinfo. Deze
817 ** wordt in locks naar de rootdir gebruikt.
818 ** Een *fileinfo van NULL verwijst naar de root van de current volume
820 struct fileinfo
822 struct direntry *direntry; // pointer wijst naar direntry binnen gecached dirblock
823 struct cdirblock *dirblock; // pointer naar gecached dirblock
826 struct volumeinfo
828 ULONG root; // 0 =>it's a volumeinfo; <>0 => it's a fileinfo
829 struct volumedata *volume;
832 #if DELDIR
833 struct deldirinfo
835 ULONG special; // 0 => volumeinfo; 1 => deldirinfo; 2 => delfile; >2 => fileinfo
836 struct volumedata *volume;
839 struct delfileinfo
841 ULONG special; // 2
842 ULONG slotnr; // het slotnr voor deze deldirentry
845 /* info id's: delfile, deldir and flushed reference */
846 #define SPECIAL_DELDIR 1
847 #define SPECIAL_DELFILE 2
848 #define SPECIAL_FLUSHED 3
849 #endif /* DELDIR */
851 union objectinfo
853 struct fileinfo file;
854 struct volumeinfo volume;
855 #if DELDIR
856 struct deldirinfo deldir;
857 struct delfileinfo delfile;
858 #endif
861 /**********************************************************************/
862 /* Fileentries/locks & volumes */
863 /**********************************************************************
865 ** Drie structuren met zelfde basis, maar verschillende lengte.
866 ** Allemaal gekoppeld via next; type geeft type entry aan.
867 ** CurrentAnode en AnodeOffset zijn eigenlijk redundant, want afleidbaar van 'offset'.
868 ** FileInfo 'info' moet ingevulde zijn; het betreffende directoryblock moet dus ge-
869 ** cached zijn.
870 ** Van 'lock' is fl_Key het directoryblocknr (redundant met info.dirblock->blocknr)
871 ** fl_Task, fl_Volume en fl_Access dienen ingevuld te zijn.
874 /* entrytype's
875 ** NB: ETF_VOLUME en ETF_LOCK zijn ALLEBIJ LOCKS!! TEST ON BOTH
877 #define ET_VOLUME 0x0004
878 #define ET_FILEENTRY 0x0008
879 #define ET_LOCK 0x000c
880 #define ETF_VOLUME 1
881 #define ETF_FILEENTRY 2
882 #define ETF_LOCK 3
883 #define ET_SHAREDREAD 0
884 #define ET_SHAREDWRITE 1
885 #define ET_EXCLREAD 2
886 #define ET_EXCLWRITE 3
888 #define IsVolumeEntry(e) ((e)->type.flags.type == ETF_VOLUME)
889 #define IsFileEntry(e) ((e)->type.flags.type == ETF_FILEENTRY)
890 #define IsLockEntry(e) ((e)->type.flags.type == ETF_LOCK)
892 #define IsVolumeLock(le) ((le)->type.flags.type == ETF_VOLUME)
894 #define SHAREDLOCK(t) ((t).flags.access <= 1)
896 // ANODENR voor fe's en le's; FIANODENR voor fileinfo's; NOT FOR VOLUMES!!
897 #define ANODENR(fe) ((fe)->anodenr)
898 #define FIANODENR(fi) ((fi)->direntry->anode)
900 union listtype
902 struct
904 unsigned pad:11;
905 unsigned dir:1; // 0 = file; 1 = dir or volume
906 unsigned type:2; // 0 = unknown; 3 = lock; 1 = volume; 2 = fileentry
907 unsigned access:2; // 0 = read shared; 2 = read excl; 1,3 = write shared, excl
908 } flags;
910 UWORD value;
913 typedef union listtype listtype;
915 /* Listentry
917 **- Alle locks op een disk zijn geketend vanuit volume->firstfe via 'next'. Het einde
918 ** van de keten is 0. Uitbreiden van de lijst gaat dmv ADDHEAD en ADDTAIL
919 **- [volume] verwijst terug naar de volume
920 **- [info] is {NULL, don't care} als root.
921 ** FileInfo van file/dir moet ingevulde zijn; het betreffende directoryblock moet dus ge-
922 ** cached zijn.
923 **- [self] verwijst naar begin structuur
924 **- [lock] bevat verwijzing naar DLT_VOLUME DosList entry. MOET 4-aligned zijn !!
925 **- [currentanode] en [anodeoffset] zijn eigenlijk redundant, want afleidbaar van [offset].
926 **- Van [lock] is fl_Key het directoryblocknr (redundant met info.dirblock->blocknr)
927 ** fl_Task, fl_Volume en fl_Access dienen ingevuld te zijn.
929 ** Possible locks: root of volume; readlock; writelock; dir; file; readfe; writefe
932 /* de algemene structure */
933 typedef struct listentry
935 struct listentry *next; /* for linkage */
936 struct listentry *prev;
937 struct FileLock lock; /* <4A> contains accesstype, dirblocknr (redundant) */
938 listtype type;
939 ULONG anodenr; /* object anodenr. Always valid. Used by ACTION_SLEEP */
940 ULONG diranodenr; /* anodenr of parent. Only valid during SLEEP_MODE. */
941 union objectinfo info; /* refers to dir */
942 ULONG dirblocknr; /* set when block flushed and info is set to NULL */
943 ULONG dirblockoffset;
944 struct volumedata *volume; /* pointer to volume */
945 } listentry_t;
947 /* de specifieke structuren */
948 typedef struct
950 listentry_t le;
952 struct anodechain *anodechain; // the cached anodechain of this file
953 struct anodechainnode *currnode; // anode behorende bij offset in file
954 ULONG anodeoffset; // blocknr binnen currentanode
955 ULONG blockoffset; // byteoffset binnen huidig block
956 FSIZE offset; // offset tov start of file
957 FSIZE originalsize; // size of file at time of opening
958 BOOL checknotify; // set if a notify is necessary at ACTION_END time > ALSO touch flag <
959 } fileentry_t;
961 typedef struct lockentry
963 listentry_t le;
965 ULONG nextanode; // anodenr of next entry (dir/vollock only)
966 struct fileinfo nextentry; // for examine
967 ULONG nextdirblocknr; // for flushed block only.. (dir/vollock only)
968 ULONG nextdirblockoffset;
969 } lockentry_t;
971 // *lock -> *fileentry
972 #define LOCKTOFILEENTRY(l) ((fileentry_t *)(((UBYTE*)l)-offsetof(fileentry_t, le.lock)))
974 // Maakt geen lock naar 'root of currentdir' aan!!
975 #define LockEntryFromLock(x) ((x) ? \
976 (lockentry_t *)((UBYTE*)BADDR(x)-offsetof(listentry_t, lock)) : 0)
978 #define ListEntryFromLock(x) ((x) ? \
979 (listentry_t *)((UBYTE*)BADDR(x)-offsetof(listentry_t, lock)) : 0)
981 #define MAXEXACTFIT 10
983 /**********************************************************************/
984 /* Disk administration */
985 /**********************************************************************/
987 #define InReservedArea(blocknr) \
988 (((blocknr) >= g->currentvolume->rootblk->firstreserved) && \
989 ((blocknr) <= g->currentvolume->rootblk->lastreserved))
991 #define LastReserved (g->currentvolume->rootblk->lastreserved)
992 #define FirstReserved (g->currentvolume->rootblk->firstreserved)
993 #define InPartition(blk) ((blk)>=g->firstblock && (blk)<=g->lastblock)
994 #define BLOCKSIZE (g->blocksize)
995 #define BLOCKSHIFT (g->blockshift)
996 #define DIRECTSIZE (g->directsize)
998 #ifndef ACTION_CHANGE_FILE_POSITION64
999 /* OS4 64-bit filesize packets */
1000 #define ACTION_CHANGE_FILE_POSITION64 8001
1001 #define ACTION_GET_FILE_POSITION64 8002
1002 #define ACTION_CHANGE_FILE_SIZE64 8003
1003 #define ACTION_GET_FILE_SIZE64 8004
1004 #endif
1006 #ifndef ACTION_SEEK64
1007 /* MOS 64-bit filesize packets */
1008 #define ACTION_SEEK64 26400
1009 #define ACTION_SET_FILE_SIZE64 26401
1010 #define ACTION_LOCK_RECORD64 26402
1011 #define ACTION_FREE_RECORD64 26403
1012 #define ACTION_QUERY_ATTR 26407
1013 #define ACTION_EXAMINE_OBJECT64 26408
1014 #define ACTION_EXAMINE_NEXT64 26409
1015 #define ACTION_EXAMINE_FH64 26410
1016 #endif
1018 struct ExAllDataEXT
1020 struct ExAllDataEXT *ed_Next;
1021 UBYTE *ed_Name;
1022 LONG ed_Type;
1023 ULONG ed_Size;
1024 ULONG ed_Prot;
1025 ULONG ed_Days;
1026 ULONG ed_Mins;
1027 ULONG ed_Ticks;
1028 UBYTE *ed_Comment;
1029 UWORD ed_OwnerUID;
1030 UWORD ed_OwnerGID;
1031 #if EXTENDED_PACKETS_MORPHOS
1032 QUAD ed_Size64;
1033 #endif
1036 #ifndef ED_SIZE64
1037 #define ED_SIZE64 (ED_OWNER + 1)
1038 #endif
1041 * TD64 support
1043 #ifndef TD_READ64
1044 #define TD_READ64 24
1045 #define TD_WRITE64 25
1046 #define TD_SEEK64 26
1047 #define TD_FORMAT64 27
1048 #endif
1051 /* NSD support */
1052 #ifndef NSCMD_DEVICEQUERY
1053 #define NSCMD_DEVICEQUERY 0x4000
1054 #define NSCMD_TD_READ64 0xc000
1055 #define NSCMD_TD_WRITE64 0xc001
1056 #define NSDEVTYPE_TRACKDISK 5
1057 struct NSDeviceQueryResult
1059 ULONG DevQueryFormat;
1060 ULONG SizeAvailable;
1061 UWORD DeviceType;
1062 UWORD DeviceSubType;
1063 UWORD *SupportedCommands;
1065 #endif
1067 #define ACCESS_DETECT (TD64 + NSD + SCSIDIRECT > 1)
1070 * Includes messages
1072 #include "messages.h"
1073 #endif