This file forms part of PFS (Professional File System)
Copyright 1993-1995 Michiel Pelt and distributed by
Fourth Level Developments.


                            PFS disk structure
                            ------------------

This  document  describes  the blocks and structures used by PFS.  Only the
new  harddisk  version  will be described here.  For the floppy version you
can refer to previous releases.

*********************
* the bootblocks
*********************

The  first  two  blocks  are  the bootblocks, as required by AmigaDOS.  The
first  longword  of  the first bootblock contains the dostype:  PFS\1.  The
rest is empty.  So the first bootblock looks like this:

     ___________________
    |                   |
000 | disktype          |
    |___________________|
004 |                   |
    |                   |
    |         .         |
    |         .         |
200 |___________________|


********************
* the rootblock
********************

Directly  behind  the  bootblocks  you  can find the rootblock, on block 2.
This  is  the  most  important  block  of a PFS disk.  PFS keeps this block
cached at all times.  It looks like this:

     ___________________
    |                   |
000 | disktype          |   'PFS\1'
004 | options           |   currently 1
008 | reserved_1        |
    |___________________|
    |         |         |
00c | cday    | cminute |   creation date (DOS format)
010 | ctick   | prot    |   protection
    |_________|_________|
    |                   |   32 character diskname. Size of string followed
014 | diskname          |   by that number of characters
    |                   |
    |___________________|
    |                   |
034 | last reserved     |   first and last reserved block (blocknumbers)
038 | first reserved    |
03c | reserved free     |   number of reserved blocks free
    |___________________|
    |         |         |
040 | blksize | rblkclt |   reserved blocksize; rootblock cluster
    |_________|_________|
    |                   |
044 | blocks free       |   number of blocks free
048 | always free       |   number of blocks always kept free
04c | roving pointer    |   used for allocation
    |___________________|
050 |                   |
    | reserved          |
    |                   |
    |___________________|
060 |                   |
    | bitmap index      |   reference to bitmap index blocks
    |                   |
    |___________________|
074 |                   |
    | anode index       |   reference to anode index blocks
    |                   |
200 |___________________|


With  the disktype field PFS recognizes that the disk is a pfs disk.  It is
the same as what can be found in the bootblock.

Options is a 32 bit field with which pfs can be configured.  Currently only
bit 0 is used.  It indicates harddisk operation and must be set to 1, since
floppies are not yet supported.

All 'reserved' fields are not used and must be set to 0.

First   and   last   reserved  indicate  the  'reserved  area'.   All  disk
information,  like  directories,  allocation  data  etc  are stored in this
reserved  area.   The  rest  of  the disk is available for data.  Currently
firstreserved  always is 2, so the reserved area starts with the rootblock.
'Reserved   free'   indicates  the  number  of  reserved  blocks  that  are
unoccupied.

'Blksize'  indicates  the size of reserved blocks in bytes.  Currently this
is  always  1024  (1K),  independent  of  the actual blocksize.  The actual
blocksize  (as  specified in the mountlist) can be either 512 or 1024 byte.
So  if  blocks  are 512 byte, which is the normal case, each reserved block
takes  two  blocks  on  disk.   BTW:   the  before mentioned first and last
reserved  indicate real blocknumbers, not reserved block numbers.  However,
'reserved  free' does refer to reserved blocks.  It indicates the number of
reserved blocks that can be allocated before the reserved area is full.

Blocks  free indicates the number of free blocks.  It is equal to the total
number  of  blocks  on  the  disk - the number of reserved blocks - 2 - the
number  of blocks taken by data.  PFS always keeps a small part of the data
area free.  This is indicated by 'always free'.

The roving pointer is used for allocation.  If you change any bitmap blocks
it is wise to set this pointer to zero.  This will never hurt.

********************
* Block ID
********************

The following blocks each have a 2 byte block id field.  This indicates the
blocktype.  Currenly used IDs are:

DB -- dirblock
AB -- anodeblock
IB -- anode index block
BM -- bitmap block
MI -- bitmap index block

********************
* Bitmap blocks
********************

To  keep  track  of  which  blocks are occupied and which are not, pfs uses
bitmap blocks.  Such a block looks like this:

     ___________________
    |         |         |
000 | id      |    x    |
    |_________|_________|
    |                   |
004 | reserved          |
008 | sequence number   |
    |___________________|
00c |                   |
    | the bitmap        |
    |                   |
400 |___________________|


Each  block  has  room  for 253 longwords allocating 8096 blocks.  Each bit
represents  a  block and a bit is set if it is available, and clear when it
is taken.

There are two bitmaps, one for the reserved area and one for the data area.
For the data area several bitmap blocks are needed.  They are numbered with
the  sequence  number  field,  starting with 0.  The first bit of the first
bitmap block represents the first data block (the block directly behind the
last reserved block)

The  bitmap  for  the  reserved area is directly behind the rootblock.  The
rootblock  cluster field in the rootblock (rblkclt) indicates the number of
blocks  occupied  by  the rootblock together with the reserved bitmap.  The
reserved bitmap has the same header as the data bitmap, but has a different
size.   The  rootblock  cluster  is  chosen  such,  that it can contain the
rootblock  itself and the entire reserved bitmap, and it is rounded up to a
multiple of 1024 byte blocks.

The  first  bit  of the reserved bitmap represents the first reserved block
(usually 2).  Each bit represents a 1024 byte reserved block.


********************
* Index blocks
********************

PFS  refers to bitmap and anode blocks by using index blocks.  These blocks
look like this:

     ___________________
    |         |         |
000 | id      |    x    |
    |_________|_________|
    |                   |
004 | reserved          |
008 | sequence number   |
    |___________________|
00c |                   |
    | 253 indices       |
    |                   |
400 |___________________|



Each  block  contains  references to 253 anode or bitmap blocks.  For large
disks  several  index  blocks  will  be needed.  They are numbered with the
sequence number, starting with 0.

There is a maximum of 5 bitmap index blocks and 99 anode index blocks.  The
rootblock contains the pointers to these blocks.

An  anode or bitmap block of a certain sequence number doesn't exist if the
corresponding  field  in the index is zero.  Holes in the index are allowed
(e.g.  it is possible for anode block 5 to exist, while 4 doesn't).

********************
* Anode blocks
********************

Files  and  directories  take  space on the disk.  PFS keeps track of which
objects takes which blocks by means of so called anodes.  Anodes are stored
in anode blocks, which look like this:

     ___________________
    |         |         |
000 | id      |    x    |
    |_________|_________|
    |                   |
004 | reserved          |
    |___________________|
    |                   |
008 | sequence number   |
    |___________________|
    |                   |
00c | reserved          |
    |___________________|
010 |                   |
    | 84 anodes         |
    |                   |
400 |___________________|


The anodes are numbered starting with 0.  The first 84 are in anodeblock 0,
the  next  84  in  anodeblock  1  etc.   Each object (file or directory) is
identified by such an anode number.

An anode looks like this:

     ___________________
    |                   |
000 | clustersize       |
004 | blocknr           |
008 | next              |
    |___________________|

The clustersize indicates how many blocks are allocated by this anode.  The
blocknr  is  the first block allocated.  So an unfragmented file can always
be  allocated  by  a  single  anode.  A fragmented file, however, needs one
anode  for  each  fragment.  Therefore is the next field.  It indicates the
anodenr of the next fragment.  If this is the last fragment, the next field
will be zero.

The clustersize and blocknr in an anode always refer to real block numbers,
even if the blocks are in the reserved area.

If  all  fields  of  the  anode  are zero, it is considered free and can be
reused.

It  is  possible  to  associate an anode with a file without allocation any
blocks.   This  can be done by setting the clustersize and next fields to 0
and the blocknr field to -1.

The first six anodes have a special meaning:

anode   name                use
----------------------------------------------
 0      ANODE_EOF           should always be 0
 1                          not used, set to 0
 2                          not used, set to 0
 3                          not used, set to 0
 4      ANODE_BADBLOCKS     Bad block list. Not used by pfs. Repair
                            programs can chain bad blocks to this
                            anode
 5      ANODE_ROOTDIR       The anode of the root directory. You can find 
                            the root directory by looking at this anode

All anodes from 6 and higher are used for directory and file allocation.


********************
* dirblocks
********************

Directories  have  an  anodenr,  just like files.  Each anode points to one
directory  block  of  1024  byte (so, with 512 byte blocks, the clustersize
field  of  an anode belonging to a directory is always 2).  If 1024 byte is
not enough for the directory, a new block with a new anode is allocated and
chained  to the first.  To anodes belonging to the same directory are never
joined to form one (by increasing the clustersize).

A dirblock looks like this.

     ___________________
    |         |         |
000 | id      |    x    |
    |_________|_________|
004 |                   |
    | reserved          |
    |___________________|
    |                   |
00c | anodenr           |
010 | parent            |
    |___________________|
014 |                   |
    | directory entries |
400 |___________________|


The  anodenr  refers to the anode belonging to the directory, not the anode
belonging  to  the  block.   So  it  always points to the head of the anode
chain, and is the same for all blocks of the same directory.

The  parent is the anodenr of the parent of this directory, or 0 if this is
the rootdirectory (which doesn't have a parent).


A directory entry looks like this:

         ___________________
        |         |         |
000     | next    | type    |
        |_________|_________|___________________
        |                                       |
002     | anode number                          |
006     | size                                  |
        |_______________________________________|
        |                   |
00a     | creation day      |
00c     | creation minute   |
00e     | creation tick     |
        |___________________|
        |         |         |
010     | prot    | nlength |
        |_________|_________|
        |                   |
012     | name              |
        |                   |
        |___________________|
012 +   |         |
nlenght | flenght |
        |_________|_________
013 +   |                   |
nlenght | filenote          |
        |                   |
        |___________________|


The next field indicates the length of this directory entry in bytes.  This
must always be even.

The  type is the type of direntry, just like FFS:  ST_FILE, ST_USERDIR etc.
See include file <dos/dosextens.h> for details.

The  anode number is the head of the anode chain for this object.  The size
is  the  filesize  in  bytes.  The number of blocks in the anode chain must
correspond to the number of blocks needed to store 'size' bytes.

The  creation day, minute and tick is the DOS timestamp of the object.  The
protection are the lower 8 file protection bits, like FFS.

The  name  and  the  filenote  are  pascal strings (length followed by that
number  of  characters).  They are placed directly behind each other and are
byte aligned.  If the file has no filenote, flength will be zero.

Each directory is padded if that is needed to word align the next directory
entry.

The  end of the directory block is indicated by appending a zero at the end
of  the  last  entry.   The  directory ends with the last entry in the last
block, where the blocks are chained by anodes.


