From d8bb8b7964d4ee283c581a5161b44a5e800e0f85 Mon Sep 17 00:00:00 2001 From: Vitaliy Kuznetsov Date: Tue, 11 Jun 2024 13:23:31 +0200 Subject: [PATCH] EX-9121 lipe: Trivial improvements for dirs report Minor changes that do not affect functionality. Adds functionality to fill the table by directory size. Changes the output for the rating table slightly, adding nesting visualization, but without sorting. Test-Parameters: trivial testlist=sanity-lipe-scan3,sanity-lipe-find3 Signed-off-by: Vitaliy Kuznetsov Change-Id: I74c8978a2e8e4806f7f600db0a573ee162d5cd94 Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/55394 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Alexandre Ioffe Reviewed-by: Andreas Dilger --- lipe/src/lipe_scan3/ls3_dir_stats.c | 397 ++++++++++++++++++++---------------- lipe/src/lipe_scan3/ls3_dir_stats.h | 2 + lipe/src/lipe_scan3/ls3_stats.c | 1 + 3 files changed, 226 insertions(+), 174 deletions(-) diff --git a/lipe/src/lipe_scan3/ls3_dir_stats.c b/lipe/src/lipe_scan3/ls3_dir_stats.c index 71e5fc3..e2e858e 100644 --- a/lipe/src/lipe_scan3/ls3_dir_stats.c +++ b/lipe/src/lipe_scan3/ls3_dir_stats.c @@ -97,6 +97,7 @@ static struct ls3_stats_dir_obj* heap->lsdr_array[0] = heap->lsdr_array[heap->lsdr_current_size_heap - 1]; heap->lsdr_current_size_heap--; ls3_sd_heapify(heap, 0); + root->lsdo_top_rate = false; return root; } @@ -157,6 +158,7 @@ static void ls3_stats_insert_heap(struct ls3_stats_dir_rating* heap, i = heap->lsdr_current_size_heap++; heap->lsdr_array[i] = dir_obj; + dir_obj->lsdo_top_rate = true; while (i != 0 && heap->lsdr_array[ls3_sd_heap_parent(i)]->lsdo_size > heap->lsdr_array[i]->lsdo_size) { @@ -222,144 +224,235 @@ const char *ls3_stats_fmt_size_units(uint64_t bytes) return buffer; } -/* ls3_stats_fprintf_out_recursive - Recursively traverse a directory tree - * in memory and prints statistics for each directory to a - * file if all conditions are met. +/** + * ls3_stats_fprintf_dir - this function prints details of a directory + * to the specified file. + * + * @param *out_fd: Output file stream. + * @param *dir_ptr: Directory object with stats. + * @param printf_rating: Flag indicating that we are printing into + * the rating table. */ -static void ls3_stats_fprintf_out_recursive(FILE *out_fd, - struct ls3_stats_dir_general *stats, - struct ls3_stats_dir_obj *dir_ptr, - bool top_rating_only, - uint64_t *total_size, - uint64_t *total_alloc_size) +static void ls3_stats_fprintf_dir(FILE *out_fd, + struct ls3_stats_dir_obj *dir_ptr, + bool printf_rating) { - struct ls3_stats_dir_obj *child_ptr; - uint64_t allocate_dir_size; + uint64_t allocated_dir_size; char fmt_str_for_fid[30]; - char tmp_alocte_size_str[LS3_STATS_NUM_STR_MAX_WITH_NULL]; + char tmp_allocated_size_str[LS3_STATS_NUM_STR_MAX_WITH_NULL]; char *tabulation; - int i; - if (dir_ptr->lsdo_depth == 0) { - *total_size += dir_ptr->lsdo_size; - *total_alloc_size += dir_ptr->lsdo_alloc_size_in_sectors * 512; - } + if (!out_fd || !dir_ptr) + return; - /* stats->lsdg_min_size_value_for_print is initialized - * to 0 by default unless the user has specified this - * option with a value in Lipe_find3. This is necessary - * when there are a lot of directories and it won't be - * very good to store it in a file. - * - * If at this stage the FID is still empty - * (dir_ptr->lsdo_fid.f_seq == 0), it means that lipe did not - * scan this directory, in other words, while lipe was scanning/working, - * this directory was deleted =(. Or data is stored on another MDT. - * But OST no have FID and type "dir" and should print anyway - * - * And skip first dir. - */ - if (dir_ptr->lsdo_depth >= 0 && - dir_ptr->lsdo_size >= stats->lsdg_min_size_value_for_print && - !top_rating_only && out_fd) { - allocate_dir_size = dir_ptr->lsdo_alloc_size_in_sectors * 512; - tabulation = ls3_stats_get_dots(dir_ptr->lsdo_depth); + if (dir_ptr->lsdo_depth < 0) + return; /* Initial catalog */ - snprintf(fmt_str_for_fid, sizeof(fmt_str_for_fid), - DFID_NOBRACE, PFID(&dir_ptr->lsdo_fid)); + allocated_dir_size = dir_ptr->lsdo_alloc_size_in_sectors * 512; + tabulation = ls3_stats_get_dots(dir_ptr->lsdo_depth); - snprintf(tmp_alocte_size_str, sizeof(tmp_alocte_size_str), - "%s", ls3_stats_fmt_size_units(allocate_dir_size)); + snprintf(fmt_str_for_fid, sizeof(fmt_str_for_fid), + DFID_NOBRACE, PFID(&dir_ptr->lsdo_fid)); - fprintf(out_fd, "%12s %12s %15u %15u %30s %s%s\n", + snprintf(tmp_allocated_size_str, sizeof(tmp_allocated_size_str), + "%s", ls3_stats_fmt_size_units(allocated_dir_size)); + + if (printf_rating) + fprintf(out_fd, "%12s %12s %15u %15u %12u %30s %s%s\n", + tmp_allocated_size_str, ls3_stats_fmt_size_units(dir_ptr->lsdo_size), - tmp_alocte_size_str, dir_ptr->lsdo_files_count, - dir_ptr->lsdo_dirs_count, fmt_str_for_fid, tabulation, + dir_ptr->lsdo_files_count, + dir_ptr->lsdo_dirs_count, + dir_ptr->lsdo_uid, + fmt_str_for_fid, + tabulation, dir_ptr->lsdo_name); - free(tabulation); - } + else + fprintf(out_fd, "%12s %12s %15u %15u %30s %s%s\n", + tmp_allocated_size_str, + ls3_stats_fmt_size_units(dir_ptr->lsdo_size), + dir_ptr->lsdo_files_count, + dir_ptr->lsdo_dirs_count, fmt_str_for_fid, + tabulation, dir_ptr->lsdo_name); - /* Trying to add a directory to the rating table */ - if (stats->lsdg_top_size) - ls3_stats_insert_heap(stats->lsdg_top_size, dir_ptr); + free(tabulation); +} + +/** + * ls3_stats_fprintf_out_recursive - Recursively traverse a directory tree + * in memory and prints statistics for each directory to a file if + * all conditions are met. + * + * This function recursively traverses the directory tree starting from + * `dir_ptr`, printing statistics for each directory to the specified file + * stream. + * + * @param out_fd Output file stream. + * @param stats General statistics object for dirs. + * @param dir_ptr Current directory object to print. + * @param printf_rating Flag indicating that we are printing into + * the rating table. + */ +static void ls3_stats_fprintf_out_recursive(FILE *out_fd, + struct ls3_stats_dir_general *stats, + struct ls3_stats_dir_obj *dir_ptr, + bool printf_rating) +{ + int i; + + if (dir_ptr->lsdo_depth >= 0 && !printf_rating && + dir_ptr->lsdo_size >= stats->lsdg_min_size_value_for_print) + ls3_stats_fprintf_dir(out_fd, dir_ptr, printf_rating); + else if (printf_rating && dir_ptr->lsdo_top_rate) + ls3_stats_fprintf_dir(out_fd, dir_ptr, printf_rating); + + /* If the parent directory is not included in the rating, then + * the child directories are not included in the rating either + */ + if (printf_rating && !dir_ptr->lsdo_top_rate) + return; for (i = 0; i < dir_ptr->lsdo_last_child + 1; i++) { + struct ls3_stats_dir_obj *child_ptr; + child_ptr = dir_ptr->lsdo_child[i]; if (child_ptr == NULL) continue; ls3_stats_fprintf_out_recursive(out_fd, stats, child_ptr, - top_rating_only, total_size, - total_alloc_size); + printf_rating); } } -static void ls3_stats_printf_rating_out(FILE *out_fd, - struct ls3_stats_dir_general *d_stats) +/** + * ls3_stats_fprintf_out - Print directory size statistics to a report file. + * + * @param d_stats General statistics object for dirs. + * @param out_fd Output file stream. + */ +void ls3_stats_fprintf_out(struct ls3_stats_dir_general *d_stats, FILE *out_fd) { - struct ls3_stats_dir_rating *heap = d_stats->lsdg_top_size; - struct fstats_report *d_fstats = d_stats->lsdg_files_report; - int i; + struct fstats_report *f_stats = d_stats->lsdg_files_report; + + if (!d_stats) + return; + + if (!d_stats->lsdg_start_dir) + return; + + if (!out_fd || !d_stats->lsdg_start_dir) + return; + + fprintf(out_fd, + "\n\n\nDirectory statistics:\n" + "Start path: '%s'\n" + "Max depth for output: %u\n" + "Size:%s\n", + (strlen(d_stats->lsdg_start_path) == 0) ? + f_stats->client_mount_path : d_stats->lsdg_start_path, + d_stats->lsdg_max_depth, + ls3_stats_fmt_size_units(d_stats->lsdg_total_size)); + + fprintf(out_fd, "Allocated size:%s\n\n", + ls3_stats_fmt_size_units(d_stats->lsdg_total_alloc_size)); + + fprintf(out_fd, + "_Alloc_Size_ ____Size____ __Files_Count__ ___Dirs_Count__" + " _____________FID______________" + " _____________Structure_and_directory_name________________\n"); + + ls3_stats_fprintf_out_recursive(out_fd, d_stats, + d_stats->lsdg_start_dir, false); + fprintf(out_fd, + "_Alloc_Size_ ____Size____ __Files_Count__ ___Dirs_Count__" + " _____________FID______________" + " _____________Structure_and_directory_name________________\n"); + + if (!d_stats->lsdg_top_size) { + LS3_WARNING("the size of the rating table has not been " + "specified or is equal to 0, the rating table " + "will not be built\n"); + return; + } fprintf(out_fd, "\n\nTop %d largest directories:\n", d_stats->lsdg_top_rating_limit); - fprintf(out_fd, "____Size____ _Alloc_Size_ __Files_Count__" + + fprintf(out_fd, "_Alloc_Size_ ____Size____ __Files_Count__" " ___Dirs_Count__ __User_ID___ _____________FID______________" " ____________________Directory_name_______________________\n"); - for (i = 0; i < heap->lsdr_current_size_heap; i++) { - uint64_t allocate_dir_size; - char fid_str[64]; - char path[PATH_MAX] = ""; - char tmp_alocte_size_str[LS3_STATS_NUM_STR_MAX_WITH_NULL]; - int rc; + ls3_stats_fprintf_out_recursive(out_fd, d_stats, + d_stats->lsdg_start_dir, true); - if (heap->lsdr_array[i]->lsdo_depth < 0) - continue; /* skip first dir */ + fprintf(out_fd, "_Alloc_Size_ ____Size____ __Files_Count__" + " ___Dirs_Count__ __User_ID___ _____________FID______________" + " ____________________Directory_name_______________________\n"); +} - allocate_dir_size = - heap->lsdr_array[i]->lsdo_alloc_size_in_sectors * 512; - /* prepare FID */ - snprintf(fid_str, sizeof(fid_str), DFID_NOBRACE, - PFID(&heap->lsdr_array[i]->lsdo_fid)); +/** + * ls3_stats_prepare_dir_recursive - Prepare directory statistics recursively. + * + * This function recursively traverses the directory tree, calculates total size, + * and prepares rating table. + * + * @param stats General statistics object for dirs. + * @param dir_ptr Current directory object. + * @param total_size Pointer to the total size value. + * @param total_alloc_size Pointer to the total allocated size value. + */ +static void ls3_stats_prepare_dir_recursive(struct ls3_stats_dir_general *stats, + struct ls3_stats_dir_obj *dir_ptr, + uint64_t *total_size, + uint64_t *total_alloc_size) +{ + uint64_t allocate_dir_size = 0; + int i; - snprintf(tmp_alocte_size_str, sizeof(tmp_alocte_size_str), - "%s", ls3_stats_fmt_size_units(allocate_dir_size)); + allocate_dir_size = dir_ptr->lsdo_alloc_size_in_sectors * 512; + if (dir_ptr->lsdo_depth == 0) { + *total_size += dir_ptr->lsdo_size; + *total_alloc_size += allocate_dir_size; + } - if (heap->lsdr_array[i]->lsdo_fid.f_seq != 0 && - !d_fstats->merging) { - rc = llapi_fid2path(d_fstats->client_mount_path, - fid_str, path, PATH_MAX, NULL, NULL); - if (rc != 0) - llapi_error(LLAPI_MSG_ERROR, rc, - "cannot get path of fid %s", fid_str); - } + /* Add in the LS3_STATS_TYPE_DIRECTORY_SIZE_KB table. + * This table includes only directories from this report, i.e. only + * those that are less than the maximum declared depth + */ + ls3_stats_update_range(stats->lsdg_files_report, + LS3_STATS_TYPE_DIRECTORY_SIZE_KB, + allocate_dir_size, LS3_STATS_EMPTY_VALUE); - fprintf(out_fd, "%12s %12s %15u %15u %12u %30s %s\n", - ls3_stats_fmt_size_units(heap->lsdr_array[i]->lsdo_size), - tmp_alocte_size_str, - heap->lsdr_array[i]->lsdo_files_count, - heap->lsdr_array[i]->lsdo_dirs_count, - heap->lsdr_array[i]->lsdo_uid, - fid_str, - strlen(path) > 0 ? path : heap->lsdr_array[i]->lsdo_name); - } + /* Trying to add a directory to the rating table */ + if (stats->lsdg_top_size) + ls3_stats_insert_heap(stats->lsdg_top_size, dir_ptr); - fprintf(out_fd, "____________ ____________ _______________" - " _______________ ____________ ______________________________" - " _________________________________________________________\n"); + for (i = 0; i < dir_ptr->lsdo_last_child + 1; i++) { + struct ls3_stats_dir_obj *child_ptr; + + child_ptr = dir_ptr->lsdo_child[i]; + if (child_ptr == NULL) + continue; + + ls3_stats_prepare_dir_recursive(stats, child_ptr, total_size, + total_alloc_size); + } } -/* ls3_stats_fprintf_out - Initiates the process of printing directory - * size statistics in an easy-to-read format into a general stats report - * with the *.out extension. +/** + * ls3_stats_prepare_dirs - Prepare directory statistics for printing. + * + * This function prepares the directory statistics contained in `d_stats` + * for printing to a file, creates a table with TOP-X rating. + * + * @param d_stats General statistics object for dirs. */ -void ls3_stats_fprintf_out(struct ls3_stats_dir_general *d_stats, FILE *out_fd) +void ls3_stats_prepare_dirs(struct ls3_stats_dir_general *d_stats) { - uint64_t total_size; - uint64_t total_alloc_size; - char tmp_alocte_size_str[LS3_STATS_NUM_STR_MAX_WITH_NULL]; - struct fstats_report *f_stats = d_stats->lsdg_files_report; + struct fstats_report *files_report = d_stats->lsdg_files_report; + struct report_template *dir_report_ptr; + uint64_t total_size = 0; + uint64_t total_alloc_size = 0; if (!d_stats) return; @@ -368,44 +461,26 @@ void ls3_stats_fprintf_out(struct ls3_stats_dir_general *d_stats, FILE *out_fd) return; ls3_stats_init_heap(d_stats); - fprintf(out_fd, - "\n\nDirectory statistics for: '%s' [files count:%u size:%s]\n", - d_stats->lsdg_start_path, - d_stats->lsdg_start_dir->lsdo_files_count, - ls3_stats_fmt_size_units(d_stats->lsdg_start_dir->lsdo_size)); - - fprintf(out_fd, - "____Size____ _Alloc_Size_ __Files_Count__ ___Dirs_Count__" - " _____________FID______________" - " _____________Structure_and_directory_name________________\n"); - - ls3_stats_fprintf_out_recursive(out_fd, d_stats, d_stats->lsdg_start_dir, - false, &total_size, &total_alloc_size); - fprintf(out_fd, - "____________ ____________ _______________ _______________" - " ______________________________" - " _________________________________________________________\n"); - - snprintf(tmp_alocte_size_str, sizeof(tmp_alocte_size_str), - "%s", ls3_stats_fmt_size_units(total_alloc_size)); + ls3_stats_prepare_dir_recursive(d_stats, d_stats->lsdg_start_dir, + &total_size, &total_alloc_size); - fprintf(out_fd, - "Total size of directories on %s: %s | allocate size: %s", - f_stats->device_name, - ls3_stats_fmt_size_units(total_size), - tmp_alocte_size_str); - /* Update total size counters for next reports (*.all) */ - d_stats->lsdg_total_size = total_size; + /* Update total size counters */ + total_alloc_size += + d_stats->lsdg_start_dir->lsdo_alloc_size_in_sectors * 512; d_stats->lsdg_total_alloc_size = total_alloc_size; + d_stats->lsdg_total_size = total_size + + d_stats->lsdg_start_dir->lsdo_size; - if (d_stats->lsdg_top_size) { + /* Update the size to the correct one, since when updating in + * ls3_stats_update_range(), this function added all the sizes into one, + * but only need the sizes of directories with a depth of 0. + */ + dir_report_ptr = files_report->reports[LS3_STATS_TYPE_DIRECTORY_SIZE_KB]; + dir_report_ptr->total_value = total_alloc_size >> 10; /* In Kb */ + + if (d_stats->lsdg_top_size) + /* Deprecated, but still works for JSON formatted reports */ ls3_stats_heap_sort(d_stats->lsdg_top_size); - ls3_stats_printf_rating_out(out_fd, d_stats); - } else { - LS3_WARNING("the size of the rating table has not been " - "specified or is equal to 0, the rating table " - "will not be built\n"); - } } /* ls3_stats_fprintf_dir_json_recursive - Recursively traverse a directory tree @@ -414,10 +489,7 @@ void ls3_stats_fprintf_out(struct ls3_stats_dir_general *d_stats, FILE *out_fd) */ static struct json_object *ls3_stats_fprintf_dir_json_recursive( struct ls3_stats_dir_general *d_stats, - struct ls3_stats_dir_obj *dir_ptr, - bool top_rating_only, - uint64_t *total_size, - uint64_t *total_alloc_size) + struct ls3_stats_dir_obj *dir_ptr) { struct json_object *jobj_dir_obj; struct json_object *jobj_dir_child; @@ -426,19 +498,12 @@ static struct json_object *ls3_stats_fprintf_dir_json_recursive( int i; jobj_dir_obj = json_object_new_object(); - jobj_dir_child = json_object_new_array(); - if (dir_ptr == NULL) return jobj_dir_obj; - if (dir_ptr->lsdo_depth == 0) { - *total_size += dir_ptr->lsdo_size; - *total_alloc_size += dir_ptr->lsdo_alloc_size_in_sectors * 512; - } - + jobj_dir_child = json_object_new_array(); if (dir_ptr->lsdo_depth >= 0 && - dir_ptr->lsdo_size >= d_stats->lsdg_min_size_value_for_print && - !top_rating_only) { + dir_ptr->lsdo_size >= d_stats->lsdg_min_size_value_for_print) { uint64_t allocate_dir_size; char fid_str[60]; char path[PATH_MAX] = ""; @@ -454,7 +519,8 @@ static struct json_object *ls3_stats_fprintf_dir_json_recursive( fid_str, path, PATH_MAX, NULL, NULL); if (rc != 0) llapi_error(LLAPI_MSG_ERROR, rc, - "cannot get path of fid %s", fid_str); + "cannot get path of fid %s\n", + fid_str); } json_object_object_add(jobj_dir_obj, "SizeBytes", @@ -503,12 +569,6 @@ static struct json_object *ls3_stats_fprintf_dir_json_recursive( json_object_new_string(path)); } - /* Trying to add a directory to the rating table */ - if (d_stats->lsdg_top_size && - !(f_stats->report_extension & LS3_STATS_FILE_EXTENSION_OUT)) { - ls3_stats_insert_heap(d_stats->lsdg_top_size, dir_ptr); - } - /* We always have at least 10 pointers in stock dir_ptr->lsdo_child[] */ for (i = 0; i < dir_ptr->lsdo_last_child + 1; i++) { struct json_object *tmp_jobj_dir_obj; @@ -518,16 +578,13 @@ static struct json_object *ls3_stats_fprintf_dir_json_recursive( continue; tmp_jobj_dir_obj = - ls3_stats_fprintf_dir_json_recursive(d_stats, child_ptr, - top_rating_only, - total_size, - total_alloc_size); + ls3_stats_fprintf_dir_json_recursive(d_stats, child_ptr); json_object_array_add(jobj_dir_child, tmp_jobj_dir_obj); } - json_object_object_add(jobj_dir_obj, - "ChildDirectories", jobj_dir_child); + json_object_object_add(jobj_dir_obj, "ChildDirectories", + jobj_dir_child); return jobj_dir_obj; } @@ -537,11 +594,8 @@ struct json_object *ls3_stats_fprintf_dirs_json( struct fstats_report *d_fstats = d_stats->lsdg_files_report; struct json_object *jobj_dirs_rating; struct json_object *jobj_objects; /* Rating */ - struct json_object *jobj_tree; + struct json_object *jobj_tree = NULL; struct ls3_stats_dir_rating *heap; - uint64_t total_size; - uint64_t total_alloc_size; - int extension = d_fstats->report_extension; int i; if (!d_stats) @@ -550,19 +604,13 @@ struct json_object *ls3_stats_fprintf_dirs_json( if (!d_stats->lsdg_start_dir) return NULL; - ls3_stats_init_heap(d_stats); if (!d_stats->lsdg_top_size) return NULL; jobj_dirs_rating = json_object_new_object(); - jobj_tree = ls3_stats_fprintf_dir_json_recursive(d_stats, - d_stats->lsdg_start_dir, - false, &total_size, - &total_alloc_size); - - if (!(extension & LS3_STATS_FILE_EXTENSION_OUT)) - ls3_stats_heap_sort(d_stats->lsdg_top_size); - + jobj_tree = + ls3_stats_fprintf_dir_json_recursive(d_stats, + d_stats->lsdg_start_dir); heap = d_stats->lsdg_top_size; jobj_objects = json_object_new_array(); if (!jobj_objects) { @@ -648,10 +696,10 @@ struct json_object *ls3_stats_fprintf_dirs_json( json_object_new_int(d_stats->lsdg_top_rating_limit)); json_object_object_add(jobj_dirs_rating, "TotalSizeBytes", - json_object_new_int64(total_size)); + json_object_new_int64(d_stats->lsdg_total_size)); json_object_object_add(jobj_dirs_rating, "TotalAllocatedSizeBytes", - json_object_new_int64(total_alloc_size)); + json_object_new_int64(d_stats->lsdg_total_alloc_size)); json_object_object_add(jobj_dirs_rating, "RatingMinSizeBytes", json_object_new_int64(heap->lsdr_min_size)); @@ -761,6 +809,7 @@ struct ls3_stats_dir_obj new_dir_ptr->lsdo_child_max = LS3_STATS_DIR_COUNT_BY_DEFAULT; new_dir_ptr->lsdo_depth = depth; new_dir_ptr->lsdo_name = xstrdup(dir_name); + new_dir_ptr->lsdo_top_rate = false; rc = pthread_mutex_init(&new_dir_ptr->lsdo_mutex, NULL); if (rc != 0) LS3_FATAL("failed to initialize mutex\n"); diff --git a/lipe/src/lipe_scan3/ls3_dir_stats.h b/lipe/src/lipe_scan3/ls3_dir_stats.h index 7dbc220..6c6dcef 100644 --- a/lipe/src/lipe_scan3/ls3_dir_stats.h +++ b/lipe/src/lipe_scan3/ls3_dir_stats.h @@ -51,6 +51,7 @@ struct ls3_stats_dir_obj { uint16_t lsdo_compress_type; int16_t lsdo_depth; /* Current object depth */ char *lsdo_name; + bool lsdo_top_rate; struct ls3_stats_dir_obj **lsdo_child; }; @@ -89,6 +90,7 @@ extern struct ls3_stats_dir_general *dir_stats; const char *ls3_stats_fmt_size_units(uint64_t bytes); void ls3_stats_fprintf_out(struct ls3_stats_dir_general *d_stats, FILE *out_fd); +void ls3_stats_prepare_dirs(struct ls3_stats_dir_general *d_stats); struct json_object *ls3_stats_fprintf_dirs_json( struct ls3_stats_dir_general *d_stats); struct ls3_stats_dir_obj *ls3_stats_allocate_new_dir( diff --git a/lipe/src/lipe_scan3/ls3_stats.c b/lipe/src/lipe_scan3/ls3_stats.c index c0436e8..41bec2c 100644 --- a/lipe/src/lipe_scan3/ls3_stats.c +++ b/lipe/src/lipe_scan3/ls3_stats.c @@ -1954,6 +1954,7 @@ void ls3_stats_printf(struct fstats_report *report, "%Y-%m-%d %H:%M:%S", time_info); /* Do all the necessary calculations */ + ls3_stats_prepare_dirs(dir_report); ls3_stats_calculate_values(report); ls3_stats_prepare_file(report); -- 1.8.3.1