From f274598c7c1d85d1815807ad5bc6b1314aaa3ad8 Mon Sep 17 00:00:00 2001 From: Vitaliy Kuznetsov Date: Mon, 19 Feb 2024 20:02:44 +0100 Subject: [PATCH] EX-8130 lipe: Add func for working with paths MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This patсh adds directory path processing helper functions that will be used later to collect directory size statistics. These functions set the stage for working on increasing the size counters for each directory, along the entire chain in the file or directory path. Test-Parameters: trivial Signed-off-by: Vitaliy Kuznetsov Change-Id: I6e7302e9771dce2933c6730a1117fec3bc2b0fda Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/53961 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Alexandre Ioffe Reviewed-by: Andreas Dilger --- lipe/src/lipe_scan3/ls3_dir_stats.c | 123 ++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/lipe/src/lipe_scan3/ls3_dir_stats.c b/lipe/src/lipe_scan3/ls3_dir_stats.c index 000f001..9725b1af 100644 --- a/lipe/src/lipe_scan3/ls3_dir_stats.c +++ b/lipe/src/lipe_scan3/ls3_dir_stats.c @@ -321,6 +321,129 @@ static void ls3_stats_init_first_dir(char *path) free(tmp_path); } +/* ls3_get_trimmed_path_and_depth - Trims the desired path. + * For example, when we have a “path” filter, it contains a path, + * but this does not mean that the resulting path from the attribute + * will not contain this path, so we need to trim the path from the + * filter and leave only the final path. + * + * ex: (/path/from/filter/dir1/dir11/dir111/file -> dir1/dir11/dir111/file) + */ +static void + ls3_stats_get_trimmed_path_and_depth(struct ls3_object_attrs *loa_all, + char *path, char **trimmed_path, + int *depth) +{ + char *sub_path = NULL; + const char *original_sub_path; + const char *last_slash; + const char *last_sub_path_slash = NULL; + size_t offset_from_start; + int count = 0; + + if (!path || !dir_stats->lsdg_start_path) + LS3_FATAL("path name or start path is NULL\n"); + + /* Find the last slash in dir_stats->lsdg_start_path */ + last_slash = strrchr(dir_stats->lsdg_start_path, '/'); + + /* if there is no slash, then simply cut it off to the beginning + * of dir_stats->lsdg_start_path + */ + if (!last_slash) { + sub_path = path; + } else { + offset_from_start = last_slash - dir_stats->lsdg_start_path + 1; + sub_path = path + offset_from_start; + } + + original_sub_path = sub_path; + + /* Calculate the depth and at the same time look + * for the last slash in sub_path (for subsequent cutting) + */ + while (*sub_path) { + if (*sub_path == '/') { + count++; + last_sub_path_slash = sub_path; + } + sub_path++; + } + + if ((loa_all->loa_mode & S_IFDIR) && + (last_sub_path_slash != sub_path + strlen(sub_path) - 1)) + count++; + else if (last_sub_path_slash == sub_path + strlen(sub_path) - 1) + count--; + + *depth = (count == 0) ? 0 : count; + + /* Trim the path to the last slash, if it exists */ + if (loa_all->loa_mode & S_IFDIR) + *trimmed_path = xstrdup(original_sub_path); + else if (last_sub_path_slash) + *trimmed_path = xstrndup(original_sub_path, + last_sub_path_slash - + original_sub_path); + else + *trimmed_path = xstrdup(original_sub_path); +} + +/* ls3_stats_dir_split_path - Splits a path into an array of names. + * Ex: dir1/dir11/dir111/dir1111/file -> ["dir1", "dir11", "dir111"] + * This is necessary in order to track the entire chain of pointers + * and increase the size counters in the future, but not more than + * the maximum specified depth. + */ +static char** ls3_stats_dir_split_path(const char *path, int *count) +{ + const char *tmp_patch = path; + int max_depth = dir_stats->lsdg_max_depth; + int dir_count = 0; + char **result; + int i; + + *count = 0; + if (!path || max_depth <= 0) + return NULL; + + if (strlen(path) == 0) + return NULL; + + + while (*tmp_patch) { + if (*tmp_patch == '/') + dir_count++; + + tmp_patch++; + } + + tmp_patch = path; /* pointer reset */ + dir_count++; + + if (dir_count < max_depth) + max_depth = dir_count; + + result = (char**)xcalloc(max_depth, sizeof(char*)); + for (i = 0; i < max_depth; i++) { + const char *next_slash = strchr(tmp_patch, '/'); + size_t length = next_slash ? (next_slash - tmp_patch) : + (path + strlen(path) - tmp_patch); + + result[i] = (char*) xcalloc(length + 1, sizeof(char)); + strncpy(result[i], tmp_patch, length); + result[i][length] = '\0'; + + if (!next_slash) + break; + + tmp_patch = next_slash + 1; + } + + *count = max_depth; + return result; +} + void ls3_stats_dir_init(void) { int rc; -- 1.8.3.1