Normal view

There are new articles available, click to refresh the page.
Before yesterdayMain stream

Explainer: inodes and inode numbers

By: hoakley
4 October 2025 at 15:00

Every self-respecting file system identifies files and directories using numbered data structures. In most modern file systems, those data structures are known as inodes, and their numbers are inode numbers, sometimes shortened to inodes. The term is thought to be a contraction of index node, which certainly makes sense, but is lost in the mists of time.

In any file system, for example an individual APFS volume, the inode numbers uniquely identify each inode, and each object within that file system has its own inode. Whatever else the file system might do, the inode number identifies one and only one object within it. Thus one invariant way of identifying any file is by referencing the file system containing it, and its inode number.

HFS+

The Mac’s original native file systems, ending most recently in Mac OS Extended File System, or HFS+ from its origins in the Hierarchical File System, don’t use inodes as such, and don’t strictly speaking have inode numbers. Instead, the data structures for their files and folders are kept in Catalogue Nodes, and their numbers are Catalogue Node IDs, CNIDs.

With Mac OS X came Unix APIs, and their requirement to use inodes and inode numbers. As CNIDs are unique to each file and folder within an HFS+ volume, for HFS+ they are used as inode numbers, although in some ways they differ. CNIDs are unsigned 32-bit integers, with the numbers 0-15 reserved for system use. For example, CNID 7 is normally used as the Startup file’s ID.

Although not necessarily related to CNIDs, it’s worth noting that the Mac’s original file system MFS allowed a maximum of 4,094 files, its successor HFS was limited to 65,535, and HFS+ to 4,294,967,295. Those are in effect the maximum number of inode numbers or their equivalents allowed in that file system.

APFS

Unlike HFS+, APFS was designed from the outset to support standard Posix features, so has inodes numbered using unsigned 64-bit integers.

Strictly, the APFS inode number is the object identifier in the header of the file-system key. Not all unsigned 64-bit integers can be used as inode numbers, though, as a bit mask is used, and the number includes an encoded object type. APFS also makes special allowance for volume groups consisting of firmlinked System and Data volumes, to allow for their inode numbers to remain unique across both volumes. Officially, those allow for a maximum number of inode numbers of 9,223,372,036,854,775,808, either in single APFS file systems, or shared across two in a volume group.

fileobject1

Every file in APFS is required to have, at an absolute minimum, an inode and its associated attributes, shown above in blue, including a set of timestamps, permissions, and other essential information about that file.

There are also three optional types of component:

  • although some files may be dataless, most have data, for which they need file extents (green), records linking to the storage blocks containing that file’s data (pink);
  • smaller extended attributes (yellow), named metadata objects that are stored in a single record;
  • larger extended attributes (yellow), over 3,804 bytes in size, whose data is stored separately in a data stream.

Interpretation

When looking at inode numbers in volume groups, they can be used to determine which of the firmlinked file systems contains any given file. Both volumes share the same volume ID, and files in the System volume have very high inode numbers, while those in the Data volume are relatively low. I have given further details here.

Inode numbers are more generally useful in distinguishing files whose data appears identical, and the behaviour of various methods of linking files.

Copying a file within the same file system (volume) creates a new file with its own inode number, of course. However, duplicating a file within the same file system results in an APFS clone file, with a distinct inode, although it shares common data, so their inode numbers are also different.

fileobject3

Instead of duplicating everything, only the inode and its attributes (blue and pink) are duplicated, together with their file extent information. There’s a flag in each clone file’s attributes to indicate that cloning has taken place.

A symbolic link or symlink is merely a pointer to the linked file’s path, and doesn’t involve inode numbers at all. Because of that, changing the linked file’s name or path breaks its link. Finder aliases and their kindred bookmarks do contain inode numbers, so should be able to cope with changes to the linked file’s name or path, provided it remains in the same file system and doesn’t change inode number.

Hard links are more complex, and depend on the way in which the file system implements them, although the fundamental rule is that each object that’s hardlinked to the same file has the same inode number. According to Apple’s reference to APFS, this is how it handles hard links.

fileobject6

When you create a hard link to a file (blue), APFS creates two siblings (purple) with their own IDs and links, including different paths and names as appropriate. Those don’t replace the original inode, and there remains a single file object for the whole of that hardlinked file.

Inode attributes keep a count of the number of links they have to siblings in their link (or reference) count. Normally, when a file has no hard links that’s one, and there are no sibling files. When a file is to be deleted, if its link count is only 1, the file and all its associated components can be removed, subject to the requirements of any clones and applicable snapshots. If the link count is greater than 1, then only the sibling being removed is deleted.

Easy access

Inode numbers are readily accessed using command tools in Terminal. For example, ls -i lists items with their inode numbers shown. One free utility that displays full information about inode numbers and much more is Precize.

The volume ID is given as the first number in the volfs path, and the second is the inode number of that file within that. Note that the File Reference URL (FileRefURL) uses a different numbering system, and the Ref count of 1 indicates this file has no hard links.

How large is that file?

By: hoakley
1 September 2025 at 14:30

At first sight, this might seem a simple question to answer. Allow me to demonstrate that it’s more complex, has changed over time, and still hasn’t been resolved.

Before 1984

Although there were exceptions, before the Mac most file systems that we were likely to encounter were simple. Each file consisted of stored data, together with a small entry in the file system’s metadata containing information such as the file’s name and its time and date of creation. By convention, as that’s not stored with the file’s data, that isn’t included in its size.

The only complication here was that storage is divided up into blocks, so in addition to the file’s actual size, we’d also want to know the total size taken by the storage blocks it used, as any given block couldn’t be shared between files, a figure often known as size on disk, and dependent on the size of those blocks. If the block size is 4,096 bytes, then any file whose data was equal to or smaller than that had a size on disk of 4,096 bytes, 4 KiB or 4.096 KB. (There are 1,000 bytes in a KB, but 1,024 bytes in a KiB.)

Classic Mac OS

One of the many innovations in the first Mac was its file system MFS, in which every file has two forks, one the traditional data fork, the other a resource fork for storing structured blobs of data termed resources. As MFS was replaced by HFS and eventually HFS+, those resource forks continued.

filesize04

Resource forks often reached considerable sizes, and although they are stored separately from data forks in HFS+, Apple usually gave the sizes of the two forks, as shown in this dialog, where the size of the resource fork is 117,836 bytes, almost as large as the file’s 144,788 bytes of data. Information about the size of that file’s entry in the file system data, its attributes, wasn’t given, though.

HFS+ in Mac OS X

In the early years of Mac OS X, there was controversy as to whether it should continue supporting the use of resource forks, and most of their uses were replaced by flattened data files arranged in bundles. Nevertheless, in Mac OS X 10.4, HFS+ became multi-forked with what were dubbed extended attributes or xattrs, one type being com.apple.ResourceFork, the classic resource fork. However, the practice of giving separate sizes for the data fork and other forks died.

APFS

When APFS was released in 2017, it changed the way in which xattrs are stored, as explained here. Now, each file can consist of:

  1. file system attributes, stored in the file system metadata structures;
  2. small xattrs of up to 3,804 bytes, stored separately from its attributes, but in file system metadata;
  3. large xattrs over 3,804 bytes, typically including any com.apple.ResourceFork, stored as data streams with separate records;
  4. data, stored in storage blocks as set out in their file extents.

As demonstrated using crafted files, initially the Finder ignored items 1-3 in stating file size, and just gave that of 4, the data, although it could instead still have been including resource forks, of course.

filesize02

The size of this text file is given as 391 bytes in the Finder’s Get Info in High Sierra, but as you’ll see below it contains over 90,000 bytes of extended attributes that figure simply ignores.

filesize01

macOS Sequoia

Here are the sizes given for another of my specially crafted demonstration files, for APFS in macOS 15.6.1 Sequoia.

According to the Finder’s Get Info dialog, this file contains 263,195 bytes and occupies 266 KB on disk. On an SSD with the standard 4 KiB block size, that should be 65 blocks, or 266,240 bytes, as given correctly. There’s something amiss with that file, though, as it claims to be a Zip archive but has an image thumbnail.

Listing its xattrs using xattred reveals no less than 14, including two of 80 KB each. xattred claims it has a data fork size of 183,136 bytes and 161,406 bytes in xattrs, making a total size of 344,542 bytes, which is nowhere near that given by the Finder. (It’s the com.apple.ResourceFork xattr, a classic resource fork, that contains the image thumbnail displayed by QuickLook instead of the normal Zip file icon.)

To discover how the Finder arrives at a size of 263,195 bytes, we need to subtract the data size from that, making 80,059 bytes, the size of the file’s resource fork or com.apple.ResourceFork xattr. So, without being explicit about forks, it’s behaving the same as in Classic Mac OS. You might find that puzzling, given that there’s another xattr of the same size that it’s ignoring, and a dozen more that don’t get a look-in. As the use of com.apple.ResourceFork xattrs has long been discouraged if not deprecated, isn’t that a strange behaviour? The more so when modern xattrs that Apple has introduced relatively recently, such as com.apple.quarantine, com.apple.macl and com.apple.provenance, are ignored.

The deeper you look into this, the more puzzling it becomes. Here are the same file’s figures as shown in Precize.

Sizes are given a few lines down, from two sources, URL Keys and the file system (FileManager), and they also differ. There’s a list of xattrs given at the foot of this window, but that only gives 12 and ignores com.apple.ResourceFork and com.apple.FinderInfo.

In the macOS API, code can obtain values for file sizes from its URL. Two keys are available, fileSizeKey and totalFileSizeKey. The first gives the data size, and the second is the same ‘total’ as that shown by the Finder, i.e. data + com.apple.ResourceFork xattr, but excluding all other xattrs. Apple’s documentation explains those as:

  • fileSize is “the total file size, in bytes”
  • totalFileSize is “the total displayable size of the file, in bytes. The allocated size in bytes may include space used by metadata.”

FileManager also gives the data size in its FileAttributeKey.size, but doesn’t give any for xattrs, even com.apple.ResourceFork. The size of the Metadata shown for the File system is instead calculated by totalling the individual sizes of all its xattrs, including com.apple.ResourceFork and com.apple.FinderInfo.

This may appear to be nit-picking, but data sizes are given to the exact number of bytes, and the size on disk for non-sparse files should always be within 4,095 bytes of the data size. Yet accounting for xattrs remains rooted in Classic Mac OS from 25 years ago and still pretends that xattrs either don’t exist, or don’t take any space.

Access Linux file systems from Apple silicon Macs

By: hoakley
5 August 2025 at 14:30

macOS comes with no support for the file systems most likely to be used by Linux. This article suggests how you might be able to access them, for example when a NAS system is connected directly to an Apple silicon Mac, or when you need to access external storage that has been used with a Linux system.

extFS

I believe Paragon Software’s extFS is the only generally available commercial solution, and is described here. If you only need access for a short period, it’s free to use for up to ten days, but must be licensed for $39.95, €39.95, or £38.81 if you want to unlock it to use for any longer. Paragon also offers support for accessing APFS from Linux and Windows.

If you need more than simple access to the contents of the file system, you can also combine extFS with an Ubuntu VM running in UTM to access backups made using Duplicity, for example. This is detailed here by Benjamin, to whom I’m very grateful for information about extFS and for inspiring this note.

macFUSE

Benjamin Fleischer’s free fork of Google’s MacFUSE software should be able to implement a fully functional alien file system running in user space. Its latest release 5.0.5 is compatible with current betas of macOS Tahoe as well as older versions back to macOS 12. However, some report that it isn’t able to deliver reliable support for Ext4 and similar. In theory, this should now be simpler, as recent versions of macOS can support macFUSE without requiring a kernel extension, and there’s an alternative backend in recent versions of macFUSE to support that. Project front page.

Jeff Geerling’s walkthrough using macFUSE with ext4fuse.

anylinuxfs

This is based on the libkrun microVM hypervisor, available separately from here. It has the advantage that it doesn’t rely on either kernel or system extensions, and is available from here. I’ve been unable to discover how reliable this is on Apple silicon, if it works at all.

Others

If you know of other ways of doing this with an Apple silicon Mac, please provide details in a comment.

❌
❌