Home MagiCMagiC Additional programs for MagiCAdditional programs for MagiC MagiC's XFS-conceptMagiC's XFS-concept

11.20 MagiC's DFS-concept

MagiC, just as MultiTOS, enables the incorporation of alternative filesystems (so-called XFSs). Firmly integrated in MagiC is only a single XFS, the DOS_XFS. On top of this XFS sit in turn subdrivers, the so-called DFS (DOS filesystem), of which two are integrated in MagiC, namely the FAT filesystem and the U filesystem (that for the drive U:).

A DOS filesystem (DFS) is called by DOS_XFS. This includes only the file functions, while the management of directories is essentially taken over by the DOS_XFS. Further DFSs can be installed. The effort for a DFS is appreciably lower than for an XFS as many functions are performed already by the DOS_XFS. The vital prerequisite is a DOS- conforming directory structure (with 32-bit entries and filenames in the 8+3 format). This section deals with the items:

See also: MagiC's XFS-concept

11.20.1 The make-up of a DFS

Since the implementation of a DFS can only be performed in Assembler, this description is specified in Assembler syntax:

dfs_name:      DS.B      8    /* Subname of the DOS filesystems */
dfs_next:      DS.L      1    /* Next driver                    */
dfs_init:      DS.L      1    /* Initialization                 */
dfs_sync:      DS.L      1    /* Synchronises the filesystem    */
dfs_drv_open:  DS.L      1    /* New drive                      */
dfs_drv_close: DS.L      1    /* Release drive                  */
dfs_dfree:     DS.L      1    /* For Dfree                      */
dfs_sfirst:    DS.L      1    /* For Fsfirst                    */
dfs_snext:     DS.L      1    /* For Fsnext                     */
dfs_ext_fd:    DS.L      1    /* Extends a directory            */
dfs_fcreate:   DS.L      1    /* Creates a directory or file    */
dfs_fxattr:    DS.L      1    /* For Fxattr                     */
dfs_dir2index: DS.L      1    /* For Dreaddir                   */
dfs_readlink:  DS.L      1    /* For Freadlink                  */
dfs_dir2FD:    DS.L      1    /* for Fopen                      */
dfs_fdelete:   DS.L      1    /* For Fdelete and Ddelete        */
dfs_pathconf:  DS.L      1    /* For Dpathconf                  */

See also: Make-up of an XFS   MagiC

11.20.1.1 dfs_dfree

Name: »dfs_dfree«
 
Parameters:
 

a0 = FD *
a1 = long df[4]
-> d0 = long errcode
Description: For Dfree it is generally sufficient to obtain from the DD the DMD that belongs to it and to specify the free space on the whole drive.
 
Group: Make-up of a DFS
 
See also: MagiC's DFS-concept
 

11.20.1.2 dfs_dir2FD

Name: »dfs_dir2FD« - Initialize a prototype FD.
 
Parameters:
 

a0 = FD *dd
a1 = DIR *dir
-> d0 = long errcode
If necessary    
a0 = LINK *l
Description: dfs_dir2FD initializes a prototype-FD, namely the fields:
 
and if necessary:
 
Other data of the FD may also be changed if necessary.
 
Group: Make-up of a DFS
 
See also: MagiC's DFS-concept
 

11.20.1.3 dfs_dir2index

Name: »dfs_dir2index«
 
Parameters:
 

a0 = FD *dd
a1 = DIR *dir
-> d0 = long index or errcode
Description: dfs_dir2index simply returns an index (32-bit) to a DIR entry. For this the FAT_DFS takes the de-Intelled starting cluster. dd is the directory that contains the file.
 
Group: Make-up of a DFS
 
See also: MagiC's DFS-concept
 

11.20.1.4 dfs_drv_close

Name: »dfs_drv_close«
 
Parameters:
 

d0 = int mode
a0 = DMD *d
-> d0 = long errcode
Description: The dfs_drv_close function too fulfills two tasks, depending on mode:
 
1. mode == 0:
The DOS_XFS asks the DFS whether the drive may be closed. If this is not permitted, then EACCDN must be returned, else E_OK (required e.g. for Dlock). Opened files were already recognized be the kernel and DOS_XFS, i.e. in that case dfs_drv_close will not be called at all.
 
For this reason, generally no altered sector buffers may exist, even those that are currently being read or written (this is always done via files!). In this case it suffices, therefore, always to return an E_OK. Things become more problematic if one uses a write-back cache. With this it may happen that no file is open any more, but a buffer still holds data that have to be written back. The kernel makes a sync call (xfs_sync, which is passed on to dfs_sync) before the inquiry is made; thus no altered buffers ought to exist any more - if they do, then for safety's sake the DFS should return EACCON.
 
2. mode == 1:
The DOS_XFS forces the closing of the drive, the DFS must return E_OK. No caches may be written back, since the drive is already invalid (after a media change has been reported already).
 
With Dlock, dfs_drv_close is first called in mode 0, then - if no error has occurred - with mode 1. This strategy will be carried out also even if at some time a mechanism is built in that monitors the eject button of interchangeable-media drives or CD-ROMs, and bars ejection if necessary.
 
Group: Make-up of a DFS
 
See also: MagiC's DFS-concept
 

11.20.1.5 dfs_drv_open

Name: »dfs_drv_open«
 
Parameters:
 

a0 = DMD *d
-> d0 = long errcode
Description: MagiC supports exactly 26 simultaneously active filesystems that are assigned letters 'A'..'Z'. dfs_drv_open has two tasks:
 
  1. At the first access to a drive (say D:), the kernel creates a DMD (drive medium descriptor) and 'offers' this to the XFSs. The DOS_XFS offers this again to all DFS drivers in turn. The entry d_dfs is still a NULL-pointer, d_drive is initialized (between 0 and 25, corresponding to 'A'..'Z'). The DFS drivers now attempt to recognize 'their' filesystem on the drive. If this succeeds, then d_dfs and d_root have to be initialized, in which case the return value is then E_OK. Else EDRIVE is reported, and the DOS_XFS tries the next DFS.
     

  2. At a repeated access d_dfs is already initialized, and the DFS has the opportunity to test for a medium change. If everything is in order, E_OK has to be returned. Else the disk medium change routine of the kernel has to be called and E_CHNG returned. For this one obtains the pointer to the medium change routine of the kernel with Dcntl.
     

Group: Make-up of a DFS
 
See also: MagiC's DFS-concept
 

11.20.1.6 dfs_ext_fd

Name: »dfs_ext_fd«
 
Parameters:
 

a0 = FD *fd
-> d0 = long errcode
Description: dfs_ext_fd is used when a file is to be created but the directory is already full. It is also used during the creation of a folder (Dcreate).
 
fd is a prototype FD, which is already opened in the exclusive mode. The file has to be extended and the new space initialized with NULLs.
 
Group: Make-up of a DFS
 
See also: MagiC's DFS-concept
 

11.20.1.7 dfs_fcreate

Name: »dfs_fcreate«
 
Parameters:
 

a0 = FD *dd
a1 = DIR *dir
d0 = int cmd
d1 = long arg
-> d0 = long errcode
Description: dfs_fcreate is used for Fcreate, Dcreate and Dcntl. The DOS_XFS has already found free space in the directory dd, and - at first in memory - created the new directory entry dir. Those parts of the DIR not used in every DFS (the cluster number too) are already initialized with NULLs. The DFS has the opportunity here still to make corrections and to initialize the reserved DIR areas according to the file-type before the DOS_XFS writes the whole entry into the directory.
 
When the call Dcntl or Fsymlink occurs, d0 and a0 contain the relevant parameters, otherwise d0 == 0. If d0 == SYMLINK_CREATE, a symbolic link must (or at least can, if possible) be created.
 
Group: Make-up of a DFS
 
See also: MagiC's DFS-concept
 

11.20.1.8 dfs_fdelete

Name: »dfs_fdelete«
 
Parameters:
 

a0 = FD *dd
a1 = DIR *dir
d0 = long dirpos
-> d0 = long errcode
Description: The file with the directory entry dir in the directory FD is to be deleted. dfs_fdelete performs the actual deletion of the file; the deletion of the directory entry and access checks are performed by the DOS_XFS.
 
Group: Make-up of a DFS
 
See also: MagiC's DFS-concept
 

11.20.1.9 dfs_fxattr

Name: »dfs_fxattr«
 
Parameters:
 

a0 = FD *dd
a1 = DIR *dir oder NULL
d0 = int mode
d1 = XATTR *xattr
-> d0 = long errcode
If necessary:    
a0 = LINK *l
Description: dfs_fxattr is required for Fxattr. The DOS_XFS has already entered all the information, which is identical for all DFSs, into the XATTR. xattr_blksize as well as xattr_nblocks both still have to be initialized by the DFS, xattr_size can be adapted for special files, say. xattr_index has been initialized by the DOS_XFS, with dir_stcl converted to the Motorola format. In many cases it will be necessary to perform a correction here, and to pass a pointer to a driver or a global data structure, for instance.
 
With mode d0 == 0 (i.e. follow symbolic links) the DFS must react appropriately and in the case of a link it has to return in d0 ELINK and in a0 the link. If dir == NULL, then the DOS_XFS has not located a directory entry but an FD (e.g. the root, or an open file).
 
Group: Make-up of a DFS
 
See also: MagiC's DFS-concept
 

11.20.1.10 dfs_init

Name: »dfs_init«
 
Parameters:
 
Description: Reserved. In case of MagiC-internal XFSs, dfs_init contains their initialization. It is not used with loaded-in XFSs.
 
Group: Make-up of a DFS
 
See also: MagiC's DFS-concept
 

11.20.1.11 dfs_name

Name: »dfs_name«
 
Parameters:
 
Description: The name is up till now just a comment; perhaps in the future it may offer the possibility of ascertaining which drivers are installed and what, say, the driver responsible for drive A: is called (i.e. what sort of filesystem the floppy disk contains).
 
The name of the integrated XFS is 'DOS_XFS ' (extended to 8 characters with spaces).
 
Group: Make-up of a DFS
 
See also: MagiC's DFS-concept
 

11.20.1.12 dfs_next

Name: »dfs_next«
 
Parameters:
 
Description: dfs_next is simply a chaining pointer to the next driver. A new driver is always incorporated at the front, so always has the highest priority. This makes it possible to load a driver in place of the integrated DOS driver, for instance.
 
Group: Make-up of a DFS
 
See also: MagiC's DFS-concept
 

11.20.1.13 dfs_pathconf

Name: »dfs_pathconf«
 
Parameters:
 

a0 = FD *dd
d0 = int which
-> d0 = long val or error-code
Description: dfs_pathconf inquires about various restrictions that apply for a given path dd. Most values for which have been set by the DOS_XFS already, so only the following values occur:
 

DP_IOPEN (0) Maximum number of simultaneously open files
DP_ATOMIC (4) Internal block size
DP_MODEATTR (7) Permitted file-types (from 21.05.95)
Group: Make-up of a DFS
 
See also: MagiC's DFS-concept
 

11.20.1.14 dfs_readlink

Name: »dfs_readlink«
 
Parameters:
 

a0 = FD *dd
a1 = DIR *dir
-> d0 = long errcode
If necessary:    
a0 = LINK *l
Description: dfs_readlink is used for Freadlink. d0 is either EACCDN if dir is not a symlink, or another error-code. If no error has arisen, a0 must return the link and d0 has to have the value ELINK.
 
Group: Make-up of a DFS
 
See also: MagiC's DFS-concept
 

11.20.1.15 dfs_sfirst

Name: »dfs_sfirst«
 
Parameters:
 

a0 = FD * d
a1 = DIR *dir
d0 = long pos
d1 = DTA *dta
-> d0 = long errcode
If necessary:    
a0 = LINK *l
Description: The DOS_XFS has already accessed the file. The DFS only needs to initialize the reserved entries dta_usr1 and dta_usr2 for the next Fsnext, so that this position can be found again.
 
File descriptors (FDs) cannot be used in dta_usrm as releasing them during a 'garbage collection' cannot be avoided. Simply blocking the FDs is not possible either as one cannot predict the end of the Fsfirst/Fsnext operation. An already failed search can be marked by deleting dta_sname, for instance.
 
pos already points to the next entry, i.e. 32 bytes after dir. For symbolic links the DFS has to react appropriately, pass ELINK in d0 and in a0 a pointer to the link. A link starts with a WORD (16-bit) for the length of the path, followed by the path itself.
 
Warning: The length must include the terminating NULL-byte and also be even. The link must lie at an even memory address.
 
The buffer for the link may be static or volatile as the kernel immediately copies the data elsewhere, with no possibility of a context change happening inbetween.
 
Group: Make-up of a DFS
 
See also: MagiC's DFS-concept
 

11.20.1.16 dfs_snext

Name: »dfs_snext«
 
Parameters:
 

a0 = DTA *dta
a1 = DMD *dmd
-> d0 = long errcode
If necessary:    
a0 = LINK *l
Description: The next matching file will be looked for, based on the data that dfs_sfirst has stored in the reserved area of the DTA. For this one can fall back on the functions of the DOS_XFS that can be obtained with Dcntl:
 
_dir_srch Searches through a directory with FD
reopen_FD Opens an FD
close_DD Closes an FD
filename_match Compares filenames
conv_path_elem Coverts filenames
init_DTA Copies data from DIR to the DTA
Group: Make-up of a DFS
 
See also: MagiC's DFS-concept
 

11.20.1.17 dfs_sync

Name: »dfs_sync«
 
Parameters:
 

a0 = DMD *d
-> d0 = long errcode
Description: The kernel has notified DOS_XFS that all buffers have been written back on drive d. A pointer to a DMD (drive medium descriptor) is passed in register a0. The DOS_XFS passes this call on directly to the DFS.
 
The return value will be an error-code. If the DFS does not manage the buffer (e.g. a RAMdisk), then a 0 has to be returned.
 
Group: Make-up of a DFS
 
See also: MagiC's DFS-concept
 

11.20.2 Data structures for a DFS

When working with a DFS the following data structures are important:

See also: XFS structures

11.20.2.1 The directory entry (DIR)

The following fields are identical for every DFS:

dir_name:  DS.B   11    /* 0x00: Filename                            */
dir_attr:  DS.B    1    /* 0x0b: Attribute                           */
dir_usr1:  DS.W    1    /* 0x0c: For free user assignment            */
dir_usr2:  DS.L    1    /* 0x0e: For free user assignment            */
dir_usr3:  DS.L    1    /* 0x12: For free user assignment            */
dir_time:  DS.W    1    /* 0x16: Time of last change (Intel format)  */
dir_date:  DS.W    1    /* 0x18: Date of last change (Intel format)  */
dir_stcl:  DS.W    1    /* 0x1a: First cluster, or other info        */
dir_flen:  DS.L    1    /* 0x1c: File length (Intel format)          */

Note: Instead of the cluster, other statements are possible as well. However, DOS_XFS treats the entry as a cluster specification at first (for xattr.index and fd_stcl as well as the creation of the entries '.' and '..' for Dcreate). In the case of Fxattr the statements of the DFS can be overwritten with other data.

See also: MagiC's DFS-concept

11.20.2.2 The device driver (MX_DDEV)

The sub-device driver (MX_DDEV) is inserted into the file descriptor by the DFS function dfs_dir2FD at the opening of a file and called up by the DOS_XFS. The MX_DDEV device driver has to make the following functions available:

typedef struct _mx_ddev
{
        LONG cdecl (*ddev_open)(struct _mx_dosfd *f);
        LONG cdecl (*ddev_close)();
        LONG cdecl (*ddev_read)();
        LONG cdecl (*ddev_write)();
        LONG cdecl (*ddev_stat)();
        LONG cdecl (*ddev_seek)();
        LONG cdecl (*ddev_datime)();
        LONG cdecl (*ddev_ioctl)();
        LONG cdecl (*ddev_delete)();
        LONG cdecl (*ddev_getc)();
        LONG cdecl (*ddev_getline)();
        LONG cdecl (*ddev_putc)();
} MX_DDEV;

See also: MagiC's DFS-concept   MagiC's XFS-concept

11.20.2.2.1 ddev_open
Name: »ddev_open«
 
Parameters:
 

a0 = FD *file
-> d0 = long errcode
Description: The file is opened, the FD is already initialized. In open-mode (fd_mode), bit O_TRUNC has to be evaluated. If appropriate an error-code has been returned, for devices O_TRUNC can be confidently ignored.
 
The field fd_fpos is already initialized to 0L. Should this not suffice (say if the FAT_DFS always memorizes the current cluster), then the appropriate fields of the user area of the FD are to be initialized or other fields of the FD adapted. ddev_open is called both on the first opening of a file (after dfs_dir2FD) as well as on duplication of a file descriptor (say if several programs access a file or a directory simultaneously). The compatibility of the open-modes (perhaps a shared read) is guaranteed by the kernel. The device driver can, for instance, modify the open-mode in such a way that the FD is always opened as 'exclusive', or arrange with the bit OM_NOCHECK that it wants to oversee the open-mode itself. If ddev_open for the prototype FD is called, then fd->fd_multi1 == fd.
 
If ddev_open returns an error-code, then the FD is simply released again by the DOS-XFS.
 
Group: DOS device driver
 
See also:
 
11.20.2.2.2 ddev_close

The file is closed. The handling of fd_refcnt is taken over by the DOS_XFS. The MX_DDEV driver here only needs to write back any buffers that may exist.

Parameters:

a0 = FD *file,
-> d0 = long errcode
11.20.2.2.3 ddev_read

See dev_read.

Parameters:

a0 = FD *file
d0 = long count
a1 = char *buffer
-> d0 = long amount
11.20.2.2.4 ddev_write

See dev_write. The MX_DDEV does not have to bother with the updating of the directory or the date of last access.

Parameters:

a0 = FD *file
d0 = long count
a1 = char *buffer
-> d0 = long amount
11.20.2.2.5 ddev_stat

See dev_stat.

Parameters:

a0 = FD *file
a1 = MAGX_UNSEL *unselect oder NULL
d0 = int rwflag
d1 = long apcode
-> d0 = long status
11.20.2.2.6 ddev_seek

See dev_seek.

Parameters:

a0 = FD *file
d0 = long where
d1 = int mode
-> d0 = long position
11.20.2.2.7 ddev_datime

See dev_datime. The MX_DDEV can simply insert a NULL-pointer here, then the DOS_XFS performs the standard procedure. The DOS_XFS converts Fcntl(FUTIME, ...) to Fdatime.

Parameters:

a0 = FD *file
a1 = int d[2]
d0 = int setflag
-> d0 = long errcode
11.20.2.2.8 ddev_ioctl

See dev_ioctl. There should be support for the functions FTRUNCATE, FIONREAD and FIONWRITE at least. DOS_XFS converts Fcntl(FUTIME, ...) to Fdatime and with that to ddev_datime, i.e. FUTIME does not have to be supported directly by ddev_ioctl.

Parameters:

a0 = FD *file
d0 = int cmd
a1 = void *buf
-> d0 = long errcode
11.20.2.2.9 ddev_delete

This function is called only by the U_DFS, i.e. the integrated DFS file system for drive U:. So if one installs one's own device driver, this is the time to release its memory and so retire from the system.

Parameters:

a0 = FD *directory
a1 = DIR *dir
-> d0 = long errcode
11.20.2.2.10 ddev_getc

See dev_getc. The MX_DDEV can simply insert a NULL-pointer here, then the DOS_XFS performs the standard procedure, i.e. calls ddev_read.

Parameters:

a0 = FD *file
d0 = int mode
-> d0 = unsigned long c
11.20.2.2.11 ddev_getline

See dev_getline. The MX_DDEV can simply insert a NULL-pointer here, then the DOS_XFS performs the standard procedure, i.e. calls ddev_read.

Parameters:

a0 = FD *file
a1 = char *buf
d1 = long size
d0 = int mode
-> d0 = long amount
11.20.2.2.12 ddev_putc

See dev_putc. The MX_DDEV can simply insert a NULL-pointer here, then the DOS_XFS performs the standard procedure, i.e. calls ddev_write.

Parameters:

a0 = FD *file
d0 = int mode
d1 = long value
-> d0 = unsigned long count

11.20.2.3 The Disk Transfer Area (DTA) for DFSs

The DTA is used by the old DOS functions Fsfirst and Fsnext, whose clumsy conception by the MSDOS originators still weighs down the system like a curse. The partitioning into res1/res2 has historical reasons, to make the structure at least in DOS_XFS as compatible as possible to old TOSs. For the DOS_XFS and with that for all DFSs the structure looks as follows:

dta_sname:  DS.B    12       /* 0x00: Search name (from Fsfirst)   */
dta_usr1 :  DS.L     1       /* 0x0c: For free user assignment     */
dta_usr2 :  DS.L     1       /* 0x10: For free user assignment     */
dta_drive:  DS.B     1       /* 0x14: Logical drive (0..25)        */
dta_attr :  DS.B     1       /* 0x15: Found attribute              */
dta_time :  DS.W     1       /* 0x16: Found time                   */
dta_date :  DS.W     1       /* 0x18: Found date                   */
dta_len  :  DS.L     1       /* 0x1a: Found length                 */
dta_name :  DS.B    14       /* 0x1e: Found filename               */

Note: Here there are two LONGwords for free assignment by the user. dta_sname contains the search name already in the current format. In dta_usr1 and dta_usr2 one must enter the current position of the search, so that a following Fsnext continues the search at the correct position.

See also: MagiC's DFS-concept

11.20.3 Installation of a DFS

A DFS is simply a program that installs the driver and then terminates itself as resident. The installation takes place with:
dosfunctions = Dcntl(DFS_INSTDFS, "U:\\", &myxfs);
the path "U:\\" is important, because the Dcntl call is performed not by the MagiC kernel, but by the DOS-XFS. The return value will be a pointer to important XFS functions, or an error-code.

The DOS_XFS functions can also be inquired for independent of the installation of a DFS by using:
dosfunctions = Dcntl(DFS_GETINFO, "U:\\", NULL);
with kernel = Dcntl (KER_GETINFO, NULL, NULL) one obtains the kernel functions.

The deinstallation of a DFS is not provided for.


Home MagiCMagiC Additional programs for MagiCAdditional programs for MagiC MagiC's XFS-conceptMagiC's XFS-concept