0001 .. SPDX-License-Identifier: GPL-2.0
0002
0003 ===================
0004 The QNX6 Filesystem
0005 ===================
0006
0007 The qnx6fs is used by newer QNX operating system versions. (e.g. Neutrino)
0008 It got introduced in QNX 6.4.0 and is used default since 6.4.1.
0009
0010 Option
0011 ======
0012
0013 mmi_fs Mount filesystem as used for example by Audi MMI 3G system
0014
0015 Specification
0016 =============
0017
0018 qnx6fs shares many properties with traditional Unix filesystems. It has the
0019 concepts of blocks, inodes and directories.
0020
0021 On QNX it is possible to create little endian and big endian qnx6 filesystems.
0022 This feature makes it possible to create and use a different endianness fs
0023 for the target (QNX is used on quite a range of embedded systems) platform
0024 running on a different endianness.
0025
0026 The Linux driver handles endianness transparently. (LE and BE)
0027
0028 Blocks
0029 ------
0030
0031 The space in the device or file is split up into blocks. These are a fixed
0032 size of 512, 1024, 2048 or 4096, which is decided when the filesystem is
0033 created.
0034
0035 Blockpointers are 32bit, so the maximum space that can be addressed is
0036 2^32 * 4096 bytes or 16TB
0037
0038 The superblocks
0039 ---------------
0040
0041 The superblock contains all global information about the filesystem.
0042 Each qnx6fs got two superblocks, each one having a 64bit serial number.
0043 That serial number is used to identify the "active" superblock.
0044 In write mode with reach new snapshot (after each synchronous write), the
0045 serial of the new master superblock is increased (old superblock serial + 1)
0046
0047 So basically the snapshot functionality is realized by an atomic final
0048 update of the serial number. Before updating that serial, all modifications
0049 are done by copying all modified blocks during that specific write request
0050 (or period) and building up a new (stable) filesystem structure under the
0051 inactive superblock.
0052
0053 Each superblock holds a set of root inodes for the different filesystem
0054 parts. (Inode, Bitmap and Longfilenames)
0055 Each of these root nodes holds information like total size of the stored
0056 data and the addressing levels in that specific tree.
0057 If the level value is 0, up to 16 direct blocks can be addressed by each
0058 node.
0059
0060 Level 1 adds an additional indirect addressing level where each indirect
0061 addressing block holds up to blocksize / 4 bytes pointers to data blocks.
0062 Level 2 adds an additional indirect addressing block level (so, already up
0063 to 16 * 256 * 256 = 1048576 blocks that can be addressed by such a tree).
0064
0065 Unused block pointers are always set to ~0 - regardless of root node,
0066 indirect addressing blocks or inodes.
0067
0068 Data leaves are always on the lowest level. So no data is stored on upper
0069 tree levels.
0070
0071 The first Superblock is located at 0x2000. (0x2000 is the bootblock size)
0072 The Audi MMI 3G first superblock directly starts at byte 0.
0073
0074 Second superblock position can either be calculated from the superblock
0075 information (total number of filesystem blocks) or by taking the highest
0076 device address, zeroing the last 3 bytes and then subtracting 0x1000 from
0077 that address.
0078
0079 0x1000 is the size reserved for each superblock - regardless of the
0080 blocksize of the filesystem.
0081
0082 Inodes
0083 ------
0084
0085 Each object in the filesystem is represented by an inode. (index node)
0086 The inode structure contains pointers to the filesystem blocks which contain
0087 the data held in the object and all of the metadata about an object except
0088 its longname. (filenames longer than 27 characters)
0089 The metadata about an object includes the permissions, owner, group, flags,
0090 size, number of blocks used, access time, change time and modification time.
0091
0092 Object mode field is POSIX format. (which makes things easier)
0093
0094 There are also pointers to the first 16 blocks, if the object data can be
0095 addressed with 16 direct blocks.
0096
0097 For more than 16 blocks an indirect addressing in form of another tree is
0098 used. (scheme is the same as the one used for the superblock root nodes)
0099
0100 The filesize is stored 64bit. Inode counting starts with 1. (while long
0101 filename inodes start with 0)
0102
0103 Directories
0104 -----------
0105
0106 A directory is a filesystem object and has an inode just like a file.
0107 It is a specially formatted file containing records which associate each
0108 name with an inode number.
0109
0110 '.' inode number points to the directory inode
0111
0112 '..' inode number points to the parent directory inode
0113
0114 Eeach filename record additionally got a filename length field.
0115
0116 One special case are long filenames or subdirectory names.
0117
0118 These got set a filename length field of 0xff in the corresponding directory
0119 record plus the longfile inode number also stored in that record.
0120
0121 With that longfilename inode number, the longfilename tree can be walked
0122 starting with the superblock longfilename root node pointers.
0123
0124 Special files
0125 -------------
0126
0127 Symbolic links are also filesystem objects with inodes. They got a specific
0128 bit in the inode mode field identifying them as symbolic link.
0129
0130 The directory entry file inode pointer points to the target file inode.
0131
0132 Hard links got an inode, a directory entry, but a specific mode bit set,
0133 no block pointers and the directory file record pointing to the target file
0134 inode.
0135
0136 Character and block special devices do not exist in QNX as those files
0137 are handled by the QNX kernel/drivers and created in /dev independent of the
0138 underlaying filesystem.
0139
0140 Long filenames
0141 --------------
0142
0143 Long filenames are stored in a separate addressing tree. The staring point
0144 is the longfilename root node in the active superblock.
0145
0146 Each data block (tree leaves) holds one long filename. That filename is
0147 limited to 510 bytes. The first two starting bytes are used as length field
0148 for the actual filename.
0149
0150 If that structure shall fit for all allowed blocksizes, it is clear why there
0151 is a limit of 510 bytes for the actual filename stored.
0152
0153 Bitmap
0154 ------
0155
0156 The qnx6fs filesystem allocation bitmap is stored in a tree under bitmap
0157 root node in the superblock and each bit in the bitmap represents one
0158 filesystem block.
0159
0160 The first block is block 0, which starts 0x1000 after superblock start.
0161 So for a normal qnx6fs 0x3000 (bootblock + superblock) is the physical
0162 address at which block 0 is located.
0163
0164 Bits at the end of the last bitmap block are set to 1, if the device is
0165 smaller than addressing space in the bitmap.
0166
0167 Bitmap system area
0168 ------------------
0169
0170 The bitmap itself is divided into three parts.
0171
0172 First the system area, that is split into two halves.
0173
0174 Then userspace.
0175
0176 The requirement for a static, fixed preallocated system area comes from how
0177 qnx6fs deals with writes.
0178
0179 Each superblock got it's own half of the system area. So superblock #1
0180 always uses blocks from the lower half while superblock #2 just writes to
0181 blocks represented by the upper half bitmap system area bits.
0182
0183 Bitmap blocks, Inode blocks and indirect addressing blocks for those two
0184 tree structures are treated as system blocks.
0185
0186 The rational behind that is that a write request can work on a new snapshot
0187 (system area of the inactive - resp. lower serial numbered superblock) while
0188 at the same time there is still a complete stable filesystem structure in the
0189 other half of the system area.
0190
0191 When finished with writing (a sync write is completed, the maximum sync leap
0192 time or a filesystem sync is requested), serial of the previously inactive
0193 superblock atomically is increased and the fs switches over to that - then
0194 stable declared - superblock.
0195
0196 For all data outside the system area, blocks are just copied while writing.