^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) .. SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) ===================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) The QNX6 Filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) ===================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) The qnx6fs is used by newer QNX operating system versions. (e.g. Neutrino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) It got introduced in QNX 6.4.0 and is used default since 6.4.1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) Option
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) ======
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) mmi_fs Mount filesystem as used for example by Audi MMI 3G system
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) Specification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) =============
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) qnx6fs shares many properties with traditional Unix filesystems. It has the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) concepts of blocks, inodes and directories.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) On QNX it is possible to create little endian and big endian qnx6 filesystems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) This feature makes it possible to create and use a different endianness fs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) for the target (QNX is used on quite a range of embedded systems) platform
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) running on a different endianness.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) The Linux driver handles endianness transparently. (LE and BE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) Blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) ------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) The space in the device or file is split up into blocks. These are a fixed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) size of 512, 1024, 2048 or 4096, which is decided when the filesystem is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) created.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) Blockpointers are 32bit, so the maximum space that can be addressed is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) 2^32 * 4096 bytes or 16TB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) The superblocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) ---------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) The superblock contains all global information about the filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) Each qnx6fs got two superblocks, each one having a 64bit serial number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) That serial number is used to identify the "active" superblock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) In write mode with reach new snapshot (after each synchronous write), the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) serial of the new master superblock is increased (old superblock serial + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) So basically the snapshot functionality is realized by an atomic final
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) update of the serial number. Before updating that serial, all modifications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) are done by copying all modified blocks during that specific write request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) (or period) and building up a new (stable) filesystem structure under the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) inactive superblock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) Each superblock holds a set of root inodes for the different filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) parts. (Inode, Bitmap and Longfilenames)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) Each of these root nodes holds information like total size of the stored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) data and the addressing levels in that specific tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) If the level value is 0, up to 16 direct blocks can be addressed by each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) Level 1 adds an additional indirect addressing level where each indirect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) addressing block holds up to blocksize / 4 bytes pointers to data blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) Level 2 adds an additional indirect addressing block level (so, already up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) to 16 * 256 * 256 = 1048576 blocks that can be addressed by such a tree).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) Unused block pointers are always set to ~0 - regardless of root node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) indirect addressing blocks or inodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) Data leaves are always on the lowest level. So no data is stored on upper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) tree levels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) The first Superblock is located at 0x2000. (0x2000 is the bootblock size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) The Audi MMI 3G first superblock directly starts at byte 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) Second superblock position can either be calculated from the superblock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) information (total number of filesystem blocks) or by taking the highest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) device address, zeroing the last 3 bytes and then subtracting 0x1000 from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) that address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) 0x1000 is the size reserved for each superblock - regardless of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) blocksize of the filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) Inodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) ------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) Each object in the filesystem is represented by an inode. (index node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) The inode structure contains pointers to the filesystem blocks which contain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) the data held in the object and all of the metadata about an object except
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) its longname. (filenames longer than 27 characters)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) The metadata about an object includes the permissions, owner, group, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) size, number of blocks used, access time, change time and modification time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) Object mode field is POSIX format. (which makes things easier)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) There are also pointers to the first 16 blocks, if the object data can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) addressed with 16 direct blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) For more than 16 blocks an indirect addressing in form of another tree is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) used. (scheme is the same as the one used for the superblock root nodes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) The filesize is stored 64bit. Inode counting starts with 1. (while long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) filename inodes start with 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) Directories
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) -----------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) A directory is a filesystem object and has an inode just like a file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) It is a specially formatted file containing records which associate each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) name with an inode number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) '.' inode number points to the directory inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) '..' inode number points to the parent directory inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) Eeach filename record additionally got a filename length field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) One special case are long filenames or subdirectory names.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) These got set a filename length field of 0xff in the corresponding directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) record plus the longfile inode number also stored in that record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) With that longfilename inode number, the longfilename tree can be walked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) starting with the superblock longfilename root node pointers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) Special files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) -------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) Symbolic links are also filesystem objects with inodes. They got a specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) bit in the inode mode field identifying them as symbolic link.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) The directory entry file inode pointer points to the target file inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) Hard links got an inode, a directory entry, but a specific mode bit set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) no block pointers and the directory file record pointing to the target file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) Character and block special devices do not exist in QNX as those files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) are handled by the QNX kernel/drivers and created in /dev independent of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) underlaying filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) Long filenames
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) --------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) Long filenames are stored in a separate addressing tree. The staring point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) is the longfilename root node in the active superblock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) Each data block (tree leaves) holds one long filename. That filename is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) limited to 510 bytes. The first two starting bytes are used as length field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) for the actual filename.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) If that structure shall fit for all allowed blocksizes, it is clear why there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) is a limit of 510 bytes for the actual filename stored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) Bitmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) ------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) The qnx6fs filesystem allocation bitmap is stored in a tree under bitmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) root node in the superblock and each bit in the bitmap represents one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) filesystem block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) The first block is block 0, which starts 0x1000 after superblock start.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) So for a normal qnx6fs 0x3000 (bootblock + superblock) is the physical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) address at which block 0 is located.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) Bits at the end of the last bitmap block are set to 1, if the device is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) smaller than addressing space in the bitmap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) Bitmap system area
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) The bitmap itself is divided into three parts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) First the system area, that is split into two halves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) Then userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) The requirement for a static, fixed preallocated system area comes from how
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) qnx6fs deals with writes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) Each superblock got it's own half of the system area. So superblock #1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) always uses blocks from the lower half while superblock #2 just writes to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) blocks represented by the upper half bitmap system area bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) Bitmap blocks, Inode blocks and indirect addressing blocks for those two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) tree structures are treated as system blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) The rational behind that is that a write request can work on a new snapshot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) (system area of the inactive - resp. lower serial numbered superblock) while
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) at the same time there is still a complete stable filesystem structure in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) other half of the system area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) When finished with writing (a sync write is completed, the maximum sync leap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) time or a filesystem sync is requested), serial of the previously inactive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) superblock atomically is increased and the fs switches over to that - then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) stable declared - superblock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) For all data outside the system area, blocks are just copied while writing.