+ assert(loop_ret < 0);
+ if (loop_ret == -E_LOOP_COMPLETE) /* no error */
+ return 1;
+ if (loop_ret == -E_OSL) { /* osl error in loop function */
+ assert(loop_osl_errno);
+ osl_errno = loop_osl_errno;
+ }
+ return loop_ret;
+}
+
+static int adu_loop_reverse(struct osl_table *t, unsigned col_num, void *private_data,
+ osl_rbtree_loop_func *func, int *loop_ret, int *loop_osl_errno)
+{
+ int ret = osl(osl_rbtree_loop_reverse(t, col_num, private_data, func));
+ return check_loop_return(ret, *loop_ret, *loop_osl_errno);
+}
+
+static int print_user_stats(void)
+{
+ struct user_info *ui;
+ int ret;
+
+ FOR_EACH_USER(ui) {
+ struct user_stats_info usi = {
+ .count = conf.limit_arg,
+ .ui = ui
+ };
+ if (!ui_used(ui) || !ui_admissible(ui))
+ continue;
+ usi.flags = USF_PRINT_DIRNAME | USF_PRINT_BYTES | USF_COMPUTE_SUMMARY;
+ printf("uid %u, by size%s:\n",
+ (unsigned) ui->uid, size_unit_buf);
+ ret = adu_loop_reverse(ui->table, UT_BYTES, &usi, user_stats_loop_function,
+ &usi.ret, &usi.osl_errno);
+ if (ret < 0)
+ return ret;
+ printf("\nuid %u, by file count%s:\n",
+ (unsigned) ui->uid, count_unit_buf);
+ usi.count = conf.limit_arg,
+ usi.flags = USF_PRINT_DIRNAME | USF_PRINT_FILES;
+ ret = adu_loop_reverse(ui->table, UT_FILES, &usi, user_stats_loop_function,
+ &usi.ret, &usi.osl_errno);
+ if (ret < 0)
+ return ret;
+ printf("\n");
+ }
+ return 1;
+}
+
+static void print_global_summary(void)
+{
+ char d[FORMATED_VALUE_SIZE], f[FORMATED_VALUE_SIZE],
+ s[FORMATED_VALUE_SIZE];
+ enum enum_count_unit ud, uf;
+ enum enum_size_unit us;
+
+ ud = format_count_value(conf.count_unit_arg, num_dirs, 0, d);
+ uf = format_count_value(conf.count_unit_arg, num_files, 0, f);
+ us = format_size_value(conf.size_unit_arg, num_bytes, 0, s);
+
+ printf("Global summary "
+ "(dirs(%c)/files(%c)/size(%c))\n"
+ "\t%s\t%s\t%s\n\n",
+ count_unit_abbrevs[ud],
+ count_unit_abbrevs[uf],
+ size_unit_abbrevs[us],
+ d, f, s
+ );
+
+}
+
+static int print_statistics(void)
+{
+ int ret;
+ struct global_stats_info gsi = {
+ .count = conf.limit_arg,
+ .flags = GSF_PRINT_DIRNAME | GSF_PRINT_BYTES | GSF_COMPUTE_SUMMARY
+ };
+
+ printf("By size%s:\n",
+ size_unit_buf);
+ ret = adu_loop_reverse(dir_table, DT_BYTES, &gsi,
+ global_stats_loop_function, &gsi.ret, &gsi.osl_errno);