From f40f993c99e6c42faab7cac8958bc12da0fee599 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sat, 31 May 2008 19:22:46 +0200 Subject: [PATCH 1/1] Switch to the new osl_rbtree_loop() semantics. This fixes the --limit option that broke by introducing the osl() wrapper. --- adu.c | 92 ++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 23 deletions(-) diff --git a/adu.c b/adu.c index deb3e94..8721089 100644 --- a/adu.c +++ b/adu.c @@ -677,6 +677,8 @@ enum global_stats_flags { struct global_stats_info { uint32_t count; + int ret; + int osl_errno; enum global_stats_flags flags; }; @@ -687,12 +689,14 @@ static int global_stats_loop_function(struct osl_row *row, void *data) 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" @@ -702,7 +706,7 @@ static int global_stats_loop_function(struct osl_row *row, void *data) 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, @@ -717,7 +721,7 @@ static int global_stats_loop_function(struct osl_row *row, void *data) 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, @@ -732,6 +736,10 @@ static int global_stats_loop_function(struct osl_row *row, void *data) 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) @@ -768,6 +776,8 @@ enum user_stats_flags { struct user_stats_info { uint32_t count; enum user_stats_flags flags; + int ret; + int osl_errno; struct user_info *ui; }; @@ -778,16 +788,18 @@ static int user_stats_loop_function(struct osl_row *row, void *data) 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))? @@ -798,7 +810,7 @@ static int user_stats_loop_function(struct osl_row *row, void *data) 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, @@ -814,7 +826,7 @@ static int user_stats_loop_function(struct osl_row *row, void *data) 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, @@ -830,11 +842,41 @@ static int user_stats_loop_function(struct osl_row *row, void *data) 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 = { @@ -847,14 +889,19 @@ static void print_user_stats(void) 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) @@ -866,19 +913,18 @@ 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, -- 2.39.2