💾 Archived View for lofi.haiku-os.org › docs › develop › file_systems › xfs.gmi captured on 2024-03-21 at 15:08:17. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-09-28)
-=-=-=-=-=-=-
This document describes how to test the XFS file system, XFS file system API for haiku and Its current status on haiku.
There are three ways we can test XFS :
But before that we will need to create XFS images for all testing purposes.
Currently only linux has full XFS support so we will use linux for generating file system images.
First we need to create an empty sparse image using command:
$ dd if=/dev/zero of=fs.img count=0 bs=1 seek=5G
The output will be:
0+0 records in 0+0 records out 0 bytes (0 B) copied, 0.000133533 s, 0.0 kB/s
Do note that we can create images of whatever size or name we want, for example the above command creates fs.img of size 5 GB, if we alter seek = 10G it will create fs.img with size 10 GB.
The XFS file system on linux supports two versions, V4 and V5.
To put XFS V5 file system on our sparse image run command:
$ /sbin/mkfs.xfs fs.img
The output will be:
meta-data =fs.img isize=512 agcount=4, agsize=65536 blks = sectsz=512 attr=2, projid32bit=1 = crc=1 finobt=1, sparse=1, rmapbt=0 = reflink=1 data = bsize=4096 blocks=262144, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0, ftype=1 log =internal log bsize=4096 blocks=2560, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0
To put XFS V4 file system on our sparse image run command:
$ /sbin/mkfs.xfs -m crc=0 file.img
The output will be:
meta-data=fs.img isize=256 agcount=4, agsize=327680 blks = sectsz=512 attr=2, projid32bit=0 data = bsize=4096 blocks=1310720, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 log =internal log bsize=4096 blocks=2560, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0
Support for the V4 format will be removed entirely in September 2030**
Now we can mount our file system image and create entries for testing XFS haiku driver.
The idea of fs_shell is to run the file system code outside of haiku. We can run it as an application, it provides a simple command line interface to perform various operations on the file system (list directories, read and display files, etc).
First we have to compile it:
jam "<build>xfs_shell"
Then run it:
jam run ":<build>xfs_shell" fs.img
Where fs.img is the file system image we created from linux kernel.
First build a version of haiku with XFS support, to do this we need to add “xfs” to the
definition
.
Then compile haiku as usual and run the resulting system in a virtual machine or on real hardware.
We can then try to mount an XFS file system using command on Haiku:
mount -t xfs <path to image> <path to mount folder>
for example:
mount -t xfs /boot/home/Desktop/fs.img /boot/home/Desktop/Testing
Here fs.img is file system image and Testing is mount point.
To be updated
All the necessary hooks for file system like xfs_mount(), open_dir(), read_dir() etc.. are implemented in the **kernel_interface.cpp** file. It acts as an interface between the Haiku kernel and the XFS file system. Documentation for all necessary file system hooks can be found
Whenever we run a file system under fs_shell we can’t use system headers, fs_shell compatible headers are there which needs to be used whenever we try to mount XFS file system using xfs_shell. To resolve this problem we use **system_dependencies.h** header file which takes care to use correct headers whenever we mount XFS file system either using xfs_shell or directly inside Haiku.
XFS stores data on disk in Big Endian byte order, to convert data into host order all classes and data headers has **SwapEndian()** function, Its better to have all data conversions at one place to avoid future problems related to data byte order.
XFS SuperBlock starts at ondisk offset 0, the definition of SuperBlock is in **xfs.h** file.
A Volume is an instance of file system and defined in **Volume.h** file. XFS Volume contains SuperBlock, file system device and essential functions like Identify(), mount() etc…
XFS uses TRACE Macro to debug file system, definitions for TRACE, ERROR and ASSERT are defined at **Debug.h** in the form of Macro.
To enable TRACE calls just add "#define TRACE_XFS" in Debug.h file and vice versa to disable it.
XFS V5 introduced metadata checksums to ensure the integrity of metadata in file system, It uses CRC32C checksum algorithm. For XFS all checksums related functions are defined in **Checksum.h** header file. It contains following functions :
in big endian byte order**
XFS V5 introduced many other fields for metadata verification like *BlockNo* *UUID* *Owner* etc.. All this fields are common in every data header and so are their checks. So to not repeat same checks again and again for all headers we created a *VerifyHeader* template function which is defined in **VerifyHeader.h** file. This function is commonly used in all forms of headers for verification purposes.
XFS inodes comes in three versions:
Version 1 inode support is already deprecated on linux kernel, Haiku XFS supports it only in read format. When we will have write support for XFS we will only support V2 and V3 inodes.
V1 & V2 inodes are 256 bytes while V3 inodes are 512 bytes in size allowing more data to be stored directly inside inode.
Similarly **DIR_AFORK_PTR** Macro expands to void pointer to the attribute offset in inode, which could be either shortform attributes, attributes extents or B+Tree node depending on the attribute format of Inode (di_aformat).
Since size of inodes could differ based on different versions of XFS we pass CoreInodeSize() function as a parameter to DIR_DFORK_PTR and DIR_AFORK_PTR macros to return correct pointer offset.
Depending on the number of entries inside directory, XFS divides directories into five formats :
Class DirectoryIterator in **Directory.h** file provides an interface between kernel request to open, read directory and all forms of directories. It first identifies correct format of entries inside inode and then returns request as per format found.
TODO : Document Node and B+Tree based directories.
XFS stores files in two formats :
All implementation of read support for files is inside *Inode()* class in **Inode.h** file.
When the format inside inode of file is *XFS_DINODE_FMT_EXTENTS* it is an extent based file, to read all data of file we simply iterate over all extents which is very similar to how we do it in Extent based directories.
When the file becomes too large such that we cannot store more extent maps inside inode the format of file is changed to B+Tree. When the format inside inode of file is *XFS_DINODE_FMT_BTREE* it is an B+Tree based file, to read all data of file first we read blocks of B+Tree to extract extent maps and then read extents to get file’s data.
Currently we only have read support for XFS, below briefly summarises read support for all formats.
Currently we have no extended attributes support for xfs.
Currently we have no symlinks support for xfs.
Currently we have no write support for xfs.
The best and only reference for xfs is latest version of “xfs_filesystem_structure” written by Linux-XFS developers.
The pdf version of above Doc can be found