[GNU Manual] [POSIX requirement] [Linux man] [FreeBSD man]
Summary
df - report file system disk space usage
Lines of code: 1819
Principal syscall: stat(), statvfs()
Support syscalls: fstatat()
Options: 30 (14 short, 16 long)
Descended from df introduced in Version 1 UNIX (1971)
Added to Fileutils in October 1992 [First version]
Number of revisions: 298
Two general strategies are to ask the filesystem for accounting metadata or check every file and estimate. The df utility uses the former strategy via sysfs()
/sysvfs()
. Check out the du utility for the other strategy
add_excluded_fs_type()
- Removes a filesystem from processingadd_fs_type()
- Adds a file system to be processedadd_uint_with_neg_flag()
- Handles signs for uint types as a distinct flagadd_to_grand_total()
- Fully summarizes usagealloc_field()
- Allocates space for a fieldalloc_table_row()
- Allocates a row for the output tabledecode_output_arg()
- Parse the output arguments for the eventual displaydevlist_compare()
- Comparison function for devicesdevlist_for_dev()
- Locate a device within the device tabledevlist_free()
- Free the devlice listdevlist_hash()
- Index function for the device listdf_readable()
- Human-readable display with distinct negative flagexcluded_fstype()
- Checks if a filesystem type is excludedfilter_mount_list()
- Removes duplicates, ensuring distinct mount list entriesget_all_entries()
- Constructs a list of all distinct mount entriesget_dev()
- Creates an output listing for a given deviceget_disk()
- Display usage for a single mount pointget_entry()
- Verifies device request and preparesstat()
get_field_list()
- Prepares the table columnsget_field_values()
- Gathers block/inode valuesget_header()
- Builds the appropriate headerget_point()
-stat()
the device at the given mount pointhas_uuid_suffix()
- True if the input is a UUIDhide_problematic_chars()
- Convert control characters to '?'last_device_for_mount()
- Returns a string for the last device mountedme_for_dev()
- Finds a device in the mount entry listprint_table()
- Final output for dfselected_fstype()
- Returns true if the input is a displayed fs type
free_mount_entry()
- Removes a mount entryget_fs_usage()
- The workhorse function to get fs data for many systems (from gnulib)human_readable()
- Formats numeric data with meaningful suffixesread_file_system_list()
- Parses mounted filesystems at /proc/self/mountinfo
Setup
df defines a few global structs and variables prior to execution:
struct devlist
is a single-linked list of devices (number/mount point)struct fs_type_list
is a list of filesystem typesstruct field_values_t
holds the possible values of all fieldsstruct field_data_t
holds the attributes for a single field
The global variables are dedicated to the option flags and the data table to display, including:
show_all_fs
- Flag for all files systems (-a)show_local_fs
- Flag for only checking local filesystems (-l)show_listed_fs
- Flag to display only given filesystems (cli arguments)file_systems_processed
- Flag set if any file system was processed*fs_select_list
- The list of file systems explicitly requested*fs_exclude_list
- The list of file systems explicitly ignoredprint_type
- Flag to show the file system type (-T)print_grand_total
- Flag to show the usage grand total (--total)field_data[]
- The header for each column**columns
- The data for each column***table
- The values in each cell (*table -> *column -> *cell)
Also, several enum types are defined to facility options, which include the display mode, the field basis (block/inode/text), the actual field types, etc.
main() initializes all of the above to default values (or NULL pointers). Two more local variables are defined:
*msg_mut_excl
- Error message for mutually exclusive optionsposix_format
- Forces the posix output format (-p)
Parsing kicks off with the short options passed as a string literal:
"aB:iF:hHklmPTt:vx:"
Parsing
Parsing df asks a few questions from the user:
- What file systems and types are we interested in?
- What information (fields) of data do we want?
- What units do we want the answer in? (block/inodes?)
- Any special considerations for the display? (POSIX style?)
Parsing failures
Parsing may fail in several ways:
- A filesystem type is both selected and excluded
- Including the --output option with any of -i, -T, or -P
- Using output fields with inode, portability, and print-type options
User specified parsing failures result in a short error message followed by the usage instructions. Access related parsing errors die with an error message.
Execution
Executing the df utility follows this path:
stat()
any of the explicitly checked file systems- Build the list of currently mounted devices
- Construct the output table header and column structures
- Go through each mounted device and get file system data
- Construct the table entry
- Print the output table
Failure cases:
- No file systems are processed (nothing mounted or target not available)
- Unable to access file systems
All failures at this stage output an error message to STDERR and return without displaying usage help