DEBUGFS(8)

โœจ NAME โœจ

debugfs โ€” the ext2/ext3/ext4 file system debugger ๐Ÿ’…


๐ŸŽ€ SYNOPSIS ๐ŸŽ€

debugfs [ -DVwcin ] [ -b blocksize ] [ -s superblock ] [ -f cmd_file ] [
-R request ] [ -d data_source_device ] [ -z undo_file ] [ device ]

๐Ÿฆ‹ DESCRIPTION ๐Ÿฆ‹

okay so bestie, debugfs is an interactive file system debugger. That's the whole vibe. You use it to examine and change the state of an ext2, ext3, or ext4 file system. It's giving surgeon energy, honestly. ๐Ÿฉบโœจ

device is a block device (think /dev/sdXX) or a file that contains the file system. That's your entry point, no cap.


๐Ÿ’… OPTIONS ๐Ÿ’…

  • -w โ€” opens the file system in read-write mode. And if you don't pass this? It's read-only, periodt. No writey-writey unless you ask. ๐Ÿซถ
  • -n โ€” disables metadata checksum verification. Only do this if you genuinely believe the metadata is correct even though e2fsprogs is out here complaining about it. iykyk. ๐Ÿ’€
  • -c โ€” opens the file system in catastrophic mode, where the inode and group bitmaps are not read up front. Lowkey useful for file systems with significant corruption, but because of that, catastrophic mode forces the file system to be opened read-only. It's literally in the name bestie.
  • -i โ€” says that device represents an ext2 image file created by the e2image program. And here's the tea: since that ext2 image file only contains the superblock, block group descriptor, block and inode allocation bitmaps, and the inode table, many debugfs commands will not function properly. ๐Ÿšจ
Warning: no safety checks are in place, and debugfs may fail in interesting ways if commands such as ls, dump, etc. are tried without specifying the data_source_device using the -d option. debugfs is a debugging tool. It has rough edges! ๐Ÿ™ˆ
  • -d data_source_device โ€” used together with the -i option. Tells it that data_source_device should be used when reading blocks that aren't found in the ext2 image file. That includes data, directory, and indirect blocks. ๐Ÿงš
  • -b blocksize โ€” forces the use of the given block size (in bytes) for the file system, instead of detecting the correct block size automatically. (This option is rarely needed; it's used primarily when the file system is extremely badly damaged/corrupted. ๐Ÿ˜ญ)
  • -s superblock โ€” makes the file system superblock be read from the given block number, instead of using the primary superblock (which lives at an offset of 1024 bytes from the beginning of the file system). Heads up: if you specify -s, you must also provide the blocksize of the file system via the -b option. (Again, rarely needed; it's for when the file system is extremely badly damaged/corrupted. ๐Ÿฉน)
  • -f cmd_file โ€” makes debugfs read in commands from cmd_file and execute them. Once it's done executing those commands, it exits. Very scripted-queen of it. ๐Ÿ‘‘
  • -D โ€” makes debugfs open the device using Direct I/O, bypassing the buffer cache. Note that some Linux devices, notably device mapper as of this writing, do not support Direct I/O. ๐Ÿ’€
  • -R request โ€” makes debugfs execute the single command request, and then exit. One and done, main character energy. โœจ
  • -V โ€” prints the version number of debugfs and exits. Short and sweet. ๐ŸŽ€
  • -z undo_file โ€” before overwriting a file system block, writes the old contents of that block to an undo file. That undo file can be used with e2undo(8) to restore the old contents of the file system should something go wrong. If the empty string is passed as the undo_file argument, the undo file will be written to a file named debugfs-device.e2undo in the directory specified via the E2FSPROGS_UNDO_DIR environment variable. ๐ŸŒˆ
WARNING: The undo file cannot be used to recover from a power or system crash. Not even a little bit. ๐Ÿšซโšก

๐ŸŒธ SPECIFYING FILES ๐ŸŒธ

So many debugfs commands take a filespec as an argument to specify an inode (as opposed to a pathname) in the file system that debugfs currently has open. Obsessed with the precision, honestly.

The filespec argument can come in two forms:

  1. An inode number surrounded by angle brackets, e.g. <2>. ๐ŸŽฏ
  2. A pathname. If the pathname is prefixed by a forward slash (/), it's interpreted relative to the root of the file system currently opened by debugfs. If it's not prefixed, the pathname is interpreted relative to the current working directory as maintained by debugfs โ€” and you can change that using the debugfs command cd. ๐Ÿšถโ™€๏ธ๐Ÿ’จ

๐Ÿ’– COMMANDS ๐Ÿ’–

This is the list of the commands that debugfs supports. Buckle up bestie, there's a lot and they're all iconic in their own way. ๐Ÿซถ

blocks filespec

Print the blocks used by the inode filespec to stdout. ๐Ÿงพ

bmap [ -a ] filespec logical_block [physical_block]

Print or set the physical block number corresponding to the logical block number logical_block in the inode filespec. If the -a flag is specified, it tries to allocate a block if necessary. ๐Ÿ’…

block_dump '[ -x ] [-f filespec] block_num

Dump the file system block given by block_num in hex and ASCII format to the console. If the -f option is specified, the block number is relative to the start of the given filespec. If the -x option is specified, the block is interpreted as an extended attribute block and printed to show the structure of extended attribute data structures. ๐Ÿ”

cat filespec

Dump the contents of the inode filespec to stdout. Yes bestie, it's literally cat. ๐Ÿ˜ป

cd filespec

Change the current working directory to filespec. ๐Ÿšช

chroot filespec

Change the root directory to be the directory filespec. Root privilege but make it filesystem-y. ๐Ÿ‘‘

close [-a]

Close the currently open file system. If the -a option is specified, write out any changes to the superblock and block group descriptors to all of the backup superblocks, not just to the master superblock. ๐ŸŒˆ

clri filespec

Clear the contents of the inode filespec. Poof. ๐Ÿ’จ

copy_inode source_inode destination_inode

Copy the contents of the inode structure in source_inode and use it to overwrite the inode structure at destination_inode. Copy-paste but for inode structs, we love to see it. ๐Ÿ“‹

dirsearch filespec filename

Search the directory filespec for filename. ๐Ÿ”Ž

dirty [-clean]

Mark the file system as dirty, so that the superblocks will be written on exit. Additionally, clear the superblock's valid flag โ€” or set it, if -clean is specified. ๐Ÿงผ

dump [-p] filespec out_file

Dump the contents of the inode filespec to the output file out_file. If the -p option is given, set the owner, group and permissions information on out_file to match filespec. ๐Ÿ’พ

dump_mmp [mmp_block]

Display the multiple-mount protection (mmp) field values. If mmp_block is specified, verify and dump the MMP values from the given block number; otherwise use the s_mmp_block field in the superblock to locate and use the existing MMP block. ๐Ÿ›ก๏ธ

dx_hash [-cv] [-h hash_alg] [-s hash_seed] filename

Calculate the directory hash of filename. The -c option will casefold the filename before calculating the hash. The -v option will make the dx_hash command more verbose and print the hash algorithm and hash seed used to calculate the hash. If a file system is open, use the hash_seed and default hash_algorithm used by the file system โ€” although these can be overridden by the -h and -s options. The hash algorithm specified with -h may be legacy, half_md4, or tea. The hash seed specified with -s must be in UUID format. ๐Ÿ”ฅ

dump_extents [-n] [-l] filespec

Dump the extent tree of the inode filespec. The -n flag will cause dump_extents to only display the interior nodes in the extent tree. The -l flag will cause dump_extents to only display the leaf nodes in the extent tree. ๐ŸŒณ

(Please note that the length and range of blocks for the last extent in an interior node is an estimate by the extents library functions, and is not stored in file system data structures. Hence, the values displayed may not necessarily be accurate and does not indicate a problem or corruption in the file system. So don't panic bestie. ๐Ÿ˜Œ)

dump_unused

Dump unused blocks which contain non-null bytes. The leftovers, the crumbs, the forgotten ones. ๐Ÿž

ea_get [-f outfile]|[-xVC] [-r] filespec attr_name

Retrieve the value of the extended attribute attr_name in the file filespec and write it either to stdout or to outfile. ๐Ÿ“ค

ea_list filespec

List the extended attributes associated with the file filespec to standard output. ๐Ÿ“œ

ea_set [-f infile] [-r] filespec attr_name attr_value

Set the value of the extended attribute attr_name in the file filespec to the string value attr_value, or read it from infile. โœ๏ธ

ea_rm filespec attr_names...

Remove the extended attribute attr_name from the file filespec. Bye bestie. ๐Ÿ‘‹

expand_dir filespec

Expand the directory filespec. ๐Ÿ“ˆ

fallocate filespec start_block [end_block]

Allocate and map uninitialized blocks into filespec between logical block start_block and end_block, inclusive. If end_block is not supplied, this function maps until it runs out of free disk blocks or the maximum file size is reached. Existing mappings are left alone โ€” no touching, no drama. ๐Ÿซถ

feature [fs_feature] [-fs_feature] ...

Set or clear various file system features in the superblock. After setting or clearing any file system features that were requested, print the current state of the file system feature set. ๐ŸŽ›๏ธ

filefrag [-dvr] filespec

Print the number of contiguous extents in filespec. If filespec is a directory and the -d option is not specified, filefrag will print the number of contiguous extents for each file in the directory. The -v option will cause filefrag to print a tabular listing of the contiguous extents in the file. The -r option will cause filefrag to do a recursive listing of the directory. ๐Ÿ—‚๏ธ

find_free_block [count [goal]]

Find the first count free blocks, starting from goal, and allocate it. Also available as ffb. ๐Ÿงฑ

find_free_inode [dir [mode]]

Find a free inode and allocate it. If present, dir specifies the inode number of the directory in which the inode is to be located. The second optional argument mode specifies the permissions of the new inode. (If the directory bit is set on the mode, the allocation routine will function differently.) Also available as ffi. ๐Ÿ†”

freeb block [count]

Mark the block number block as not allocated. If the optional argument count is present, then count blocks starting at block number block will be marked as not allocated. Freed and thriving. ๐Ÿ’…

freefrag โ€” freefrag [-c chunk_kb]

okay so this one is literally the fragmentation vibe check for the file system you've currently got open ๐Ÿซถ. Add the -c option and the filefrag command will tell you how many free chunks of size chunk_kb it can find in the file system. Two rules tho, no cap: the chunk size has to be a power of two, and it has to be bigger than the file system block size. ๐Ÿ’…


freei โ€” freei filespec [num]

frees the inode that filespec is pointing at ๐Ÿฆ‹. And if you also hand it a num, it'll clear num-1 inodes right after that specified inode too. bye bestie โœจ


get_quota โ€” get_quota quota_type id

shows you the quota info for the quota type you asked for โ€” that's user, group, or project โ€” plus the matching ID. that's it, that's the whole thing ๐Ÿ’œ


help

prints the list of commands that debugfs actually understands ๐Ÿ“œ. your little cheat sheet, periodt.


htree_dump โ€” htree_dump filespec

dumps the hash-indexed directory filespec and shows you its whole tree structure ๐ŸŒณ. very "let me show you the family tree" energy.


icheck โ€” icheck block ...

give it one or more blocks on the command line and it prints a listing of the inodes that use them ๐Ÿ‘‘.


inode_dump โ€” inode_dump [-b]|[-e]|[-x] filespec

prints the contents of the inode data structure in hex and ASCII ๐Ÿ”ฅ. the flags, listen up:

  • -b โ€” only dumps the contents of the i_blocks array.
  • -e โ€” only dumps the contents of the extra inode space, which is where in-line extended attributes live.
  • -x โ€” dumps the extra inode space interpreted as extended attributes.

and like, this whole command is genuinely useful for debugging corrupted inodes that are carrying extended attributes around. ๐Ÿ’€


imap โ€” imap filespec

prints the location of the inode data structure (like, in the inode table) for the inode filespec ๐Ÿ“.


init_filesys โ€” init_filesys device blocksize

creates an ext2 file system on device with device size blocksize ๐ŸŒˆ.

heads up bestie: this does NOT fully initialize all of the data structures. if you want the full thing done properly, use the mke2fs(8) program. this is literally just a call to the low-level library that sets up the superblock and the block descriptors. that's all it does, no more. ๐Ÿ™ˆ

journal_close

closes the open journal. doors closed, lights off, bye ๐Ÿ’…


journal_open โ€” journal_open [-c] [-v ver] [-f ext_jnl]

opens the journal for reading and writing โœจ. you can turn on journal checksumming by supplying -c, and checksum formats 2 and 3 get selected with the -v option. an external journal can be loaded from ext_jnl via -f ๐ŸŽ€.


journal_run

replays all the transactions in the open journal ๐Ÿ”. it's giving "rewind and re-run".


journal_write โ€” journal_write [-b blocks] [-r revoke] [-c] file

writes a transaction to the open journal โœ๏ธ. the list of blocks to write should come in as a comma-separated list in blocks, and the blocks themselves should be readable from file. you can also hand over a list of blocks to revoke as a comma-separated list in revoke. by default a commit record gets written at the end โ€” but the -c switch makes it write an uncommitted transaction instead ๐Ÿ‘€.


kill_file โ€” kill_file filespec

deallocates the inode filespec and all its blocks ๐Ÿ’€.

ngl this one does NOT remove any directory entries (if there even are any) pointing at this inode. if your goal is to actually unlink a file, go look at the rm(1) command instead.

lcd โ€” lcd directory

changes the current working directory of the debugfs process itself to directory on the native file system ๐Ÿงš. yes, it's lcd โ€” the "local" one, not the file-system-inside one, iykyk.


list_quota โ€” list_quota quota_type

displays the quota information for the given quota type โ€” again, that's user, group, or project ๐ŸŒธ.


ln โ€” ln filespec dest_file

creates a link named dest_file that's a hard link to filespec ๐Ÿ”—.

real talk: this does NOT adjust the inode reference counts. noted, and now you know. ๐Ÿ’…

logdump โ€” logdump [-acsOS] [-b block] [-n num_trans ] [-i filespec] [-f journal_file] [output_file]

dumps the contents of the ext3 journal ๐Ÿ““. by default it dumps the journal inode exactly as specified in the superblock. but you can override that with -i, which dumps the journal from the internal inode given by filespec. a regular file containing journal data can be specified with -f. and finally, the -s option uses the backup information sitting in the superblock to locate the journal. okay now the rest of the flags, one by one:

  • -S โ€” causes logdump to print the contents of the journal superblock.
  • -a โ€” causes logdump to print the contents of all of the descriptor blocks.
  • -b โ€” causes logdump to print all journal records that refer to the specified block.
  • -c โ€” prints out the contents of all of the data blocks selected by the -a and -b options.
  • -O โ€” causes logdump to display old (checkpointed) journal entries ๐Ÿ‘‘. this one's for trying to track down journal problems even after the journal has been replayed.
  • -n โ€” causes logdump to continue past a journal block that's missing a magic number ๐Ÿ˜ญ. instead, it'll stop only when the entire log is printed, or after num_trans transactions.

ls โ€” ls [-l] [-c] [-d] [-p] [-r] filespec

prints a listing of the files in the directory filespec ๐Ÿ“‚. the flags do this:

  • -c โ€” causes directory block checksums (if present) to be displayed.
  • -d โ€” lists deleted entries in the directory ๐Ÿ’€.
  • -l โ€” lists files using a more verbose format.
  • -p โ€” lists the files in a format that's way more easily parsable by scripts, and it also makes it more clear when there are spaces or other non-printing characters hanging out at the end of filenames.
  • -r โ€” forces the printing of the filename, even if it's encrypted ๐Ÿ”.

list_deleted_inodes โ€” list_deleted_inodes [limit]

lists deleted inodes, optionally limited to those that got deleted within limit seconds ago โณ. also available as lsdel โœจ.

so back in the day this command was useful for recovering from accidental file deletions on ext2 file systems. unfortunately it's not useful for that purpose if the files were deleted using ext3 or ext4, because the inode's data blocks are just... no longer available once the inode is released. sorry bestie ๐Ÿ˜ญ

modify_inode โ€” modify_inode filespec

modifies the contents of the inode structure in the inode filespec โœ๏ธ. also available as mi ๐ŸŽ€.


mkdir โ€” mkdir filespec

makes a directory. that's the tweet ๐Ÿฆ‹.


mknod โ€” mknod filespec [p|[[c|b] major minor]]

creates a special device file โ€” a named pipe, or a character or block device ๐Ÿ’…. and if it's a character or block device you're making, then the major and minor device numbers must be specified. no skipping that part.


ncheck โ€” ncheck [-c] inode_num ...

takes the list of inode numbers you give it and prints a listing of the pathnames pointing to those inodes ๐Ÿ›ค๏ธ. the -c flag enables checking the file type information in the directory entry, to make sure it matches the inode's type โœ….


open โ€” open [-weficD] [-b blocksize] [-d image_filename] [-s superblock] [-z undo_file] device

opens a file system for editing ๐Ÿ”“. the flags:

  • -f โ€” forces the file system to be opened even if there are some unknown or incompatible file system features that would normally stop it from being opened ๐Ÿšจ.
  • -e โ€” causes the file system to be opened in exclusive mode.
  • -b, -c, -d, -i, -s, -w, and -D โ€” these behave exactly the same as the command-line options to debugfs.

orphan_inodes

lists the orphan inodes in the file system ๐Ÿฅบ. they're just little guys with no home.


punch โ€” punch filespec start_blk [end_blk]

deletes the blocks in the inode ranging from start_blk to end_blk ๐Ÿ•ณ๏ธ. and if you leave off end_blk, then this command functions as a truncate command โ€” meaning all of the blocks starting at start_blk through to the end of the file get deallocated. โœ‚๏ธ


makes a symbolic link ๐ŸŽ€.


pwd

prints the current working directory ๐Ÿ“.


quit

quits debugfs. exit stage left, you ate ๐Ÿ‘‘.


rdump โ€” rdump directory[...] destination

recursively dumps directory, or multiple directories, plus all their contents (regular files, symbolic links, and other directories too) into the named destination ๐Ÿ“ฆ. and heads up: destination should be an existing directory on the native file system.


rm โ€” rm pathname

unlinks pathname ๐Ÿ”ช. if that causes the inode pointed to by pathname to have no other references, then it deallocates the file. this command functions as the unlink() system call, fr fr.


rmdir โ€” rmdir filespec

removes the directory filespec ๐Ÿ—‘๏ธ.


setb โ€” setb block [count]

marks the block number block as allocated โœ…. if the optional argument count is present, then count blocks starting at block number block get marked as allocated too.


set_block_group โ€” set_block_group bgnum field value

modifies the block group descriptor specified by bgnum so that the block group descriptor field field has value value ๐Ÿ’…. also available as set_bg โœจ.


set_current_time โ€” set_current_time time

sets the current time, in seconds since the Unix epoch, to use whenever it's setting file system fields ๐Ÿ•ฐ๏ธ. time travel but make it filesystem.


seti โ€” seti filespec [num]

marks inode filespec as in use in the inode bitmap ๐Ÿ’–. and if num is specified, it also sets num-1 inodes after the specified inode.


set_inode_field โ€” set_inode_field filespec field value

modifies the inode specified by filespec so that the inode field field has value value ๐Ÿ› ๏ธ. and you can see the whole list of valid inode fields that can be set with this command by running:

set_inode_field -l

also available as sif ๐ŸŽ€.


set_mmp_value โ€” set_mmp_value field value

modifies the multiple-mount protection (MMP) data so that the MMP field field has value value ๐Ÿ”ฅ. the list of valid MMP fields you can set with this command? display it with:

set_mmp_value -l

also available as smmp โœจ.


set_super_value โ€” set_super_value field value

sets the superblock field field to value ๐Ÿ‘‘. to see the list of valid superblock fields you can set with this command, run:

set_super_value -l

also available as ssv ๐Ÿ’œ.


show_debugfs_params

displays debugfs parameters, like information about the file system that's currently opened ๐ŸŒˆ.


show_super_stats โ€” show_super_stats [-h]

lists the contents of the super block and the block group descriptors ๐Ÿ“‹. if you give it the -h flag, it only prints out the superblock contents. also available as stats ๐Ÿฆ‹.


stat โ€” stat filespec

displays the contents of the inode structure of the inode filespec ๐Ÿ‘€.


supported_features

displays the file system features supported by this version of debugfs โญ. a little resume, if you will.


testb โ€” testb block [count]

tests whether the block number block is marked as allocated in the block bitmap ๐Ÿง. if the optional argument count is present, then count blocks starting at block number block get tested.


testi โ€” testi filespec

tests whether the inode filespec is marked as allocated in the inode bitmap โœ….

undel โ€” bringing deleted files back from the void ๐ŸงŸโ€โ™€๏ธโœจ

  • undel <inode_number> [pathname] โ€” un-deletes the inode you name, and yeah, it has to be wrapped in angle brackets like <12> or it won't vibe. Once it's back, the inode and all its blocks get marked as in use again, and if you also hand over a pathname, it'll link the recovered inode there for you. ๐Ÿซถ
bestie listen. Always run e2fsck after using undel to recover deleted files. Always. Not optional, not "maybe later". Always. ๐Ÿ’€

Also, real talk: if you're recovering a large number of deleted files, linking an inode to a directory might force that directory to be expanded, and that expansion could allocate a block that one of your yet-to-be-undeleted files was still using. Messy!! So the safer glow-up is:

  1. Undelete all the inodes without specifying a destination pathname.
  2. Then, in a separate pass, either use the debugfs link command to link the inode to the destination pathname, or use e2fsck to check the file system and link all of the recovered inodes to the lost+found directory.

Two passes, zero regrets, that's the move. ๐Ÿ’…


  • unlink pathname โ€” removes the link specified by pathname to an inode. That's it, that's the whole job. Note: this does not adjust the inode reference counts, so don't come crying to unlink about refcounts, it's not that kind of command. ๐Ÿ™ˆ

write โ€” copy-paste but make it filesystem ๐Ÿฆ‹

  • write source_file out_file โ€” copies the contents of source_file into a newly-created file inside the file system, and that new file is named out_file. New file, fresh start, main character energy. โœจ

zap_block โ€” the block destroyer, two flavours ๐Ÿ”ฅ

Flavour one: overwrite it

  • zap_block [-f filespec] [-o offset] [-l length] [-p pattern]** block_num โ€” overwrites the block specified by block_num with zero (NUL) bytes. If -p is given, it uses the byte specified by pattern instead. If -f is given, then block_num is relative to the start of the file given by filespec. And the -o and -l options limit the range of bytes to zap to the specified offset and length relative to the start of the block. ๐ŸŽฏ

Flavour two: bit-flip it

  • zap_block [-f filespec] [-b bit]** block_num โ€” bit-flips portions of the physical block_num. If -f is given, then block_num is a logical block relative to the start of filespec. ๐ŸŒ€
This one literally rewrites blocks. Be so fr before you type it. ๐Ÿ˜ญ

๐ŸŒˆ ENVIRONMENT VARIABLES ๐ŸŒˆ

  • DEBUGFS_PAGER, PAGER โ€” debugfs always pipes the output of some commands through a pager program. The commands in question are:
    • show_super_stats (aka stats)
    • list_directory (aka ls)
    • show_inode_info (aka stat)
    • list_deleted_inodes (aka lsdel)
    • htree_dump

The specific pager can be explicitly specified by the DEBUGFS_PAGER environment variable, and if that one isn't set, then by the PAGER environment variable. ๐ŸŽ€

Heads up: because a pager is always used, the less(1) pager is not particularly appropriate, since it clears the screen before displaying the output of the command, and clears the output of the screen when the pager is exited. ๐Ÿ˜ฌ

Many users prefer to use the less(1) pager for most purposes โ€” which is literally why the DEBUGFS_PAGER environment variable exists, so you can override the more general PAGER environment variable. iykyk. ๐Ÿ’–


๐Ÿ‘‘ AUTHOR ๐Ÿ‘‘

debugfs was written by Theodore Ts'o <tytso@mit.edu>. Legend behaviour, honestly. ๐Ÿซก


๐ŸŒธ SEE ALSO ๐ŸŒธ


And that's a wrap on the whole page, bestie!! ๐ŸŽ‰ This one's from E2fsprogs version 1.47.4, dated March 2025, and it's the DEBUGFS(8) manual page โ€” go forth and debug your file systems responsibly. Slay, stay safe, and back up your data before you zap_block anything. ๐Ÿ’…๐Ÿ’–โœจ

๐Ÿ“ฆ where this page comes from