diff options
author | Bernhard Voelker <mail@bernhard-voelker.de> | 2013-07-27 14:25:28 +0200 |
---|---|---|
committer | Bernhard Voelker <mail@bernhard-voelker.de> | 2013-07-27 14:25:28 +0200 |
commit | 333dc83d52e014a0b532e316ea8cd93b048f1ac6 (patch) | |
tree | 3bf519653280e660e7311e436b6e0e0fee8160a5 /src/du.c | |
parent | 2bdb74ec1a453f6c6084d042e573de436ec205f3 (diff) | |
download | coreutils-333dc83d52e014a0b532e316ea8cd93b048f1ac6.tar.xz |
du: add --inodes option
This new option can be used to find directories with a huge
amount of files. The GNU find utility has the printf format
"%h" which prints the number of entries in a directory, but
this is non-cumulative and doesn't handle hard links.
* src/du.c (struct duinfo): Add new member for counting inodes.
(duinfo_init): Initialize inodes member with Zero.
(duinfo_set): Set inodes counter to 1.
(duinfo_add): Sum up the 2 given inodes counters.
(opt_inodes): Add new boolean flag to remember if the --inodes
option has been specified.
(INODES_OPTION): Add new enum value to be used ...
(long_options): ... here.
(usage): Add description of the new option.
(print_size): Pass inodes counter or size to print_only_size,
depending on the inodes mode.
(process_file): Adapt threshold handling: with --inodes, print or
elide the entries according to the struct member inodes.
(main): Add a case for accepting the new INODES_OPTION.
Print a warning diagnostic when --inodes is used together with the
option --apparent-size or -b.
Reset the output_block_size to 1 ... and thus ignoring the
options -m and -k.
* tests/du/inodes.sh: Add a new test.
* tests/local.mk (all_tests): Mention it.
* doc/coreutils.texi (du invocation): Document the new option.
* NEWS: Mention the new option.
Diffstat (limited to 'src/du.c')
-rw-r--r-- | src/du.c | 38 |
1 files changed, 34 insertions, 4 deletions
@@ -78,6 +78,9 @@ struct duinfo /* Size of files in directory. */ uintmax_t size; + /* Number of inodes in directory. */ + uintmax_t inodes; + /* Latest time stamp found. If tmax.tv_sec == TYPE_MINIMUM (time_t) && tmax.tv_nsec < 0, no time stamp has been found. */ struct timespec tmax; @@ -88,6 +91,7 @@ static inline void duinfo_init (struct duinfo *a) { a->size = 0; + a->inodes = 0; a->tmax.tv_sec = TYPE_MINIMUM (time_t); a->tmax.tv_nsec = -1; } @@ -97,6 +101,7 @@ static inline void duinfo_set (struct duinfo *a, uintmax_t size, struct timespec tmax) { a->size = size; + a->inodes = 1; a->tmax = tmax; } @@ -106,6 +111,7 @@ duinfo_add (struct duinfo *a, struct duinfo const *b) { uintmax_t sum = a->size + b->size; a->size = a->size <= sum ? sum : UINTMAX_MAX; + a->inodes = a->inodes + b->inodes; if (timespec_cmp (a->tmax, b->tmax) < 0) a->tmax = b->tmax; } @@ -154,6 +160,9 @@ static intmax_t opt_threshold = 0; /* Human-readable options for output. */ static int human_output_opts; +/* Output inodes count instead of blocks used. */ +static bool opt_inodes = false; + /* If true, print most recently modified date, using the specified format. */ static bool opt_time = false; @@ -197,7 +206,8 @@ enum HUMAN_SI_OPTION, FTS_DEBUG, TIME_OPTION, - TIME_STYLE_OPTION + TIME_STYLE_OPTION, + INODES_OPTION }; static struct option const long_options[] = @@ -214,6 +224,7 @@ static struct option const long_options[] = {"exclude-from", required_argument, NULL, 'X'}, {"files0-from", required_argument, NULL, FILES0_FROM_OPTION}, {"human-readable", no_argument, NULL, 'h'}, + {"inodes", no_argument, NULL, INODES_OPTION}, {"si", no_argument, NULL, HUMAN_SI_OPTION}, {"max-depth", required_argument, NULL, 'd'}, {"null", no_argument, NULL, '0'}, @@ -306,6 +317,7 @@ Summarize disk usage of each FILE, recursively for directories.\n\ -H equivalent to --dereference-args (-D)\n\ -h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G)\ \n\ + --inodes list inode usage information instead of block usage\n\ "), stdout); fputs (_("\ -k like --block-size=1K\n\ @@ -394,7 +406,10 @@ print_only_size (uintmax_t n_bytes) static void print_size (const struct duinfo *pdui, const char *string) { - print_only_size (pdui->size); + print_only_size (opt_inodes + ? pdui->inodes + : pdui->size); + if (opt_time) { putchar ('\t'); @@ -589,9 +604,10 @@ process_file (FTS *fts, FTSENT *ent) || level == 0) { /* Print or elide this entry according to the --threshold option. */ + uintmax_t v = opt_inodes ? dui_to_print.inodes : dui_to_print.size; if (opt_threshold < 0 - ? dui_to_print.size <= -opt_threshold - : dui_to_print.size >= opt_threshold) + ? v <= -opt_threshold + : v >= opt_threshold) print_size (&dui_to_print, file); } @@ -853,6 +869,10 @@ main (int argc, char **argv) add_exclude (exclude, optarg, EXCLUDE_WILDCARDS); break; + case INODES_OPTION: + opt_inodes = true; + break; + case TIME_OPTION: opt_time = true; time_type = @@ -899,6 +919,16 @@ main (int argc, char **argv) if (opt_summarize_only) max_depth = 0; + if (opt_inodes) + { + if (apparent_size) + { + error (0, 0, _("warning: options --apparent-size and -b are " + "ineffective with --inodes")); + } + output_block_size = 1; + } + /* Process time style if printing last times. */ if (opt_time) { |