struct global_stats_info {
uint32_t count;
+ int ret;
+ int osl_errno;
enum global_stats_flags flags;
};
char *dirname, formated_value[25];
int ret, summary = gsi->flags & GSF_COMPUTE_SUMMARY;
- if (!gsi->count && !summary)
- return -E_LOOP_COMPLETE;
+ if (!gsi->count && !summary) {
+ ret = -E_LOOP_COMPLETE;
+ goto err;
+ }
if (gsi->count && (gsi->flags & GSF_PRINT_DIRNAME)) {
ret = get_dir_name_of_row(row, &dirname);
if (ret < 0)
- return ret;
+ goto err;
printf("%s%s", dirname,
(gsi->flags & (GSF_PRINT_FILES | GSF_PRINT_BYTES))?
"\t" : "\n"
uint64_t files;
ret = osl(osl_get_object(dir_table, row, DT_FILES, &obj));
if (ret < 0)
- return ret;
+ goto err;
files = *(uint64_t *)obj.data;
if (gsi->count && (gsi->flags & GSF_PRINT_FILES)) {
format_size_value(conf.size_unit_arg, files,
uint64_t bytes;
ret = osl(osl_get_object(dir_table, row, DT_BYTES, &obj));
if (ret < 0)
- return ret;
+ goto err;
bytes = *(uint64_t *)obj.data;
if (gsi->count && (gsi->flags & GSF_PRINT_BYTES)) {
format_size_value(conf.size_unit_arg, bytes,
if (gsi->count > 0)
gsi->count--;
return 1;
+err:
+ gsi->ret = ret;
+ gsi->osl_errno = (ret == -E_OSL)? osl_errno : 0;
+ return -1;
}
static void print_id_stats(void)
struct user_stats_info {
uint32_t count;
enum user_stats_flags flags;
+ int ret;
+ int osl_errno;
struct user_info *ui;
};
int ret, summary = usi->flags & GSF_COMPUTE_SUMMARY;
char formated_value[25];
- if (!usi->count && !summary)
- return -E_LOOP_COMPLETE;
+ if (!usi->count && !summary) {
+ ret = -E_LOOP_COMPLETE;
+ goto err;
+ }
if (usi->count && (usi->flags & USF_PRINT_DIRNAME)) {
char *dirname;
ret = osl(osl_get_object(usi->ui->table, row, UT_DIR_NUM, &obj));
if (ret < 0)
- return ret;
+ goto err;
ret = get_dir_name_by_number((uint64_t *)obj.data, &dirname);
if (ret < 0)
- return ret;
+ goto err;
printf("%s%s",
dirname,
(usi->flags & (USF_PRINT_FILES | USF_PRINT_BYTES))?
uint64_t files;
ret = osl(osl_get_object(usi->ui->table, row, UT_FILES, &obj));
if (ret < 0)
- return ret;
+ goto err;
files = *(uint64_t *)obj.data;
if (usi->count && (usi->flags & USF_PRINT_FILES)) {
format_size_value(conf.size_unit_arg, files,
uint64_t bytes;
ret = osl(osl_get_object(usi->ui->table, row, UT_BYTES, &obj));
if (ret < 0)
- return ret;
+ goto err;
bytes = *(uint64_t *)obj.data;
if (usi->count && (usi->flags & USF_PRINT_BYTES)) {
format_size_value(conf.size_unit_arg, bytes,
if (usi->count > 0)
usi->count--;
return 1;
+err:
+ usi->ret = ret;
+ usi->osl_errno = (ret == -E_OSL)? osl_errno : 0;
+ return -1;
+}
+
+static int check_loop_return(int ret, int loop_ret, int loop_osl_errno)
+{
+ if (ret >= 0)
+ return ret;
+ assert(ret == -E_OSL);
+ if (osl_errno != E_OSL_LOOP)
+ /* error not caused by loop function returning negative. */
+ return ret;
+ 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 void print_user_stats(void)
+static int print_user_stats(void)
{
struct user_info *ui;
+ int ret;
FOR_EACH_USER(ui) {
struct user_stats_info usi = {
printf("************************************************ uid %u\n",
(unsigned) ui->uid);
printf("----------------- Largest dirs -------------------\n");
- osl(osl_rbtree_loop_reverse(ui->table, UT_BYTES, &usi,
- user_stats_loop_function));
+ ret = adu_loop_reverse(ui->table, UT_BYTES, &usi, user_stats_loop_function,
+ &usi.ret, &usi.osl_errno);
+ if (ret < 0)
+ return ret;
printf("---------- dirs containing most files ------------\n");
usi.count = conf.limit_arg,
usi.flags = USF_PRINT_DIRNAME | USF_PRINT_FILES;
- osl(osl_rbtree_loop_reverse(ui->table, UT_FILES, &usi,
- user_stats_loop_function));
+ ret = adu_loop_reverse(ui->table, UT_FILES, &usi, user_stats_loop_function,
+ &usi.ret, &usi.osl_errno);
+ if (ret < 0)
+ return ret;
}
+ return 1;
}
static int print_statistics(void)
};
printf("----------------- Largest dirs -------------------\n");
- ret = osl(osl_rbtree_loop_reverse(dir_table, DT_BYTES, &gsi,
- global_stats_loop_function));
- if (ret < 0 && ret != -E_LOOP_COMPLETE)
+ ret = adu_loop_reverse(dir_table, DT_BYTES, &gsi,
+ global_stats_loop_function, &gsi.ret, &gsi.osl_errno);
+ if (ret < 0)
return ret;
gsi.count = conf.limit_arg;
gsi.flags = GSF_PRINT_DIRNAME | GSF_PRINT_FILES;
printf("---------- dirs containing most files ------------\n");
- ret = osl(osl_rbtree_loop_reverse(dir_table, DT_FILES, &gsi,
- global_stats_loop_function));
- if (ret < 0 && ret != -E_LOOP_COMPLETE)
+ ret = adu_loop_reverse(dir_table, DT_FILES, &gsi,
+ global_stats_loop_function, &gsi.ret, &gsi.osl_errno);
+ if (ret < 0)
return ret;
-
printf("------------------ Global summary (dirs/files/bytes)\n"
"%llu\t%llu\t%llu\n",
(long long unsigned)num_dirs, (long long unsigned)num_files,