IOCTL-XFS-SCRUB-METADATA(2)

πŸ“¦
version 7.2.1 Β· 3 versions
, in alpine 3.22, alpine 3.23, alpine 3.24, arch rolling, centos-stream 10, fedora 43, fedora 44, nixos 26.05, nixpkgs unstable, opensuse-leap 16.0, ubuntu resolute, ubuntu stonking

✨ NAME ✨

ioctl_xfs_scrub_metadata β€” check XFS filesystem metadata πŸ’–

okay so real talk, this is a page from section 2, the System Calls Manual, and it's the whole entire tea on the XFS ioctl that goes "hey bestie, is my metadata okay or is it giving damaged". Buckle up, it's a long one 🫢


🌈 SYNOPSIS 🌈

#include <xfs/xfs_fs.h>

int ioctl(int dest_fd, XFS_IOC_SCRUB_METADATA, struct xfs_scrub_metadata
*arg);

πŸ¦‹ DESCRIPTION πŸ¦‹

So basically, this XFS ioctl slides into the kernel driver and is like "bestie, pls examine a piece of filesystem metadata for errors or for suboptimal metadata" πŸ‘€. And "examine" here is doing a LOT of heavy lifting β€” it means:

  • running the metadata verifiers,
  • checking records for obviously incorrect or straight-up impossible values,
  • and cross-referencing every record against any other available metadata in the filesystem. the way it cross-checks everything?? iconic πŸ”₯

This ioctl can also try to repair or optimize metadata, but heads up, that can block normal filesystem operations for a long period of time 😭 so like, don't be shocked.

The type and location of the metadata you wanna scrub gets passed in a struct that looks exactly like this:

struct xfs_scrub_metadata {
     __u32 sm_type;
     __u32 sm_flags;
     __u64 sm_ino;
     __u32 sm_gen;
     __u32 sm_agno;
     __u64 sm_reserved[5];
};

The field sm_reserved must be zero. no exceptions, don't be cute with it πŸ’…


🌸 sm_type β€” what are we even checking 🌸

The field sm_type tells the kernel the type of metadata to check:

  • XFS_SCRUB_TYPE_PROBE β€” probe the kernel to see if it's even willing to try to check or repair this filesystem. sm_agno, sm_ino, and sm_gen must all be zero.
  • XFS_SCRUB_TYPE_SB, XFS_SCRUB_TYPE_AGF, XFS_SCRUB_TYPE_AGFL, XFS_SCRUB_TYPE_AGI β€” examine a given allocation group's superblock, free space header, free block list, or inode header, respectively. headers get checked for obviously incorrect values and cross-referenced against the allocation group's metadata btrees, if possible. you gotta put the allocation group number in sm_agno. and sm_ino and sm_gen must be zero.
  • XFS_SCRUB_TYPE_BNOBT, XFS_SCRUB_TYPE_CNTBT, XFS_SCRUB_TYPE_INOBT, XFS_SCRUB_TYPE_FINOBT, XFS_SCRUB_TYPE_RMAPBT, XFS_SCRUB_TYPE_REFCNTBT β€” examine a given allocation group's two free space btrees, two inode btrees, reverse mapping btrees, or reference count btrees, respectively. records get checked for obviously incorrect values and cross-referenced with other allocation group metadata records so we can be sure there are no conflicts 🚨. the allocation group number goes in sm_agno, and sm_ino and sm_gen must be zero.
  • XFS_SCRUB_TYPE_RGSUPER β€” examine a given realtime allocation group's superblock. the realtime allocation group number goes in sm_agno. sm_ino and sm_gen must be zero.
  • XFS_SCRUB_TYPE_INODE β€” examine a given inode record for obviously incorrect values and discrepancies with the rest of the filesystem metadata. parent pointers get checked for impossible inode values and then followed up to the parent directory to make sure the linkage is correct 🧚. you can specify the inode to examine either through sm_ino and sm_gen, or, if you don't specify it, then the file described by dest_fd gets examined instead. sm_agno must be zero.
  • XFS_SCRUB_TYPE_BMBTD, XFS_SCRUB_TYPE_BMBTA, XFS_SCRUB_TYPE_BMBTC β€” examine a given inode's data block map, extended attribute block map, or copy on write block map. inode records get examined for obviously incorrect values and discrepancies with the three block map types. the block maps get checked for obviously wrong values and cross-referenced with the allocation group space extent metadata to catch discrepancies. the inode to examine can be specified in the same manner as XFS_SCRUB_TYPE_INODE.
  • XFS_SCRUB_TYPE_XATTR β€” examine the extended attribute records and indices of a given inode for incorrect pointers and other signs of damage πŸ’€. the inode to examine can be specified in the same manner as XFS_SCRUB_TYPE_INODE.
  • XFS_SCRUB_TYPE_DIR β€” examine the entries in a given directory for invalid data or dangling pointers. if the filesystem supports directory parent pointers, every entry gets checked to confirm that the child file has a matching parent pointer πŸŽ€. the directory to examine can be specified in the same manner as XFS_SCRUB_TYPE_INODE.
  • XFS_SCRUB_TYPE_PARENT β€” for filesystems that support directory parent pointers, this scrubber examines all the parent pointers attached to a file and confirms that the parent directory has an entry matching the parent pointer. for filesystems that do not support directory parent pointers, this scrubber instead checks that a subdirectory's dotdot entry points to a directory with an entry that points back to the subdirectory πŸ”. the inode to examine can be specified in the same manner as XFS_SCRUB_TYPE_INODE.
  • XFS_SCRUB_TYPE_DIRTREE β€” this scrubber looks for problems in the directory tree structure, like loops and directories reachable through more than one path πŸŒ€. problems get detected by walking parent pointers upwards towards the root. loops get detected by comparing the parent directory at each step against the directories already examined. directories with multiple paths get detected by counting the parent pointers attached to a directory. non-directories don't have links pointing away from the directory tree root and can be skipped, so don't even worry about them. the directory to examine can be specified in the same manner as XFS_SCRUB_TYPE_INODE.
  • XFS_SCRUB_TYPE_SYMLINK β€” examine the target of a symbolic link for obvious pathname problems πŸ”—. the link to examine can be specified in the same manner as XFS_SCRUB_TYPE_INODE.
  • XFS_SCRUB_TYPE_RTBITMAP, XFS_SCRUB_TYPE_RTSUM, XFS_SCRUB_TYPE_RTRMAPBT, XFS_SCRUB_TYPE_RTREFCBT β€” examine a given realtime allocation group's free space bitmap, summary file, reverse mapping btree, or reference count btree, respectively.
  • XFS_SCRUB_TYPE_UQUOTA, XFS_SCRUB_TYPE_GQUOTA, XFS_SCRUB_TYPE_PQUOTA β€” examine all user, group, or project quota records for corruption 🧾.
  • XFS_SCRUB_TYPE_FSCOUNTERS β€” examine all filesystem summary counters (free blocks, inode count, free inode count) for errors.
  • XFS_SCRUB_TYPE_NLINKS β€” scan all inodes in the filesystem to verify each file's link count πŸ”’.
  • XFS_SCRUB_TYPE_HEALTHY β€” mark everything healthy after a clean scrub run ✨. this clears out all the indirect health problem markers that might still be lurking in the system.
  • XFS_SCRUB_TYPE_METAPATH β€” check that a metadata directory path actually points to the active metadata inode. metadata inodes are usually cached for the duration of the mount, so this scrubber makes sure that the same inode will still be reachable after an unmount and mount cycle πŸ”„. discrepancies can happen if the directory or parent pointer scrubbers rebuild a metadata directory but lose a link in the process. sm_ino should be passed one of the following special values to communicate which path to check:
    • XFS_SCRUB_METAPATH_RTDIR β€” realtime metadata file subdirectory.
    • XFS_SCRUB_METAPATH_RTBITMAP β€” realtime bitmap file.
    • XFS_SCRUB_METAPATH_RTSUMMARY β€” realtime summary file.
    • XFS_SCRUB_METAPATH_QUOTADIR β€” quota metadata file subdirectory.
    • XFS_SCRUB_METAPATH_USRQUOTA β€” user quota file.
    • XFS_SCRUB_METAPATH_GRPQUOTA β€” group quota file.
    • XFS_SCRUB_METAPATH_PRJQUOTA β€” project quota file.
    • XFS_SCRUB_METAPATH_RTRMAPBT β€” realtime rmap btree file.
    • XFS_SCRUB_METAPATH_RTREFCOUNTBT β€” realtime reference count btree file.

and for this one, the values of sm_agno and sm_gen must be zero.


πŸ’… sm_flags β€” behavior + the receipts πŸ’…

The field sm_flags controls the behavior of the scrub operation and also carries more info about how the operation turned out πŸ‘‘. And here's the vibe check: if none of the XFS_SCRUB_OFLAG_* flags are set when the call returns, the metadata is clean ✨.

  • XFS_SCRUB_IFLAG_REPAIR β€” if the caller sets this flag, the kernel driver will examine the metadata and try to fix all the problems and optimize the metadata when possible πŸ› οΈ. if no errors happen during the repair operation, the check gets performed a second time to determine whether the repair actually succeeded. if errors happen, the call returns an error status immediately.
  • XFS_SCRUB_OFLAG_CORRUPT β€” the metadata was corrupt when the call returned 😭. if XFS_SCRUB_IFLAG_REPAIR was specified, then an attempted repair failed to fix the problem. unmount the filesystem and run xfs_repair to fix the filesystem.
  • XFS_SCRUB_OFLAG_PREEN β€” the metadata is ok, but some aspect of it could be optimized to increase performance πŸ“ˆ. call again with XFS_SCRUB_IFLAG_REPAIR to optimize the metadata.
  • XFS_SCRUB_OFLAG_XFAIL β€” filesystem errors were encountered when accessing other metadata to cross-reference the records attached to this metadata object πŸ™ˆ.
  • XFS_SCRUB_OFLAG_XCORRUPT β€” discrepancies were found when cross-referencing the records attached to this metadata object against all other available metadata in the system πŸ‘€.
  • XFS_SCRUB_OFLAG_INCOMPLETE β€” the checker was unable to complete its check of all records πŸ˜”.
  • XFS_SCRUB_OFLAG_WARNING β€” the checker encountered a metadata object with potentially problematic records. however, the records were not obviously corrupt. so like, sus but not confirmed πŸ€”.

For metadata checkers that operate on inodes or inode metadata, the fields sm_ino and sm_gen are the inode number and generation number of the inode to check 🧐. if the inode number is zero, the inode represented by dest_fd gets used instead. if the generation number of the inode doesn't match sm_gen, the call will return an error code for the invalid argument 🚫. and the sm_agno field must be zero.


bestie this page is long and it does not end here β€” there's more coming in part 2, so don't go anywhere πŸ’–

okay bestie, picking up right where we left off πŸ’– for the metadata checkers that do their thing on allocation group metadata, the field sm_agno tells you which allocation group to go dig around in for that metadata. and the sm_ino and sm_gen fields? yeah those gotta be zero. no exceptions, babe. πŸ™…β€β™€οΈ

and for the metadata checkers that work on filesystem-wide metadata? no extra arguments needed, you're already that girl. sm_agno, sm_ino, and sm_gen must all be zero. periodt. πŸ’…


✨ RETURN VALUE ✨

if something goes wrong, -1 gets returned and errno gets set to spill all the tea about what happened. 😭


πŸŽ€ ERRORS πŸŽ€

so the error codes can be one of these, but ngl it's not limited to these either β€” the universe is vast and so is the error space:

  • EBUSY β€” the filesystem object is busy bestie 😩 like it's occupied. you're gonna have to try the whole operation again later.
  • EFSCORRUPTED β€” yikes!! severe filesystem corruption was detected and it could not be repaired. unmount the filesystem and run xfs_repair to fix the filesystem. no skipping this step, fr fr.
  • EINVAL β€” one or more of the arguments you specified is invalid. check ur inputs bestie πŸ™ˆ
  • ENOENT β€” the specified metadata object does not exist. for example, this error code is returned for a XFS_SCRUB_TYPE_REFCNTBT request on a filesystem that does not support reflink. it's giving "you're looking for something that was never there" πŸ’€
  • ENOMEM β€” there was not sufficient memory to perform the scrub or repair operation. some operations (most notably reference count checking) require large amounts of memory. she's hungry and you didn't feed her 😭
  • ENOSPC β€” there is not enough free disk space to attempt a repair. disk said "no room at the inn" πŸ“
  • ENOTRECOVERABLE β€” filesystem was mounted in norecovery mode and therefore has an unclean log. neither scrub nor repair operations can be attempted with an unclean log. like, at all. don't even try it.
  • ENOTTY β€” online scrubbing or repair were not enabled. the feature said "not today" πŸ™…β€β™€οΈ
  • EOPNOTSUPP β€” repairs of the requested metadata object are not supported. it's just not in her repertoire, queen. πŸ‘‘
  • EROFS β€” filesystem is read-only and a repair was requested. you literally cannot write to a read-only filesystem bestie, that's the whole vibe. 😭
  • ESHUTDOWN β€” filesystem is shut down due to previous errors. she's not coming to the function rn, previous drama took her out. πŸ’€

🌈 CONFORMING TO 🌈

this API is specific to XFS filesystem on the Linux kernel. iykyk. no portability arc here, it's a one-filesystem kinda love story. πŸ¦‹


πŸ’œ NOTES πŸ’œ

okay real talk for a sec bestie: these operations may block other filesystem operations for a long time. like, a while. a minute. potentially more. so plan accordingly. ⏳

a calling process can stop the operation by being sent a fatal signal, but heads up β€” non-fatal signals are blocked. so like, if you're trying to politely nudge it with something non-fatal, that's not gonna land. only the fatal ones get through, periodt. πŸ’…


⭐ SEE ALSO ⭐

go read those too, they're iconic. πŸ“šβœ¨


and that's a wrap on the whole page bestie!! πŸŽ€βœ¨ this one came from the XFS corner of the world, dated 2017-12-01, and it lives as IOCTL-XFS-SCRUB-METADATA(2) in the manual. slay, ate, no crumbs left. πŸ’–πŸ‘‘πŸ¦‹

πŸ“¦ where this page comes from