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
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
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
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
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
62 * Revision 1.9 1995/07/21 07:00:57 Michiel
63 * importing messages.h
66 * Revision 1.8 1995/07/11 09:24:38 Michiel
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
77 * Revision 1.5 1995/06/04 06:12:33 Michiel
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)
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
101 #ifndef DOS_DOSEXTENS_H
102 #include <dos/dosextens.h>
104 #ifndef DEVICES_TRACKDISK_H
105 #include <devices/trackdisk.h>
108 #include <proto/exec.h>
111 #include <proto/dos.h>
117 #ifndef LIBRARIES_MULTIUSER_H
118 #include <libraries/multiuser.h>
121 #ifndef DEVICES_SCSIDISK_H
122 #include <devices/scsidisk.h>
127 /****************************************************************************/
128 /* Useful macros to handle various compiler dependecies */
129 /****************************************************************************/
131 #if defined(__GNUC__)
132 #define __READONLY__ __attribute__((section(".rodata")))
134 #define __USED__ __attribute__((used))
143 /****************************************************************************/
144 /* For SAS/C use amiga.lib assembly memory pool routines */
145 /****************************************************************************/
147 void * __asm
AsmCreatePool(register __d0 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 *,
155 register __a6
struct ExecBase
*);
156 void __asm
AsmFreePooled(register __a0
void *,
157 register __a1
void *,
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 */
168 #if INCLUDE_VERSION < 44
169 typedef CONST
unsigned char *CONST_STRPTR
;
173 /****************************************************************************/
174 /* MorphOS specific global headers */
175 /****************************************************************************/
178 #include <clib/macros.h>
179 #define min(a,b) MIN(a,b)
180 #define max(a,b) MAX(a,b)
182 #define NewList(l) NEWLIST(l)
184 #define Insert(l,n,ln) INSERT(l,n,ln)
186 #define AddHead(l,n) ADDHEAD(l,n)
188 #define AddTail(l,n) ADDTAIL(l,n)
190 #define Remove(n) REMOVE(n)
192 #define RemHead(l) REMHEAD(l)
194 #define RemTail(l) REMTAIL(l)
195 #define memcpy(d,s,n) CopyMem(s,d,n)
198 /****************************************************************************/
199 /* AROS specific global headers */
200 /****************************************************************************/
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
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
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
232 /****************************************************************************/
233 /* muFS related defines */
234 /****************************************************************************/
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 /****************************************************************************/
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 */
281 BOOL set
; /* 0 -> read; 1 -> write */
286 #if defined(__GNUC__) || defined(__VBCC__)
291 /*****************************************************************************/
292 /* Allocation data */
293 /*****************************************************************************/
296 * The global allocation data
298 * the number of blocks really free can be found in rootblock->blocksfree
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
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.
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
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 /*****************************************************************************/
378 /*****************************************************************************/
381 * The global anode data
383 * Other used globaldata fields:
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
;
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 /*****************************************************************************/
422 /*****************************************************************************/
424 /* the LRU global data */
427 struct MinList LRUqueue
;
428 struct MinList LRUpool
;
430 struct lru_cachedblock
*LRUarray
;
431 UWORD reserved_blksize
;
435 /*****************************************************************************/
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!
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 */
455 ULONG blocknr
; /* blocknr of cached block; 0 = empty slot */
456 UBYTE dirty
; /* dirty flag (TRUE/FALSE) */
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
472 #define ACCESS_TD64 3
475 /* ALL globals are defined here */
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 */
506 struct diskcache dc
; /* cache to make '196 byte mode' faster */
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
*);
516 struct MinList volumes
; /* Volume list. Normally only one volume */
517 struct volumedata
*currentvolume
;
518 ULONG changecount
; /* diskchange counter. Should be initialized by NewVolume */
521 /* disktype: ID_PFS_DISK/NO_DISK_PRESENT/UNREADABLE_DISK
522 * (only valid if currentvolume==NULL)
526 /* state of currentvolume (ID_WRITE_PROTECTED/VALIDATED/VALIDATING) */
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
;
591 struct SignalSemaphore
*device_unit_lock_sema
;
592 LONG device_unit_lock_count
;
594 #if !defined(__MORPHOS__) || !defined(SYSTEM_PRIVATE)
595 struct IOStdReq
*resethandlerioreq
;
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 /*****************************************************************************/
642 /*****************************************************************************/
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. */
652 struct crootblockextension
*rblkextension
; /* extended rblk, NULL if disabled*/
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
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) */
696 struct idlehandle
*next
;
697 struct idlehandle
*previous
;
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
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
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)); \
740 #define ReHash(blk, list, mask) \
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)
760 #define IsDelDir(oi) ((oi).deldir.special==SPECIAL_DELDIR)
761 #define IsDelFile(oi) ((oi).deldir.special==SPECIAL_DELFILE)
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:
782 /**********************************************************************/
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 /**********************************************************************/
799 /* >4G file size support */
802 /* Limit to useful sane size, not real max for now */
803 #define MAX_FILE_SIZE 0x7fffffffff
807 #define MAX_FILE_SIZE 0xffffffff
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
822 struct direntry
*direntry
; // pointer wijst naar direntry binnen gecached dirblock
823 struct cdirblock
*dirblock
; // pointer naar gecached dirblock
828 ULONG root
; // 0 =>it's a volumeinfo; <>0 => it's a fileinfo
829 struct volumedata
*volume
;
835 ULONG special
; // 0 => volumeinfo; 1 => deldirinfo; 2 => delfile; >2 => fileinfo
836 struct volumedata
*volume
;
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
853 struct fileinfo file
;
854 struct volumeinfo volume
;
856 struct deldirinfo deldir
;
857 struct delfileinfo delfile
;
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-
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.
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
881 #define ETF_FILEENTRY 2
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)
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
913 typedef union listtype listtype
;
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-
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) */
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 */
947 /* de specifieke structuren */
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 <
961 typedef struct lockentry
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
;
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
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
1020 struct ExAllDataEXT
*ed_Next
;
1031 #if EXTENDED_PACKETS_MORPHOS
1037 #define ED_SIZE64 (ED_OWNER + 1)
1044 #define TD_READ64 24
1045 #define TD_WRITE64 25
1046 #define TD_SEEK64 26
1047 #define TD_FORMAT64 27
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
;
1062 UWORD DeviceSubType
;
1063 UWORD
*SupportedCommands
;
1067 #define ACCESS_DETECT (TD64 + NSD + SCSIDIRECT > 1)
1072 #include "messages.h"