Common File System Types

File system types are an important part of storage management in an operating system, and the different kinds suit different application scenarios and requirements. This chapter walks through the common file system types, covering their characteristics, structure, strengths, weaknesses, and use cases.

Classification of File Systems

By Operating System

Windows File Systems

  • FAT: the file system used by early Windows systems
  • NTFS: the mainstream file system of modern Windows systems
  • ReFS: the next-generation file system of Windows Server

Unix/Linux File Systems

  • ext2/ext3/ext4: the file systems commonly used on Linux
  • XFS: a high-performance file system
  • Btrfs: a next-generation file system
  • ZFS: an enterprise-grade file system

macOS File Systems

  • HFS+: the traditional macOS file system
  • APFS: the modern macOS file system

By Feature Set

Traditional File Systems

  • Block-based file systems
  • Support the basic file operations
  • Provide a directory structure

Journaling File Systems

  • Support a transaction log
  • Provide data consistency guarantees
  • Recover quickly after a crash

Network File Systems

  • Support access to remote files
  • Share files across a network
  • Provide distributed storage

The FAT File System

Basic Concepts

FAT (File Allocation Table) is the file system used by early Windows systems. It is simple and highly compatible.

Structure

// The FAT file system structure
struct fat_boot_sector {
    char jump_code[3];        // the jump instruction
    char oem_name[8];         // the OEM name
    int bytes_per_sector;     // bytes per sector
    int sectors_per_cluster;  // sectors per cluster
    int reserved_sectors;     // number of reserved sectors
    int num_fats;            // number of FAT tables
    int root_entries;        // number of root directory entries
    int total_sectors;       // total number of sectors
    char media_type;         // the media type
    int sectors_per_fat;     // sectors per FAT
    int sectors_per_track;   // sectors per track
    int num_heads;          // number of heads
    int hidden_sectors;     // number of hidden sectors
    int large_sectors;      // number of large sectors
};

struct fat_directory_entry {
    char filename[8];        // the file name
    char extension[3];       // the extension
    char attributes;         // the file attributes
    char reserved[10];       // reserved fields
    int time;               // the time
    int date;               // the date
    int start_cluster;      // the starting cluster number
    int file_size;          // the file size
};

The File Allocation Table

// The structure of the FAT
struct fat_table {
    int* entries;           // the entries of the FAT
    int table_size;         // the size of the table
    int free_clusters;      // the number of free clusters
};

// The meaning of the values in a FAT entry
#define FAT_FREE           0x0000    // a free cluster
#define FAT_RESERVED       0x0001    // a reserved cluster
#define FAT_BAD_CLUSTER    0xFFF7    // a bad cluster
#define FAT_END_OF_FILE    0xFFFF    // the end of the file

Implementing the File Operations

// Reading a file in the FAT file system
int fat_read_file(const char* filename, char* buffer, int offset, int size) {
    // 1. Find the directory entry of the file
    struct fat_directory_entry* entry = find_file_entry(filename);
    if (entry == NULL) return -1;

    // 2. Get the starting cluster of the file
    int current_cluster = entry->start_cluster;
    int bytes_read = 0;
    int current_offset = 0;

    // 3. Move forward to the requested offset
    while (current_offset < offset && current_cluster != FAT_END_OF_FILE) {
        current_cluster = get_next_cluster(current_cluster);
        current_offset += CLUSTER_SIZE;
    }

    // 4. Read the data
    while (bytes_read < size && current_cluster != FAT_END_OF_FILE) {
        int bytes_to_read = min(CLUSTER_SIZE, size - bytes_read);
        int cluster_offset = (offset + bytes_read) % CLUSTER_SIZE;

        read_cluster_data(current_cluster, buffer + bytes_read, cluster_offset, bytes_to_read);

        bytes_read += bytes_to_read;
        current_cluster = get_next_cluster(current_cluster);
    }

    return bytes_read;
}

// Writing a file in the FAT file system
int fat_write_file(const char* filename, const char* data, int size) {
    // 1. Find or create the directory entry of the file
    struct fat_directory_entry* entry = find_or_create_file_entry(filename);
    if (entry == NULL) return -1;

    // 2. Allocate the clusters
    int clusters_needed = (size + CLUSTER_SIZE - 1) / CLUSTER_SIZE;
    int* cluster_chain = allocate_cluster_chain(clusters_needed);
    if (cluster_chain == NULL) return -1;

    // 3. Update the FAT
    for (int i = 0; i < clusters_needed - 1; i++) {
        set_fat_entry(cluster_chain[i], cluster_chain[i + 1]);
    }
    set_fat_entry(cluster_chain[clusters_needed - 1], FAT_END_OF_FILE);

    // 4. Write the data
    int bytes_written = 0;
    for (int i = 0; i < clusters_needed; i++) {
        int bytes_to_write = min(CLUSTER_SIZE, size - bytes_written);
        write_cluster_data(cluster_chain[i], data + bytes_written, bytes_to_write);
        bytes_written += bytes_to_write;
    }

    // 5. Update the directory entry
    entry->start_cluster = cluster_chain[0];
    entry->file_size = size;
    entry->time = get_current_time();
    entry->date = get_current_date();

    free(cluster_chain);
    return bytes_written;
}

Strengths and Weaknesses

Advantages

  • Simplicity: the structure is simple and easy to understand and implement
  • Compatibility: almost every operating system supports it
  • Lightweight: little system overhead, which suits embedded systems

Disadvantages

  • Performance limits: large files are accessed inefficiently
  • Wasted space: the cluster size is fixed, so small files waste space
  • Fragmentation: file fragmentation appears easily
  • Limited features: it does not support advanced features

Use Cases

  • Removable storage devices (USB drives, SD cards)
  • Embedded systems
  • Scenarios that need cross-platform compatibility

The NTFS File System

Basic Concepts

NTFS (New Technology File System) is the standard file system of the Windows NT family of operating systems. It offers a rich feature set and good performance.

Structure

// The NTFS boot sector
struct ntfs_boot_sector {
    char jump_code[3];        // the jump instruction
    char oem_name[8];         // the OEM name
    int bytes_per_sector;     // bytes per sector
    int sectors_per_cluster;  // sectors per cluster
    int reserved_sectors;     // number of reserved sectors
    char unused[5];          // unused
    char media_type;         // the media type
    char unused2[2];         // unused
    int sectors_per_track;   // sectors per track
    int num_heads;          // number of heads
    int hidden_sectors;     // number of hidden sectors
    long long total_sectors; // total number of sectors
    long long mft_cluster;   // the starting cluster of the MFT
    long long mft_mirror_cluster; // the cluster of the MFT mirror
    int mft_record_size;    // the size of an MFT record
    int index_block_size;   // the size of an index block
    long long volume_serial; // the volume serial number
    int checksum;           // the checksum
};

// The header of an MFT record
struct mft_record_header {
    char signature[4];       // the signature "FILE"
    int update_offset;       // the offset of the update sequence array
    int update_count;        // the update sequence count
    int logfile_sequence;    // the log file sequence number
    int sequence_number;     // the sequence number
    int link_count;          // the link count
    int attributes_offset;    // the offset of the attributes
    int flags;               // the flags
    int record_size;         // the size of the record
    int allocated_size;      // the allocated size
    long long file_reference; // the file reference
    int next_attribute_id;   // the ID of the next attribute
};

The Master File Table (MFT)

// The structure of an MFT attribute
struct ntfs_attribute {
    int attribute_type;      // the type of the attribute
    int attribute_length;    // the length of the attribute
    int non_resident;       // whether the attribute is non-resident
    int name_length;        // the length of the name
    int name_offset;        // the offset of the name
    int flags;              // the flags
    int attribute_id;       // the ID of the attribute
    union {
        struct {
            int value_length;    // the length of the value
            int value_offset;    // the offset of the value
        } resident;
        struct {
            long long starting_vcn;  // the starting VCN
            long long ending_vcn;    // the ending VCN
            int runlist_offset;      // the offset of the run list
            int compression_unit;    // the compression unit
            long long allocated_size; // the allocated size
            long long actual_size;   // the actual size
            long long initialized_size; // the initialized size
        } non_resident;
    } data;
};

Implementing the File Operations

// Reading an NTFS file
int ntfs_read_file(const char* filename, char* buffer, int offset, int size) {
    // 1. Find the MFT record
    struct mft_record* record = find_mft_record(filename);
    if (record == NULL) return -1;

    // 2. Find the data attribute
    struct ntfs_attribute* data_attr = find_attribute(record, ATTRIBUTE_DATA);
    if (data_attr == NULL) return -1;

    // 3. Parse the run list
    struct runlist* runs = parse_runlist(data_attr);
    if (runs == NULL) return -1;

    // 4. Move forward to the requested offset
    int bytes_read = 0;
    int current_offset = 0;
    struct runlist_entry* current_run = runs->entries;

    while (current_offset < offset && current_run != NULL) {
        current_offset += current_run->length * CLUSTER_SIZE;
        current_run = current_run->next;
    }

    // 5. Read the data
    while (bytes_read < size && current_run != NULL) {
        int bytes_to_read = min(current_run->length * CLUSTER_SIZE, size - bytes_read);
        int run_offset = (offset + bytes_read) % (current_run->length * CLUSTER_SIZE);

        read_cluster_range(current_run->start_cluster, current_run->length,
                          buffer + bytes_read, run_offset, bytes_to_read);

        bytes_read += bytes_to_read;
        current_run = current_run->next;
    }

    free_runlist(runs);
    return bytes_read;
}

Advanced Features

1. Journaling

// An NTFS log record
struct ntfs_log_record {
    int record_type;         // the type of the record
    int sequence_number;     // the sequence number
    int data_length;         // the length of the data
    char data[MAX_LOG_DATA]; // the log data
};

// Writing to the log
int write_ntfs_log(int operation_type, const char* data, int data_length) {
    struct ntfs_log_record* record = malloc(sizeof(struct ntfs_log_record));
    record->record_type = operation_type;
    record->sequence_number = get_next_sequence_number();
    record->data_length = data_length;
    memcpy(record->data, data, data_length);

    write_log_record(record);
    free(record);
    return 0;
}

2. Compression

// NTFS compression
int ntfs_compress_file(const char* filename) {
    struct mft_record* record = find_mft_record(filename);
    if (record == NULL) return -1;

    // Find the data attribute
    struct ntfs_attribute* data_attr = find_attribute(record, ATTRIBUTE_DATA);
    if (data_attr == NULL) return -1;

    // Set the compression flag
    data_attr->flags |= ATTRIBUTE_COMPRESSED;

    // Compress the data
    char* original_data = read_file_data(record);
    char* compressed_data = compress_data(original_data, data_attr->actual_size);

    // Update the attribute
    update_attribute_data(data_attr, compressed_data);

    free(original_data);
    free(compressed_data);
    return 0;
}

3. Encryption

// NTFS encryption
int ntfs_encrypt_file(const char* filename, const char* password) {
    struct mft_record* record = find_mft_record(filename);
    if (record == NULL) return -1;

    // Generate the encryption key
    unsigned char key[32];
    generate_encryption_key(password, key);

    // Encrypt the file data
    char* original_data = read_file_data(record);
    char* encrypted_data = encrypt_data(original_data, key);

    // Create the encrypted attribute
    struct ntfs_attribute* enc_attr = create_attribute(record, ATTRIBUTE_ENCRYPTED);
    set_attribute_data(enc_attr, encrypted_data);

    free(original_data);
    free(encrypted_data);
    return 0;
}

Strengths and Weaknesses

Advantages

  • Rich feature set: supports advanced features such as journaling, compression, and encryption
  • Excellent performance: handles large files well
  • High reliability: journaling guarantees data consistency
  • Good security: supports file-level encryption and permission control

Disadvantages

  • Complexity: the structure is complex and hard to implement
  • Compatibility: non-Windows systems support it only to a limited extent
  • Resource usage: the system overhead is comparatively large

Use Cases

  • Windows desktop and server systems
  • Environments that need advanced security features
  • Large-capacity storage systems

The ext4 File System

Basic Concepts

ext4 (Fourth Extended File System) is the most widely used file system on Linux, and it improves on ext3.

Structure

// The ext4 superblock
struct ext4_super_block {
    int s_inodes_count;      // total number of inodes
    int s_blocks_count;      // total number of blocks
    int s_r_blocks_count;    // number of reserved blocks
    int s_free_blocks_count; // number of free blocks
    int s_free_inodes_count; // number of free inodes
    int s_first_data_block;  // the first data block
    int s_log_block_size;    // the base-2 logarithm of the block size
    int s_log_cluster_size;  // the base-2 logarithm of the cluster size
    int s_blocks_per_group;  // number of blocks per group
    int s_clusters_per_group; // number of clusters per group
    int s_inodes_per_group;  // number of inodes per group
    int s_mtime;            // the mount time
    int s_wtime;            // the write time
    int s_mnt_count;        // the mount count
    int s_max_mnt_count;    // the maximum mount count
    int s_magic;            // the magic number
    int s_state;            // the state of the file system
    int s_errors;           // the error handling behaviour
    int s_minor_rev_level;  // the minor revision level
    int s_lastcheck;        // the time of the last check
    int s_checkinterval;    // the interval between checks
    int s_creator_os;       // the operating system that created it
    int s_rev_level;        // the revision level
    int s_def_resuid;       // the default reserved user ID
    int s_def_resgid;       // the default reserved group ID
    int s_first_ino;        // the first non-reserved inode
    int s_inode_size;       // the size of an inode
    int s_block_group_nr;   // the block group number
    int s_feature_compat;   // the compatible features
    int s_feature_incompat; // the incompatible features
    int s_feature_ro_compat; // the read-only compatible features
    char s_uuid[16];        // the UUID of the file system
    char s_volume_name[16]; // the volume name
    char s_last_mounted[64]; // the last mount point
    int s_algorithm_usage_bitmap; // the algorithm usage bitmap
    char s_prealloc_blocks; // the number of preallocated blocks
    char s_prealloc_dir_blocks; // the number of preallocated directory blocks
    char s_reserved_gdt_blocks; // the number of reserved GDT blocks
    char s_journal_uuid[16]; // the UUID of the journal
    int s_journal_inum;     // the inode number of the journal
    int s_journal_dev;      // the device number of the journal
    int s_last_orphan;      // the last orphaned inode
    int s_hash_seed[4];     // the hash seed
    char s_def_hash_version; // the default hash version
    char s_jnl_backup_type; // the type of the journal backup
    int s_desc_size;        // the size of the descriptor
    int s_default_mount_opts; // the default mount options
    int s_first_meta_bg;    // the first metadata block group
    int s_mkfs_time;        // the creation time
    int s_jnl_blocks[17];   // the journal blocks
    int s_blocks_count_hi;  // the upper 32 bits of the total block count
    int s_r_blocks_count_hi; // the upper 32 bits of the reserved block count
    int s_free_blocks_count_hi; // the upper 32 bits of the free block count
    int s_min_extra_isize;  // the minimum extra inode size
    int s_want_extra_isize; // the desired extra inode size
    int s_flags;            // the flags
    int s_raid_stride;      // the RAID stride
    int s_mmp_interval;     // the MMP interval
    long long s_mmp_block;  // the MMP block
    int s_raid_stripe_width; // the RAID stripe width
    char s_log_groups_per_flex; // the number of flexible groups per group
    char s_reserved_char_pad; // reserved character padding
    int s_reserved_pad;     // reserved padding
    long long s_kbytes_written; // the number of kilobytes written
    int s_snapshot_inum;    // the inode number of the snapshot
    int s_snapshot_id;      // the snapshot ID
    long long s_snapshot_r_blocks_count; // the number of reserved snapshot blocks
    int s_snapshot_list;    // the snapshot list
    int s_error_count;      // the error count
    int s_first_error_time; // the time of the first error
    int s_first_error_ino;  // the inode of the first error
    long long s_first_error_block; // the block of the first error
    char s_first_error_func[32]; // the function of the first error
    int s_first_error_line; // the line of the first error
    int s_last_error_time;  // the time of the last error
    int s_last_error_ino;   // the inode of the last error
    long long s_last_error_block; // the block of the last error
    char s_last_error_func[32]; // the function of the last error
    int s_last_error_line;  // the line of the last error
    char s_mount_opts[64];  // the mount options
    int s_usr_quota_inum;  // the inode of the user quota
    int s_grp_quota_inum;  // the inode of the group quota
    int s_overhead_blocks;  // the number of overhead blocks
    int s_backup_bgs[2];   // the backup block groups
    char s_reserved[157];  // reserved fields
};

The inode Structure

// The ext4 inode structure
struct ext4_inode {
    int i_mode;             // the file type and permissions
    int i_uid;              // the user ID
    long long i_size;       // the file size
    int i_atime;            // the access time
    int i_ctime;            // the creation time
    int i_mtime;            // the modification time
    int i_dtime;            // the deletion time
    int i_gid;              // the group ID
    int i_links_count;      // the number of links
    int i_blocks;           // the number of blocks
    int i_flags;            // the flags
    union {
        struct {
            int l_i_reserved1; // reserved field
        } linux1;
        struct {
            int h_i_translator; // the translator
        } hurd1;
        struct {
            int m_i_reserved1; // reserved field
        } masix1;
    } osd1;
    int i_block[15];        // the block pointers
    int i_generation;       // the generation number
    int i_file_acl;         // the file ACL
    long long i_size_high;  // the upper 32 bits of the file size
    int i_faddr;            // the fragment address
    union {
        struct {
            char l_i_frag;  // the fragment number
            char l_i_fsize; // the fragment size
            int i_pad1;     // padding
            int l_i_reserved2[2]; // reserved fields
        } linux2;
        struct {
            char h_i_frag;  // the fragment number
            char h_i_fsize; // the fragment size
            int h_i_mode_high; // the upper 16 bits of the mode
            int h_i_uid_high;  // the upper 16 bits of the user ID
            int h_i_gid_high;  // the upper 16 bits of the group ID
            int h_i_author;     // the author
        } hurd2;
        struct {
            char m_i_frag;  // the fragment number
            char m_i_fsize; // the fragment size
            int m_i_reserved2[2]; // reserved fields
        } masix2;
    } osd2;
    int i_reserved2[2];     // reserved fields
};

Implementing the File Operations

// Reading an ext4 file
int ext4_read_file(const char* filename, char* buffer, int offset, int size) {
    // 1. Find the inode
    struct ext4_inode* inode = find_inode_by_name(filename);
    if (inode == NULL) return -1;

    // 2. Check the size of the file
    if (offset >= inode->i_size) return 0;
    if (offset + size > inode->i_size) {
        size = inode->i_size - offset;
    }

    // 3. Compute the block numbers
    int start_block = offset / BLOCK_SIZE;
    int end_block = (offset + size - 1) / BLOCK_SIZE;
    int bytes_read = 0;

    // 4. Read the data blocks
    for (int block = start_block; block <= end_block; block++) {
        int block_number = get_block_number(inode, block);
        if (block_number == 0) break;

        int block_offset = (block == start_block) ? (offset % BLOCK_SIZE) : 0;
        int bytes_to_read = min(BLOCK_SIZE - block_offset, size - bytes_read);

        read_block_data(block_number, buffer + bytes_read, block_offset, bytes_to_read);
        bytes_read += bytes_to_read;
    }

    return bytes_read;
}

Journaling

// The ext4 journal structures
struct ext4_journal_header {
    int h_magic;            // the magic number
    int h_blocktype;        // the block type
    int h_sequence;         // the sequence number
};

struct ext4_journal_commit_block {
    struct ext4_journal_header header;
    int commit_sec;         // the commit time in seconds
    int commit_nsec;        // the commit time in nanoseconds
};

// Writing to the journal
int ext4_write_journal(int transaction_id, struct journal_entry* entries, int count) {
    // 1. Write the journal header
    struct ext4_journal_header header;
    header.h_magic = EXT4_JOURNAL_MAGIC;
    header.h_blocktype = EXT4_JOURNAL_COMMIT_BLOCK;
    header.h_sequence = transaction_id;

    write_journal_block(&header, sizeof(header));

    // 2. Write the journal entries
    for (int i = 0; i < count; i++) {
        write_journal_block(&entries[i], sizeof(struct journal_entry));
    }

    // 3. Write the commit block
    struct ext4_journal_commit_block commit;
    commit.header = header;
    commit.commit_sec = get_current_time();
    commit.commit_nsec = get_current_nsec();

    write_journal_block(&commit, sizeof(commit));

    return 0;
}

Strengths and Weaknesses

Advantages

  • Good stability: proven over a long period of time, so it is highly stable
  • Strong compatibility: fully compatible with ext2 and ext3
  • Excellent performance: supports large files and directories
  • Rich feature set: supports journaling, extended attributes, and more

Disadvantages

  • Fragmentation: fragmentation may appear after long-term use
  • Feature limits: it does not support some advanced features, such as snapshots
  • Scalability: the maximum size of the file system is limited

Use Cases

  • Linux desktop and server systems
  • Production environments that need stability
  • Traditional Unix/Linux applications

Other File Systems

The XFS File System

XFS is a high-performance file system that is particularly well suited to large files and parallel I/O.

// The XFS superblock
struct xfs_sb {
    int sb_magicnum;        // the magic number
    int sb_blocksize;       // the block size
    long long sb_dblocks;   // the number of data blocks
    long long sb_rblocks;   // the number of realtime blocks
    long long sb_rextents;  // the number of realtime extents
    char sb_uuid[16];       // the UUID
    long long sb_logstart;  // the starting block of the log
    long long sb_rootino;   // the root inode number
    long long sb_rbmino;    // the inode number of the realtime bitmap
    long long sb_rsumino;   // the inode number of the realtime summary
    int sb_rextsize;        // the size of a realtime extent
    int sb_agblocks;        // the number of blocks in an allocation group
    int sb_agcount;         // the number of allocation groups
    int sb_rbmblocks;       // the number of realtime bitmap blocks
    int sb_logblocks;       // the number of log blocks
    int sb_versionnum;      // the version number
    int sb_sectsize;        // the sector size
    int sb_inodesize;       // the inode size
    int sb_inopblock;       // the number of inodes per block
    char sb_fname[12];      // the name of the file system
    int sb_blocklog;        // the base-2 logarithm of the block size
    int sb_sectlog;         // the base-2 logarithm of the sector size
    int sb_inodelog;        // the base-2 logarithm of the inode size
    int sb_inopblog;        // the base-2 logarithm of the inodes per block
    int sb_agblklog;        // the base-2 logarithm of the blocks in an allocation group
    int sb_rextslog;        // the base-2 logarithm of the realtime extent size
    int sb_inprogress;      // the mount flag
    int sb_imax_pct;        // the maximum percentage of inodes
    long long sb_icount;    // the number of allocated inodes
    long long sb_ifree;     // the number of free inodes
    long long sb_fdblocks;  // the number of free data blocks
    long long sb_frextents; // the number of free realtime extents
    long long sb_uquotino;  // the inode number of the user quota
    long long sb_gquotino;  // the inode number of the group quota
    int sb_qflags;          // the quota flags
    int sb_flags;           // the flags
    int sb_shared_vn;       // the shared version number
    int sb_inoalignmt;      // the inode alignment mask
    int sb_unit;            // the unit
    int sb_width;           // the width
    int sb_dirblklog;       // the base-2 logarithm of the directory block size
    int sb_logsectlog;      // the base-2 logarithm of the log sector size
    int sb_logsectsize;     // the log sector size
    int sb_logsunit;        // the log unit
    int sb_features2;       // the features set 2
    int sb_bad_features2;   // the bad features set 2
    int sb_features_compat; // the compatible features
    int sb_features_ro_compat; // the read-only compatible features
    int sb_features_incompat; // the incompatible features
    int sb_features_log_incompat; // the log-incompatible features
    char sb_fname[12];      // the name of the file system
    char sb_pad[4];         // padding
    long long sb_features3; // the features set 3
    long long sb_features4; // the features set 4
    int sb_crc;             // the CRC
    int sb_pad2;            // padding 2
    long long sb_pquotino;  // the inode number of the project quota
    long long sb_lsn;       // the log sequence number
    long long sb_meta_uuid[16]; // the metadata UUID
};

The Btrfs File System

Btrfs is a next-generation file system with support for snapshots, compression, RAID, and other advanced features.

// The Btrfs superblock
struct btrfs_super_block {
    char csum[32];          // the checksum
    char fsid[16];          // the ID of the file system
    long long bytenr;       // the byte number
    long long flags;        // the flags
    char chunk_tree_uuid[16]; // the UUID of the chunk tree
    long long generation;   // the generation number
    long long root;         // the root
    long long chunk_root;   // the chunk root
    long long log_root;     // the log root
    long long log_root_transid; // the transaction ID of the log root
    long long total_bytes;  // the total number of bytes
    long long bytes_used;   // the number of bytes in use
    long long root_dir_objectid; // the object ID of the root directory
    long long num_devices;  // the number of devices
    long long sector_size;  // the sector size
    long long node_size;    // the node size
    long long leaf_size;    // the leaf size
    long long stripe_size;  // the stripe size
    int n;                  // unused
    long long chunk_root_generation; // the generation number of the chunk root
    long long compat_flags; // the compatible flags
    long long compat_ro_flags; // the read-only compatible flags
    long long incompat_flags; // the incompatible flags
    long long csum_type;    // the type of the checksum
    long long root_level;   // the level of the root
    long long chunk_root_level; // the level of the chunk root
    long long log_root_level; // the level of the log root
    struct btrfs_dev_item dev_item; // the device item
    char label[256];        // the label
    long long cache_generation; // the generation number of the cache
    long long uuid_tree_generation; // the generation number of the UUID tree
    long long reserved[30]; // reserved fields
    char sys_chunk_array[2048]; // the system chunk array
    struct btrfs_root_backup super_roots[BTRFS_NUM_BACKUP_ROOTS]; // the backup super roots
};

A Guide to Choosing a File System

Factors to Consider

1. Performance Requirements

  • High throughput: XFS, Btrfs
  • Low latency: ext4, NTFS
  • Large file handling: XFS, ZFS

2. Feature Requirements

  • Snapshot support: Btrfs, ZFS
  • Compression: Btrfs, NTFS
  • Encryption: NTFS, ext4 (through eCryptfs)

3. Compatibility Requirements

  • Cross-platform: FAT, exFAT
  • Windows compatibility: NTFS
  • Linux compatibility: ext4, XFS

4. Reliability Requirements

  • Data consistency: journaling file systems
  • Error recovery: Btrfs, ZFS
  • Data integrity: ZFS, Btrfs

Desktop Systems

  • Windows: NTFS
  • Linux: ext4
  • macOS: APFS

Server Systems

  • High performance: XFS
  • High reliability: ZFS
  • Balanced: ext4

Storage Systems

  • Large capacity: XFS, ZFS
  • Network storage: NFS, CIFS
  • Cloud storage: distributed file systems

Glossary

TermAbbreviationExplanation
File Allocation TableFATThe file allocation table file system
FAT12-A 12-bit FAT, used on floppy disks
FAT16-A 16-bit FAT
FAT32-A 32-bit FAT
New Technology File SystemNTFSThe Windows file system
Second Extended File Systemext2The second-generation extended file system for Linux
Third Extended File Systemext3ext2 with journaling
Fourth Extended File Systemext4The fourth-generation extended file system for Linux
XFS-A high-performance 64-bit file system
B-Tree File SystemBtrfsA copy-on-write file system
Zettabyte File SystemZFSA large-capacity file system
Hierarchical File System PlusHFS+The macOS file system
Apple File SystemAPFSApple’s next-generation file system
Extended File Allocation TableexFATAn extended FAT that supports large files
Universal Disk FormatUDFThe universal format for optical discs
ISO9660-The standard file system for CD-ROMs
Journaling file system-A file system that keeps a log of operations
Copy-on-writeCOWA technique that copies data before modifying it
Snapshot-A point-in-time copy of a file system
Checksum-Verifies the integrity of data
Compression-File system level data compression
Encryption-File system level data encryption
Deduplication-Eliminates duplicate data blocks
Cluster file system-A file system shared by several nodes

Found an issue with this content?

Tell us what could be improved.