1 /* df - summarize free disk space
2 Copyright (C) 1991-2015 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 /* Written by David MacKenzie <djm@gnu.ai.mit.edu>.
18 --human-readable and --megabyte options added by lm@sgi.com.
19 --si and large file support added by eggert@twinsun.com. */
23 #include <sys/types.h>
28 #include "canonicalize.h"
34 #include "mountlist.h"
36 #include "find-mount-point.h"
38 /* The official name of this program (e.g., no 'g' prefix). */
39 #define PROGRAM_NAME "df"
42 proper_name_utf8 ("Torbjorn Granlund", "Torbj\303\266rn Granlund"), \
43 proper_name ("David MacKenzie"), \
44 proper_name ("Paul Eggert")
46 /* Filled with device numbers of examined file systems to avoid
47 duplicates in output. */
51 struct mount_entry
*me
;
55 /* If true, show even file systems with zero size or
56 uninteresting types. */
57 static bool show_all_fs
;
59 /* If true, show only local file systems. */
60 static bool show_local_fs
;
62 /* If true, output data for each file system corresponding to a
63 command line argument -- even if it's a dummy (automounter) entry. */
64 static bool show_listed_fs
;
66 /* Human-readable options for output. */
67 static int human_output_opts
;
69 /* The units to use when printing sizes. */
70 static uintmax_t output_block_size
;
72 /* True if a file system has been processed for output. */
73 static bool file_systems_processed
;
75 /* If true, invoke the 'sync' system call before getting any usage data.
76 Using this option can make df very slow, especially with many or very
77 busy disks. Note that this may make a difference on some systems --
78 SunOS 4.1.3, for one. It is *not* necessary on GNU/Linux. */
79 static bool require_sync
;
81 /* Desired exit status. */
82 static int exit_status
;
84 /* A file system type to display. */
89 struct fs_type_list
*fs_next
;
92 /* Linked list of file system types to display.
93 If 'fs_select_list' is NULL, list all types.
94 This table is generated dynamically from command-line options,
95 rather than hardcoding into the program what it thinks are the
96 valid file system types; let the user specify any file system type
97 they want to, and if there are any file systems of that type, they
100 Some file system types:
101 4.2 4.3 ufs nfs swap ignore io vm efs dbg */
103 static struct fs_type_list
*fs_select_list
;
105 /* Linked list of file system types to omit.
106 If the list is empty, don't exclude any types. */
108 static struct fs_type_list
*fs_exclude_list
;
110 /* Linked list of mounted file systems. */
111 static struct mount_entry
*mount_list
;
113 /* If true, print file system type as well. */
114 static bool print_type
;
116 /* If true, print a grand total at the end. */
117 static bool print_grand_total
;
119 /* Grand total data. */
120 static struct fs_usage grand_fsu
;
131 static int header_mode
= DEFAULT_MODE
;
133 /* Displayable fields. */
136 SOURCE_FIELD
, /* file system */
137 FSTYPE_FIELD
, /* FS type */
138 SIZE_FIELD
, /* FS size */
139 USED_FIELD
, /* FS size used */
140 AVAIL_FIELD
, /* FS size available */
141 PCENT_FIELD
, /* percent used */
142 ITOTAL_FIELD
, /* inode total */
143 IUSED_FIELD
, /* inodes used */
144 IAVAIL_FIELD
, /* inodes available */
145 IPCENT_FIELD
, /* inodes used in percent */
146 TARGET_FIELD
, /* mount point */
147 FILE_FIELD
, /* specified file name */
148 INVALID_FIELD
/* validation marker */
151 /* Flag if a field contains a block, an inode or another value. */
154 BLOCK_FLD
, /* Block values field */
155 INODE_FLD
, /* Inode values field */
156 OTHER_FLD
/* Neutral field, e.g. target */
159 /* Attributes of a display field. */
162 display_field_t field
;
164 field_type_t field_type
;
165 const char *caption
;/* NULL means to use the default header of this field. */
166 size_t width
; /* Auto adjusted (up) widths used to align columns. */
167 mbs_align_t align
; /* Alignment for this field. */
171 /* Header strings, minimum width and alignment for the above fields. */
172 static struct field_data_t field_data
[] = {
173 [SOURCE_FIELD
] = { SOURCE_FIELD
,
174 "source", OTHER_FLD
, N_("Filesystem"), 14, MBS_ALIGN_LEFT
, false },
176 [FSTYPE_FIELD
] = { FSTYPE_FIELD
,
177 "fstype", OTHER_FLD
, N_("Type"), 4, MBS_ALIGN_LEFT
, false },
179 [SIZE_FIELD
] = { SIZE_FIELD
,
180 "size", BLOCK_FLD
, N_("blocks"), 5, MBS_ALIGN_RIGHT
, false },
182 [USED_FIELD
] = { USED_FIELD
,
183 "used", BLOCK_FLD
, N_("Used"), 5, MBS_ALIGN_RIGHT
, false },
185 [AVAIL_FIELD
] = { AVAIL_FIELD
,
186 "avail", BLOCK_FLD
, N_("Available"), 5, MBS_ALIGN_RIGHT
, false },
188 [PCENT_FIELD
] = { PCENT_FIELD
,
189 "pcent", BLOCK_FLD
, N_("Use%"), 4, MBS_ALIGN_RIGHT
, false },
191 [ITOTAL_FIELD
] = { ITOTAL_FIELD
,
192 "itotal", INODE_FLD
, N_("Inodes"), 5, MBS_ALIGN_RIGHT
, false },
194 [IUSED_FIELD
] = { IUSED_FIELD
,
195 "iused", INODE_FLD
, N_("IUsed"), 5, MBS_ALIGN_RIGHT
, false },
197 [IAVAIL_FIELD
] = { IAVAIL_FIELD
,
198 "iavail", INODE_FLD
, N_("IFree"), 5, MBS_ALIGN_RIGHT
, false },
200 [IPCENT_FIELD
] = { IPCENT_FIELD
,
201 "ipcent", INODE_FLD
, N_("IUse%"), 4, MBS_ALIGN_RIGHT
, false },
203 [TARGET_FIELD
] = { TARGET_FIELD
,
204 "target", OTHER_FLD
, N_("Mounted on"), 0, MBS_ALIGN_LEFT
, false },
206 [FILE_FIELD
] = { FILE_FIELD
,
207 "file", OTHER_FLD
, N_("File"), 0, MBS_ALIGN_LEFT
, false }
210 static char const *all_args_string
=
211 "source,fstype,itotal,iused,iavail,ipcent,size,"
212 "used,avail,pcent,file,target";
214 /* Storage for the definition of output columns. */
215 static struct field_data_t
**columns
;
217 /* The current number of output columns. */
218 static size_t ncolumns
;
221 struct field_values_t
223 uintmax_t input_units
;
224 uintmax_t output_units
;
227 bool negate_available
;
228 uintmax_t available_to_root
;
233 /* Storage for pointers for each string (cell of table). */
234 static char ***table
;
236 /* The current number of processed rows (including header). */
239 /* For long options that have no equivalent short option, use a
240 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
243 NO_SYNC_OPTION
= CHAR_MAX
+ 1,
249 static struct option
const long_options
[] =
251 {"all", no_argument
, NULL
, 'a'},
252 {"block-size", required_argument
, NULL
, 'B'},
253 {"inodes", no_argument
, NULL
, 'i'},
254 {"human-readable", no_argument
, NULL
, 'h'},
255 {"si", no_argument
, NULL
, 'H'},
256 {"local", no_argument
, NULL
, 'l'},
257 {"output", optional_argument
, NULL
, OUTPUT_OPTION
},
258 {"portability", no_argument
, NULL
, 'P'},
259 {"print-type", no_argument
, NULL
, 'T'},
260 {"sync", no_argument
, NULL
, SYNC_OPTION
},
261 {"no-sync", no_argument
, NULL
, NO_SYNC_OPTION
},
262 {"total", no_argument
, NULL
, TOTAL_OPTION
},
263 {"type", required_argument
, NULL
, 't'},
264 {"exclude-type", required_argument
, NULL
, 'x'},
265 {GETOPT_HELP_OPTION_DECL
},
266 {GETOPT_VERSION_OPTION_DECL
},
270 /* Replace problematic chars with '?'.
271 Since only control characters are currently considered,
272 this should work in all encodings. */
275 hide_problematic_chars (char *cell
)
280 if (iscntrl (to_uchar (*p
)))
287 /* Dynamically allocate a row of pointers in TABLE, which
288 can then be accessed with standard 2D array notation. */
291 alloc_table_row (void)
294 table
= xnrealloc (table
, nrows
, sizeof (char **));
295 table
[nrows
- 1] = xnmalloc (ncolumns
, sizeof (char *));
298 /* Output each cell in the table, accounting for the
299 alignment and max width of each column. */
306 for (row
= 0; row
< nrows
; row
++)
309 for (col
= 0; col
< ncolumns
; col
++)
311 char *cell
= table
[row
][col
];
313 /* Note the SOURCE_FIELD used to be displayed on it's own line
314 if (!posix_format && mbswidth (cell) > 20), but that
315 functionality was probably more problematic than helpful,
316 hence changed in commit v8.10-40-g99679ff. */
321 if (col
== ncolumns
- 1) /* The last one. */
322 flags
= MBA_NO_RIGHT_PAD
;
324 size_t width
= columns
[col
]->width
;
325 cell
= ambsalign (cell
, &width
, columns
[col
]->align
, flags
);
326 /* When ambsalign fails, output unaligned data. */
327 fputs (cell
? cell
: table
[row
][col
], stdout
);
330 IF_LINT (free (table
[row
][col
]));
333 IF_LINT (free (table
[row
]));
336 IF_LINT (free (table
));
339 /* Dynamically allocate a struct field_t in COLUMNS, which
340 can then be accessed with standard array notation. */
343 alloc_field (int f
, const char *c
)
346 columns
= xnrealloc (columns
, ncolumns
, sizeof (struct field_data_t
*));
347 columns
[ncolumns
- 1] = &field_data
[f
];
349 columns
[ncolumns
- 1]->caption
= c
;
351 if (field_data
[f
].used
)
352 assert (!"field used");
354 /* Mark field as used. */
355 field_data
[f
].used
= true;
359 /* Given a string, ARG, containing a comma-separated list of arguments
360 to the --output option, add the appropriate fields to columns. */
362 decode_output_arg (char const *arg
)
364 char *arg_writable
= xstrdup (arg
);
365 char *s
= arg_writable
;
368 /* find next comma */
369 char *comma
= strchr (s
, ',');
371 /* If we found a comma, put a NUL in its place and advance. */
376 display_field_t field
= INVALID_FIELD
;
377 for (unsigned int i
= 0; i
< ARRAY_CARDINALITY (field_data
); i
++)
379 if (STREQ (field_data
[i
].arg
, s
))
385 if (field
== INVALID_FIELD
)
387 error (0, 0, _("option --output: field %s unknown"), quote (s
));
388 usage (EXIT_FAILURE
);
391 if (field_data
[field
].used
)
393 /* Prevent the fields from being used more than once. */
394 error (0, 0, _("option --output: field %s used more than once"),
395 quote (field_data
[field
].arg
));
396 usage (EXIT_FAILURE
);
411 alloc_field (field
, NULL
);
415 alloc_field (field
, N_("Size"));
419 alloc_field (field
, N_("Avail"));
423 assert (!"invalid field");
432 /* Get the appropriate columns for the mode. */
434 get_field_list (void)
439 alloc_field (SOURCE_FIELD
, NULL
);
441 alloc_field (FSTYPE_FIELD
, NULL
);
442 alloc_field (SIZE_FIELD
, NULL
);
443 alloc_field (USED_FIELD
, NULL
);
444 alloc_field (AVAIL_FIELD
, NULL
);
445 alloc_field (PCENT_FIELD
, NULL
);
446 alloc_field (TARGET_FIELD
, NULL
);
450 alloc_field (SOURCE_FIELD
, NULL
);
452 alloc_field (FSTYPE_FIELD
, NULL
);
454 alloc_field (SIZE_FIELD
, N_("Size"));
455 alloc_field (USED_FIELD
, NULL
);
456 alloc_field (AVAIL_FIELD
, N_("Avail"));
457 alloc_field (PCENT_FIELD
, NULL
);
458 alloc_field (TARGET_FIELD
, NULL
);
462 alloc_field (SOURCE_FIELD
, NULL
);
464 alloc_field (FSTYPE_FIELD
, NULL
);
465 alloc_field (ITOTAL_FIELD
, NULL
);
466 alloc_field (IUSED_FIELD
, NULL
);
467 alloc_field (IAVAIL_FIELD
, NULL
);
468 alloc_field (IPCENT_FIELD
, NULL
);
469 alloc_field (TARGET_FIELD
, NULL
);
473 alloc_field (SOURCE_FIELD
, NULL
);
475 alloc_field (FSTYPE_FIELD
, NULL
);
476 alloc_field (SIZE_FIELD
, NULL
);
477 alloc_field (USED_FIELD
, NULL
);
478 alloc_field (AVAIL_FIELD
, NULL
);
479 alloc_field (PCENT_FIELD
, N_("Capacity"));
480 alloc_field (TARGET_FIELD
, NULL
);
486 /* Add all fields if --output was given without a field list. */
487 decode_output_arg (all_args_string
);
492 assert (!"invalid header_mode");
496 /* Obtain the appropriate header entries. */
505 for (col
= 0; col
< ncolumns
; col
++)
508 char const *header
= _(columns
[col
]->caption
);
510 if (columns
[col
]->field
== SIZE_FIELD
511 && (header_mode
== DEFAULT_MODE
512 || (header_mode
== OUTPUT_MODE
513 && !(human_output_opts
& human_autoscale
))))
515 char buf
[LONGEST_HUMAN_READABLE
+ 1];
517 int opts
= (human_suppress_point_zero
518 | human_autoscale
| human_SI
520 & (human_group_digits
| human_base_1024
| human_B
)));
522 /* Prefer the base that makes the human-readable value more exact,
523 if there is a difference. */
525 uintmax_t q1000
= output_block_size
;
526 uintmax_t q1024
= output_block_size
;
527 bool divisible_by_1000
;
528 bool divisible_by_1024
;
532 divisible_by_1000
= q1000
% 1000 == 0; q1000
/= 1000;
533 divisible_by_1024
= q1024
% 1024 == 0; q1024
/= 1024;
535 while (divisible_by_1000
& divisible_by_1024
);
537 if (divisible_by_1000
< divisible_by_1024
)
538 opts
|= human_base_1024
;
539 if (divisible_by_1024
< divisible_by_1000
)
540 opts
&= ~human_base_1024
;
541 if (! (opts
& human_base_1024
))
544 char *num
= human_readable (output_block_size
, buf
, opts
, 1, 1);
546 /* Reset the header back to the default in OUTPUT_MODE. */
547 header
= _("blocks");
549 /* TRANSLATORS: this is the "1K-blocks" header in "df" output. */
550 if (asprintf (&cell
, _("%s-%s"), num
, header
) == -1)
553 else if (header_mode
== POSIX_MODE
&& columns
[col
]->field
== SIZE_FIELD
)
555 char buf
[INT_BUFSIZE_BOUND (uintmax_t)];
556 char *num
= umaxtostr (output_block_size
, buf
);
558 /* TRANSLATORS: this is the "1024-blocks" header in "df -P". */
559 if (asprintf (&cell
, _("%s-%s"), num
, header
) == -1)
563 cell
= strdup (header
);
568 hide_problematic_chars (cell
);
570 table
[nrows
- 1][col
] = cell
;
572 columns
[col
]->width
= MAX (columns
[col
]->width
, mbswidth (cell
, 0));
576 /* Is FSTYPE a type of file system that should be listed? */
578 static bool _GL_ATTRIBUTE_PURE
579 selected_fstype (const char *fstype
)
581 const struct fs_type_list
*fsp
;
583 if (fs_select_list
== NULL
|| fstype
== NULL
)
585 for (fsp
= fs_select_list
; fsp
; fsp
= fsp
->fs_next
)
586 if (STREQ (fstype
, fsp
->fs_name
))
591 /* Is FSTYPE a type of file system that should be omitted? */
593 static bool _GL_ATTRIBUTE_PURE
594 excluded_fstype (const char *fstype
)
596 const struct fs_type_list
*fsp
;
598 if (fs_exclude_list
== NULL
|| fstype
== NULL
)
600 for (fsp
= fs_exclude_list
; fsp
; fsp
= fsp
->fs_next
)
601 if (STREQ (fstype
, fsp
->fs_name
))
606 /* Filter mount list by skipping duplicate entries.
607 In the case of duplicates - based on the device number - the mount entry
608 with a '/' in its me_devname (i.e., not pseudo name like tmpfs) wins.
609 If both have a real devname (e.g. bind mounts), then that with the shorter
610 me_mountdir wins. With DEVICES_ONLY == true (set with df -a), only update
611 the global device_list, rather than filtering the global mount_list. */
614 filter_mount_list (bool devices_only
)
616 struct mount_entry
*me
;
618 /* Sort all 'wanted' entries into the list device_list. */
619 for (me
= mount_list
; me
;)
622 struct devlist
*devlist
;
623 struct mount_entry
*discard_me
= NULL
;
625 /* Avoid stating remote file systems as that may hang.
626 On Linux we probably have me_dev populated from /proc/self/mountinfo,
627 however we still stat() in case another device was mounted later. */
628 if ((me
->me_remote
&& show_local_fs
)
629 || -1 == stat (me
->me_mountdir
, &buf
))
631 /* If remote, and showing just local, add ME for filtering later.
632 If stat failed; add ME to be able to complain about it later. */
633 buf
.st_dev
= me
->me_dev
;
637 /* If we've already seen this device... */
638 for (devlist
= device_list
; devlist
; devlist
= devlist
->next
)
639 if (devlist
->dev_num
== buf
.st_dev
)
644 bool target_nearer_root
= strlen (devlist
->me
->me_mountdir
)
645 > strlen (me
->me_mountdir
);
646 /* With bind mounts, prefer items nearer the root of the source */
647 bool source_below_root
= devlist
->me
->me_mntroot
!= NULL
648 && me
->me_mntroot
!= NULL
649 && (strlen (devlist
->me
->me_mntroot
)
650 < strlen (me
->me_mntroot
));
651 if (! print_grand_total
&& me
->me_remote
&& devlist
->me
->me_remote
652 && ! STREQ (devlist
->me
->me_devname
, me
->me_devname
))
654 /* Don't discard remote entries with different locations,
655 as these are more likely to be explicitly mounted.
656 However avoid this when producing a total to give
657 a more accurate value in that case. */
659 else if ((strchr (me
->me_devname
, '/')
660 /* let "real" devices with '/' in the name win. */
661 && ! strchr (devlist
->me
->me_devname
, '/'))
662 /* let points towards the root of the device win. */
663 || (target_nearer_root
&& ! source_below_root
)
664 /* let an entry overmounted on a new device win... */
665 || (! STREQ (devlist
->me
->me_devname
, me
->me_devname
)
666 /* ... but only when matching an existing mnt point,
667 to avoid problematic replacement when given
668 inaccurate mount lists, seen with some chroot
669 environments for example. */
670 && STREQ (me
->me_mountdir
,
671 devlist
->me
->me_mountdir
)))
673 /* Discard mount entry for existing device. */
674 discard_me
= devlist
->me
;
679 /* Discard mount entry currently being processed. */
690 free_mount_entry (discard_me
);
694 /* Add the device number to the global list devlist. */
695 devlist
= xmalloc (sizeof *devlist
);
697 devlist
->dev_num
= buf
.st_dev
;
698 devlist
->next
= device_list
;
699 device_list
= devlist
;
705 /* Finally rebuild the mount_list from the devlist. */
706 if (! devices_only
) {
710 /* Add the mount entry. */
711 me
= device_list
->me
;
712 me
->me_next
= mount_list
;
714 /* Free devlist entry and advance. */
715 struct devlist
*devlist
= device_list
->next
;
717 device_list
= devlist
;
722 /* Search a mount entry list for device id DEV.
723 Return the corresponding mount entry if found or NULL if not. */
725 static struct mount_entry
const * _GL_ATTRIBUTE_PURE
726 me_for_dev (dev_t dev
)
728 struct devlist
*dl
= device_list
;
732 if (dl
->dev_num
== dev
)
740 /* Return true if N is a known integer value. On many file systems,
741 UINTMAX_MAX represents an unknown value; on AIX, UINTMAX_MAX - 1
742 represents unknown. Use a rule that works on AIX file systems, and
743 that almost-always works on other types. */
745 known_value (uintmax_t n
)
747 return n
< UINTMAX_MAX
- 1;
750 /* Like human_readable (N, BUF, human_output_opts, INPUT_UNITS, OUTPUT_UNITS),
753 - If NEGATIVE, then N represents a negative number,
754 expressed in two's complement.
755 - Otherwise, return "-" if N is unknown. */
758 df_readable (bool negative
, uintmax_t n
, char *buf
,
759 uintmax_t input_units
, uintmax_t output_units
)
761 if (! known_value (n
) && !negative
)
765 char *p
= human_readable (negative
? -n
: n
, buf
+ negative
,
766 human_output_opts
, input_units
, output_units
);
773 /* Logical equivalence */
774 #define LOG_EQ(a, b) (!(a) == !(b))
776 /* Add integral value while using uintmax_t for value part and separate
777 negation flag. It adds value of SRC and SRC_NEG to DEST and DEST_NEG.
778 The result will be in DEST and DEST_NEG. See df_readable to understand
779 how the negation flag is used. */
781 add_uint_with_neg_flag (uintmax_t *dest
, bool *dest_neg
,
782 uintmax_t src
, bool src_neg
)
784 if (LOG_EQ (*dest_neg
, src_neg
))
808 /* Return true if S ends in a string that may be a 36-byte UUID,
809 i.e., of the form HHHHHHHH-HHHH-HHHH-HHHH-HHHHHHHHHHHH, where
810 each H is an upper or lower case hexadecimal digit. */
811 static bool _GL_ATTRIBUTE_PURE
812 has_uuid_suffix (char const *s
)
814 size_t len
= strlen (s
);
816 && strspn (s
+ len
- 36, "-0123456789abcdefABCDEF") == 36);
819 /* Obtain the block values BV and inode values IV
820 from the file system usage FSU. */
822 get_field_values (struct field_values_t
*bv
,
823 struct field_values_t
*iv
,
824 const struct fs_usage
*fsu
)
827 iv
->input_units
= iv
->output_units
= 1;
828 iv
->total
= fsu
->fsu_files
;
829 iv
->available
= iv
->available_to_root
= fsu
->fsu_ffree
;
830 iv
->negate_available
= false;
832 iv
->used
= UINTMAX_MAX
;
833 iv
->negate_used
= false;
834 if (known_value (iv
->total
) && known_value (iv
->available_to_root
))
836 iv
->used
= iv
->total
- iv
->available_to_root
;
837 iv
->negate_used
= (iv
->total
< iv
->available_to_root
);
841 bv
->input_units
= fsu
->fsu_blocksize
;
842 bv
->output_units
= output_block_size
;
843 bv
->total
= fsu
->fsu_blocks
;
844 bv
->available
= fsu
->fsu_bavail
;
845 bv
->available_to_root
= fsu
->fsu_bfree
;
846 bv
->negate_available
= (fsu
->fsu_bavail_top_bit_set
847 && known_value (fsu
->fsu_bavail
));
849 bv
->used
= UINTMAX_MAX
;
850 bv
->negate_used
= false;
851 if (known_value (bv
->total
) && known_value (bv
->available_to_root
))
853 bv
->used
= bv
->total
- bv
->available_to_root
;
854 bv
->negate_used
= (bv
->total
< bv
->available_to_root
);
858 /* Add block and inode values to grand total. */
860 add_to_grand_total (struct field_values_t
*bv
, struct field_values_t
*iv
)
862 if (known_value (iv
->total
))
863 grand_fsu
.fsu_files
+= iv
->total
;
864 if (known_value (iv
->available
))
865 grand_fsu
.fsu_ffree
+= iv
->available
;
867 if (known_value (bv
->total
))
868 grand_fsu
.fsu_blocks
+= bv
->input_units
* bv
->total
;
869 if (known_value (bv
->available_to_root
))
870 grand_fsu
.fsu_bfree
+= bv
->input_units
* bv
->available_to_root
;
871 if (known_value (bv
->available
))
872 add_uint_with_neg_flag (&grand_fsu
.fsu_bavail
,
873 &grand_fsu
.fsu_bavail_top_bit_set
,
874 bv
->input_units
* bv
->available
,
875 bv
->negate_available
);
878 /* Obtain a space listing for the disk device with absolute file name DISK.
879 If MOUNT_POINT is non-NULL, it is the name of the root of the
881 If STAT_FILE is non-null, it is the name of a file within the file
882 system that the user originally asked for; this provides better
883 diagnostics, and sometimes it provides better results on networked
884 file systems that give different free-space results depending on
885 where in the file system you probe.
886 If FSTYPE is non-NULL, it is the type of the file system on DISK.
887 If MOUNT_POINT is non-NULL, then DISK may be NULL -- certain systems may
888 not be able to produce statistics in this case.
889 ME_DUMMY and ME_REMOTE are the mount entry flags.
890 Caller must set PROCESS_ALL to true when iterating over all entries, as
891 when df is invoked with no non-option argument. See below for details. */
894 get_dev (char const *disk
, char const *mount_point
, char const* file
,
895 char const *stat_file
, char const *fstype
,
896 bool me_dummy
, bool me_remote
,
897 const struct fs_usage
*force_fsu
,
900 if (me_remote
&& show_local_fs
)
903 if (me_dummy
&& !show_all_fs
&& !show_listed_fs
)
906 if (!selected_fstype (fstype
) || excluded_fstype (fstype
))
909 /* Ignore relative MOUNT_POINTs, which are present for example
910 in /proc/mounts on Linux with network namespaces. */
911 if (!force_fsu
&& mount_point
&& ! IS_ABSOLUTE_FILE_NAME (mount_point
))
914 /* If MOUNT_POINT is NULL, then the file system is not mounted, and this
915 program reports on the file system that the special file is on.
916 It would be better to report on the unmounted file system,
917 but statfs doesn't do that on most systems. */
919 stat_file
= mount_point
? mount_point
: disk
;
924 else if (get_fs_usage (stat_file
, disk
, &fsu
))
926 /* If we can't access a system provided entry due
927 to it not being present (now), or due to permissions,
928 just output placeholder values rather than failing. */
929 if (process_all
&& (errno
== EACCES
|| errno
== ENOENT
))
935 fsu
.fsu_bavail_top_bit_set
= false;
936 fsu
.fsu_blocksize
= fsu
.fsu_blocks
= fsu
.fsu_bfree
=
937 fsu
.fsu_bavail
= fsu
.fsu_files
= fsu
.fsu_ffree
= UINTMAX_MAX
;
941 error (0, errno
, "%s", quotef (stat_file
));
942 exit_status
= EXIT_FAILURE
;
946 else if (process_all
&& show_all_fs
)
948 /* Ensure we don't output incorrect stats for over-mounted directories.
949 Discard stats when the device name doesn't match. Though don't
950 discard when used and current mount entries are both remote due
951 to the possibility of aliased host names or exports. */
953 if (stat (stat_file
, &sb
) == 0)
955 struct mount_entry
const * dev_me
= me_for_dev (sb
.st_dev
);
956 if (dev_me
&& ! STREQ (dev_me
->me_devname
, disk
)
957 && (! dev_me
->me_remote
|| ! me_remote
))
960 fsu
.fsu_bavail_top_bit_set
= false;
961 fsu
.fsu_blocksize
= fsu
.fsu_blocks
= fsu
.fsu_bfree
=
962 fsu
.fsu_bavail
= fsu
.fsu_files
= fsu
.fsu_ffree
= UINTMAX_MAX
;
967 if (fsu
.fsu_blocks
== 0 && !show_all_fs
&& !show_listed_fs
)
971 file_systems_processed
= true;
976 disk
= "-"; /* unknown */
979 file
= "-"; /* unspecified */
981 char *dev_name
= xstrdup (disk
);
984 /* On some systems, dev_name is a long-named symlink like
985 /dev/disk/by-uuid/828fc648-9f30-43d8-a0b1-f7196a2edb66 pointing to a
986 much shorter and more useful name like /dev/sda1. It may also look
987 like /dev/mapper/luks-828fc648-9f30-43d8-a0b1-f7196a2edb66 and point to
988 /dev/dm-0. When process_all is true and dev_name is a symlink whose
989 name ends with a UUID use the resolved name instead. */
991 && has_uuid_suffix (dev_name
)
992 && (resolved_dev
= canonicalize_filename_mode (dev_name
, CAN_EXISTING
)))
995 dev_name
= resolved_dev
;
999 fstype
= "-"; /* unknown */
1001 struct field_values_t block_values
;
1002 struct field_values_t inode_values
;
1003 get_field_values (&block_values
, &inode_values
, &fsu
);
1005 /* Add to grand total unless processing grand total line. */
1006 if (print_grand_total
&& ! force_fsu
)
1007 add_to_grand_total (&block_values
, &inode_values
);
1010 for (col
= 0; col
< ncolumns
; col
++)
1012 char buf
[LONGEST_HUMAN_READABLE
+ 2];
1015 struct field_values_t
*v
;
1016 switch (columns
[col
]->field_type
)
1028 v
= NULL
; /* Avoid warnings where assert() is not __noreturn__. */
1029 assert (!"bad field_type");
1032 switch (columns
[col
]->field
)
1035 cell
= xstrdup (dev_name
);
1039 cell
= xstrdup (fstype
);
1044 cell
= xstrdup (df_readable (false, v
->total
, buf
,
1045 v
->input_units
, v
->output_units
));
1050 cell
= xstrdup (df_readable (v
->negate_used
, v
->used
, buf
,
1051 v
->input_units
, v
->output_units
));
1056 cell
= xstrdup (df_readable (v
->negate_available
, v
->available
, buf
,
1057 v
->input_units
, v
->output_units
));
1064 if (! known_value (v
->used
) || ! known_value (v
->available
))
1066 else if (!v
->negate_used
1067 && v
->used
<= TYPE_MAXIMUM (uintmax_t) / 100
1068 && v
->used
+ v
->available
!= 0
1069 && (v
->used
+ v
->available
< v
->used
)
1070 == v
->negate_available
)
1072 uintmax_t u100
= v
->used
* 100;
1073 uintmax_t nonroot_total
= v
->used
+ v
->available
;
1074 pct
= u100
/ nonroot_total
+ (u100
% nonroot_total
!= 0);
1078 /* The calculation cannot be done easily with integer
1079 arithmetic. Fall back on floating point. This can suffer
1080 from minor rounding errors, but doing it exactly requires
1081 multiple precision arithmetic, and it's not worth the
1083 double u
= v
->negate_used
? - (double) - v
->used
: v
->used
;
1084 double a
= v
->negate_available
1085 ? - (double) - v
->available
: v
->available
;
1086 double nonroot_total
= u
+ a
;
1089 long int lipct
= pct
= u
* 100 / nonroot_total
;
1090 double ipct
= lipct
;
1092 /* Like 'pct = ceil (dpct);', but avoid ceil so that
1093 the math library needn't be linked. */
1094 if (ipct
- 1 < pct
&& pct
<= ipct
+ 1)
1095 pct
= ipct
+ (ipct
< pct
);
1101 if (asprintf (&cell
, "%.0f%%", pct
) == -1)
1105 cell
= strdup ("-");
1114 cell
= xstrdup (file
);
1118 #ifdef HIDE_AUTOMOUNT_PREFIX
1119 /* Don't print the first directory name in MOUNT_POINT if it's an
1120 artifact of an automounter. This is a bit too aggressive to be
1122 if (STRNCMP_LIT (mount_point
, "/auto/") == 0)
1124 else if (STRNCMP_LIT (mount_point
, "/tmp_mnt/") == 0)
1127 cell
= xstrdup (mount_point
);
1131 assert (!"unhandled field");
1135 assert (!"empty cell");
1137 hide_problematic_chars (cell
);
1138 columns
[col
]->width
= MAX (columns
[col
]->width
, mbswidth (cell
, 0));
1139 table
[nrows
- 1][col
] = cell
;
1144 /* Scan the mount list returning the _last_ device found for MOUNT.
1145 NULL is returned if MOUNT not found. The result is malloced. */
1147 last_device_for_mount (char const* mount
)
1149 struct mount_entry
const *me
;
1150 struct mount_entry
const *le
= NULL
;
1152 for (me
= mount_list
; me
; me
= me
->me_next
)
1154 if (STREQ (me
->me_mountdir
, mount
))
1160 char *devname
= le
->me_devname
;
1161 char *canon_dev
= canonicalize_file_name (devname
);
1162 if (canon_dev
&& IS_ABSOLUTE_FILE_NAME (canon_dev
))
1165 return xstrdup (le
->me_devname
);
1171 /* If DISK corresponds to a mount point, show its usage
1172 and return true. Otherwise, return false. */
1174 get_disk (char const *disk
)
1176 struct mount_entry
const *me
;
1177 struct mount_entry
const *best_match
= NULL
;
1178 bool best_match_accessible
= false;
1179 bool eclipsed_device
= false;
1180 char const *file
= disk
;
1182 char *resolved
= canonicalize_file_name (disk
);
1183 if (resolved
&& IS_ABSOLUTE_FILE_NAME (resolved
))
1186 size_t best_match_len
= SIZE_MAX
;
1187 for (me
= mount_list
; me
; me
= me
->me_next
)
1189 /* TODO: Should cache canon_dev in the mount_entry struct. */
1190 char *devname
= me
->me_devname
;
1191 char *canon_dev
= canonicalize_file_name (me
->me_devname
);
1192 if (canon_dev
&& IS_ABSOLUTE_FILE_NAME (canon_dev
))
1193 devname
= canon_dev
;
1195 if (STREQ (disk
, devname
))
1197 char *last_device
= last_device_for_mount (me
->me_mountdir
);
1198 eclipsed_device
= last_device
&& ! STREQ (last_device
, devname
);
1199 size_t len
= strlen (me
->me_mountdir
);
1201 if (! eclipsed_device
1202 && (! best_match_accessible
|| len
< best_match_len
))
1204 struct stat disk_stats
;
1205 bool this_match_accessible
= false;
1207 if (stat (me
->me_mountdir
, &disk_stats
) == 0)
1208 best_match_accessible
= this_match_accessible
= true;
1210 if (this_match_accessible
1211 || (! best_match_accessible
&& len
< best_match_len
))
1214 if (len
== 1) /* Traditional root. */
1221 best_match_len
= len
;
1235 get_dev (best_match
->me_devname
, best_match
->me_mountdir
, file
, NULL
,
1236 best_match
->me_type
, best_match
->me_dummy
,
1237 best_match
->me_remote
, NULL
, false);
1240 else if (eclipsed_device
)
1242 error (0, 0, _("cannot access %s: over-mounted by another device"),
1244 exit_status
= EXIT_FAILURE
;
1251 /* Figure out which device file or directory POINT is mounted on
1252 and show its disk usage.
1253 STATP must be the result of 'stat (POINT, STATP)'. */
1255 get_point (const char *point
, const struct stat
*statp
)
1257 struct stat disk_stats
;
1258 struct mount_entry
*me
;
1259 struct mount_entry
const *best_match
= NULL
;
1261 /* Calculate the real absolute file name for POINT, and use that to find
1262 the mount point. This avoids statting unavailable mount points,
1263 which can hang df. */
1264 char *resolved
= canonicalize_file_name (point
);
1265 if (resolved
&& resolved
[0] == '/')
1267 size_t resolved_len
= strlen (resolved
);
1268 size_t best_match_len
= 0;
1270 for (me
= mount_list
; me
; me
= me
->me_next
)
1272 if (!STREQ (me
->me_type
, "lofs")
1273 && (!best_match
|| best_match
->me_dummy
|| !me
->me_dummy
))
1275 size_t len
= strlen (me
->me_mountdir
);
1276 if (best_match_len
<= len
&& len
<= resolved_len
1277 && (len
== 1 /* root file system */
1278 || ((len
== resolved_len
|| resolved
[len
] == '/')
1279 && STREQ_LEN (me
->me_mountdir
, resolved
, len
))))
1282 best_match_len
= len
;
1289 && (stat (best_match
->me_mountdir
, &disk_stats
) != 0
1290 || disk_stats
.st_dev
!= statp
->st_dev
))
1294 for (me
= mount_list
; me
; me
= me
->me_next
)
1296 if (me
->me_dev
== (dev_t
) -1)
1298 if (stat (me
->me_mountdir
, &disk_stats
) == 0)
1299 me
->me_dev
= disk_stats
.st_dev
;
1302 /* Report only I/O errors. Other errors might be
1303 caused by shadowed mount points, which means POINT
1304 can't possibly be on this file system. */
1307 error (0, errno
, "%s", quotef (me
->me_mountdir
));
1308 exit_status
= EXIT_FAILURE
;
1311 /* So we won't try and fail repeatedly. */
1312 me
->me_dev
= (dev_t
) -2;
1316 if (statp
->st_dev
== me
->me_dev
1317 && !STREQ (me
->me_type
, "lofs")
1318 && (!best_match
|| best_match
->me_dummy
|| !me
->me_dummy
))
1320 /* Skip bogus mtab entries. */
1321 if (stat (me
->me_mountdir
, &disk_stats
) != 0
1322 || disk_stats
.st_dev
!= me
->me_dev
)
1323 me
->me_dev
= (dev_t
) -2;
1330 get_dev (best_match
->me_devname
, best_match
->me_mountdir
, point
, point
,
1331 best_match
->me_type
, best_match
->me_dummy
, best_match
->me_remote
,
1335 /* We couldn't find the mount entry corresponding to POINT. Go ahead and
1336 print as much info as we can; methods that require the device to be
1337 present will fail at a later point. */
1339 /* Find the actual mount point. */
1340 char *mp
= find_mount_point (point
, statp
);
1343 get_dev (NULL
, mp
, point
, NULL
, NULL
, false, false, NULL
, false);
1349 /* Determine what kind of node NAME is and show the disk usage
1350 for it. STATP is the results of 'stat' on NAME. */
1353 get_entry (char const *name
, struct stat
const *statp
)
1355 if ((S_ISBLK (statp
->st_mode
) || S_ISCHR (statp
->st_mode
))
1359 get_point (name
, statp
);
1362 /* Show all mounted file systems, except perhaps those that are of
1363 an unselected type or are empty. */
1366 get_all_entries (void)
1368 struct mount_entry
*me
;
1370 filter_mount_list (show_all_fs
);
1372 for (me
= mount_list
; me
; me
= me
->me_next
)
1373 get_dev (me
->me_devname
, me
->me_mountdir
, NULL
, NULL
, me
->me_type
,
1374 me
->me_dummy
, me
->me_remote
, NULL
, true);
1377 /* Add FSTYPE to the list of file system types to display. */
1380 add_fs_type (const char *fstype
)
1382 struct fs_type_list
*fsp
;
1384 fsp
= xmalloc (sizeof *fsp
);
1385 fsp
->fs_name
= (char *) fstype
;
1386 fsp
->fs_next
= fs_select_list
;
1387 fs_select_list
= fsp
;
1390 /* Add FSTYPE to the list of file system types to be omitted. */
1393 add_excluded_fs_type (const char *fstype
)
1395 struct fs_type_list
*fsp
;
1397 fsp
= xmalloc (sizeof *fsp
);
1398 fsp
->fs_name
= (char *) fstype
;
1399 fsp
->fs_next
= fs_exclude_list
;
1400 fs_exclude_list
= fsp
;
1406 if (status
!= EXIT_SUCCESS
)
1410 printf (_("Usage: %s [OPTION]... [FILE]...\n"), program_name
);
1412 Show information about the file system on which each FILE resides,\n\
1413 or all file systems by default.\n\
1416 emit_mandatory_arg_note ();
1418 /* TRANSLATORS: The thousands and decimal separators are best
1419 adjusted to an appropriate default for your locale. */
1421 -a, --all include pseudo, duplicate, inaccessible file systems\n\
1422 -B, --block-size=SIZE scale sizes by SIZE before printing them; e.g.,\n\
1423 '-BM' prints sizes in units of 1,048,576 bytes;\n\
1424 see SIZE format below\n\
1425 -h, --human-readable print sizes in powers of 1024 (e.g., 1023M)\n\
1426 -H, --si print sizes in powers of 1000 (e.g., 1.1G)\n\
1429 -i, --inodes list inode information instead of block usage\n\
1430 -k like --block-size=1K\n\
1431 -l, --local limit listing to local file systems\n\
1432 --no-sync do not invoke sync before getting usage info (default)\
1436 --output[=FIELD_LIST] use the output format defined by FIELD_LIST,\n\
1437 or print all fields if FIELD_LIST is omitted.\n\
1438 -P, --portability use the POSIX output format\n\
1439 --sync invoke sync before getting usage info\n\
1442 --total elide all entries insignificant to available space,\n\
1443 and produce a grand total\n\
1446 -t, --type=TYPE limit listing to file systems of type TYPE\n\
1447 -T, --print-type print file system type\n\
1448 -x, --exclude-type=TYPE limit listing to file systems not of type TYPE\n\
1451 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
1452 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
1453 emit_blocksize_note ("DF");
1456 FIELD_LIST is a comma-separated list of columns to be included. Valid\n\
1457 field names are: 'source', 'fstype', 'itotal', 'iused', 'iavail', 'ipcent',\n\
1458 'size', 'used', 'avail', 'pcent', 'file' and 'target' (see info page).\n\
1460 emit_ancillary_info (PROGRAM_NAME
);
1466 main (int argc
, char **argv
)
1468 struct stat
*stats
IF_LINT ( = 0);
1470 initialize_main (&argc
, &argv
);
1471 set_program_name (argv
[0]);
1472 setlocale (LC_ALL
, "");
1473 bindtextdomain (PACKAGE
, LOCALEDIR
);
1474 textdomain (PACKAGE
);
1476 atexit (close_stdout
);
1478 fs_select_list
= NULL
;
1479 fs_exclude_list
= NULL
;
1480 show_all_fs
= false;
1481 show_listed_fs
= false;
1482 human_output_opts
= -1;
1484 file_systems_processed
= false;
1485 exit_status
= EXIT_SUCCESS
;
1486 print_grand_total
= false;
1487 grand_fsu
.fsu_blocksize
= 1;
1489 /* If true, use the POSIX output format. */
1490 bool posix_format
= false;
1492 const char *msg_mut_excl
= _("options %s and %s are mutually exclusive");
1497 int c
= getopt_long (argc
, argv
, "aB:iF:hHklmPTt:vx:", long_options
,
1509 enum strtol_error e
= human_options (optarg
, &human_output_opts
,
1510 &output_block_size
);
1511 if (e
!= LONGINT_OK
)
1512 xstrtol_fatal (e
, oi
, c
, long_options
, optarg
);
1516 if (header_mode
== OUTPUT_MODE
)
1518 error (0, 0, msg_mut_excl
, "-i", "--output");
1519 usage (EXIT_FAILURE
);
1521 header_mode
= INODES_MODE
;
1524 human_output_opts
= human_autoscale
| human_SI
| human_base_1024
;
1525 output_block_size
= 1;
1528 human_output_opts
= human_autoscale
| human_SI
;
1529 output_block_size
= 1;
1532 human_output_opts
= 0;
1533 output_block_size
= 1024;
1536 show_local_fs
= true;
1538 case 'm': /* obsolescent, exists for BSD compatibility */
1539 human_output_opts
= 0;
1540 output_block_size
= 1024 * 1024;
1543 if (header_mode
== OUTPUT_MODE
)
1545 error (0, 0, msg_mut_excl
, "-T", "--output");
1546 usage (EXIT_FAILURE
);
1551 if (header_mode
== OUTPUT_MODE
)
1553 error (0, 0, msg_mut_excl
, "-P", "--output");
1554 usage (EXIT_FAILURE
);
1556 posix_format
= true;
1559 require_sync
= true;
1561 case NO_SYNC_OPTION
:
1562 require_sync
= false;
1566 /* Accept -F as a synonym for -t for compatibility with Solaris. */
1568 add_fs_type (optarg
);
1571 case 'v': /* For SysV compatibility. */
1575 add_excluded_fs_type (optarg
);
1579 if (header_mode
== INODES_MODE
)
1581 error (0, 0, msg_mut_excl
, "-i", "--output");
1582 usage (EXIT_FAILURE
);
1584 if (posix_format
&& header_mode
== DEFAULT_MODE
)
1586 error (0, 0, msg_mut_excl
, "-P", "--output");
1587 usage (EXIT_FAILURE
);
1591 error (0, 0, msg_mut_excl
, "-T", "--output");
1592 usage (EXIT_FAILURE
);
1594 header_mode
= OUTPUT_MODE
;
1596 decode_output_arg (optarg
);
1600 print_grand_total
= true;
1603 case_GETOPT_HELP_CHAR
;
1604 case_GETOPT_VERSION_CHAR (PROGRAM_NAME
, AUTHORS
);
1607 usage (EXIT_FAILURE
);
1611 if (human_output_opts
== -1)
1615 human_output_opts
= 0;
1616 output_block_size
= (getenv ("POSIXLY_CORRECT") ? 512 : 1024);
1619 human_options (getenv ("DF_BLOCK_SIZE"),
1620 &human_output_opts
, &output_block_size
);
1623 if (header_mode
== INODES_MODE
|| header_mode
== OUTPUT_MODE
)
1625 else if (human_output_opts
& human_autoscale
)
1626 header_mode
= HUMAN_MODE
;
1627 else if (posix_format
)
1628 header_mode
= POSIX_MODE
;
1630 /* Fail if the same file system type was both selected and excluded. */
1633 struct fs_type_list
*fs_incl
;
1634 for (fs_incl
= fs_select_list
; fs_incl
; fs_incl
= fs_incl
->fs_next
)
1636 struct fs_type_list
*fs_excl
;
1637 for (fs_excl
= fs_exclude_list
; fs_excl
; fs_excl
= fs_excl
->fs_next
)
1639 if (STREQ (fs_incl
->fs_name
, fs_excl
->fs_name
))
1642 _("file system type %s both selected and excluded"),
1643 quote (fs_incl
->fs_name
));
1650 return EXIT_FAILURE
;
1653 assume (0 < optind
);
1659 /* Open each of the given entries to make sure any corresponding
1660 partition is automounted. This must be done before reading the
1661 file system table. */
1662 stats
= xnmalloc (argc
- optind
, sizeof *stats
);
1663 for (i
= optind
; i
< argc
; ++i
)
1665 /* Prefer to open with O_NOCTTY and use fstat, but fall back
1666 on using "stat", in case the file is unreadable. */
1667 int fd
= open (argv
[i
], O_RDONLY
| O_NOCTTY
);
1668 if ((fd
< 0 || fstat (fd
, &stats
[i
- optind
]))
1669 && stat (argv
[i
], &stats
[i
- optind
]))
1671 error (0, errno
, "%s", quotef (argv
[i
]));
1672 exit_status
= EXIT_FAILURE
;
1681 read_file_system_list ((fs_select_list
!= NULL
1682 || fs_exclude_list
!= NULL
1684 || field_data
[FSTYPE_FIELD
].used
1687 if (mount_list
== NULL
)
1689 /* Couldn't read the table of mounted file systems.
1690 Fail if df was invoked with no file name arguments,
1691 or when either of -a, -l, -t or -x is used with file name
1692 arguments. Otherwise, merely give a warning and proceed. */
1694 if ( ! (optind
< argc
)
1697 || fs_select_list
!= NULL
1698 || fs_exclude_list
!= NULL
))
1700 status
= EXIT_FAILURE
;
1702 const char *warning
= (status
== 0 ? _("Warning: ") : "");
1703 error (status
, errno
, "%s%s", warning
,
1704 _("cannot read table of mounted file systems"));
1717 /* Display explicitly requested empty file systems. */
1718 show_listed_fs
= true;
1720 for (i
= optind
; i
< argc
; ++i
)
1722 get_entry (argv
[i
], &stats
[i
- optind
]);
1724 IF_LINT (free (stats
));
1729 if (file_systems_processed
)
1731 if (print_grand_total
)
1733 (field_data
[SOURCE_FIELD
].used
? "-" : "total"),
1734 NULL
, NULL
, NULL
, false, false, &grand_fsu
, false);
1740 /* Print the "no FS processed" diagnostic only if there was no preceding
1741 diagnostic, e.g., if all have been excluded. */
1742 if (exit_status
== EXIT_SUCCESS
)
1743 error (EXIT_FAILURE
, 0, _("no file systems processed"));
1746 IF_LINT (free (columns
));