summaryrefslogtreecommitdiff
path: root/src/du.c
diff options
context:
space:
mode:
authorBernhard Voelker <mail@bernhard-voelker.de>2013-07-27 14:25:28 +0200
committerBernhard Voelker <mail@bernhard-voelker.de>2013-07-27 14:25:28 +0200
commit333dc83d52e014a0b532e316ea8cd93b048f1ac6 (patch)
tree3bf519653280e660e7311e436b6e0e0fee8160a5 /src/du.c
parent2bdb74ec1a453f6c6084d042e573de436ec205f3 (diff)
downloadcoreutils-333dc83d52e014a0b532e316ea8cd93b048f1ac6.tar.gz
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.c38
1 files changed, 34 insertions, 4 deletions
diff --git a/src/du.c b/src/du.c
index a6fa16b29..9f1f98c5c 100644
--- a/src/du.c
+++ b/src/du.c
@@ -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)
{