static const char LF3_SCM_SCAN_PROC[] = "lipe-scan";
static char *lf3_policy_body;
static bool lf3_policy_body_has_action;
+static bool lf3_policy_has_depth;
+static char *lf3_depth_arg_val;
+static bool lf3_policy_has_top_rating;
+static char *lf3_top_rating_arg_val;
+static bool lf3_stats_has_start_path;
+static char *lf3_stats_start_path;
typedef unsigned long long __ull;
assert(unit == 1);
+ if (strcmp(thunk, "depth") == 0) {
+ lf3_policy_has_depth = true;
+ lf3_depth_arg_val = xsprintf("%llu", val);
+ /* skip it */
+ return xsprintf("");
+ } else if (strcmp(thunk, "top-rating") == 0) {
+ lf3_policy_has_top_rating = true;
+ lf3_top_rating_arg_val = xsprintf("%llu", val);
+ /* skip it */
+ return xsprintf("");
+ } else if (strcmp(thunk, "spath") == 0) {
+ /* value doesn't make sense here */
+ lf3_stats_has_start_path = true;
+ return xsprintf("");
+ }
+
return xsprintf("(%c (%s) %llu)", cmp, thunk, val);
}
{
assert(begin + 2 == end);
+ /* copy path for size statistics, since it will
+ * no longer be available later. */
+ lf3_stats_has_start_path = true;
+ lf3_stats_start_path = xsprintf("\"%s\"", lf3_arg[begin + 1]);
+ LF3_DEBUG_S(lf3_stats_start_path);
+
return lf3_fnmatch_expr(LF3_FNMATCH, lf3_arg[begin + 1], "call-with-relative-path");
}
X2("gid", lf3_numeric_expr("gid", begin, end));
X2("projid", lf3_numeric_expr("projid", begin, end));
X2("links", lf3_numeric_expr("nlink", begin, end));
+ X2("depth", lf3_numeric_expr("depth", begin, end));
+ X2("top-rating", lf3_numeric_expr("top-rating", begin, end));
X2("mirror-count", lf3_numeric_expr("lov-mirror-count", begin, end));
X2("stripe-count", lf3_numeric_expr("lov-stripe-count", begin, end));
LF3_DEBUG_S(lf3_policy_body);
LF3_DEBUG_B(lf3_policy_body_has_action);
+ if (!lf3_policy_has_depth)
+ lf3_depth_arg_val = "(lipe-getopt-stats-depth)";
+
+ if (!lf3_policy_has_top_rating)
+ lf3_top_rating_arg_val = "(lipe-getopt-top-rating)";
+
+ if (!lf3_stats_has_start_path)
+ lf3_stats_start_path = "(lipe-getopt-spath)";
+
if (rc != 0 || lf3_policy_body == NULL)
LF3_FATAL("internal argument parsing error\n");
" %s\n"
" %s\n"
" %s\n"
+ " %s\n"
+ " %s\n"
+ " %s\n"
" %s))\n"
" (lambda () %K)))\n",
&lf3_genvar_list,
policy_thunk,
"(lipe-getopt-required-attrs)",
thread_count,
+ lf3_depth_arg_val,
+ lf3_top_rating_arg_val,
+ lf3_stats_start_path,
&lf3_fini_list);
LF3_DEBUG_S(scm_code);
#include "ls3_object_attrs.h"
#include "ls3_scan.h"
#include "ls3_stats.h"
+#include "ls3_dir_stats.h"
#define LS3_MODULE_NAME "lipe"
#define LS3_SCAN "lipe-scan"
#define LS3_GETOPT_CLIENT_MOUNT_PATH "lipe-getopt-client-mount-path"
#define LS3_GETOPT_REQUIRED_ATTRS "lipe-getopt-required-attrs"
#define LS3_GETOPT_THREAD_COUNT "lipe-getopt-thread-count"
+#define LS3_GETOPT_STATS_DEPTH "lipe-getopt-stats-depth"
+#define LS3_GETOPT_TOP_RATING "lipe-getopt-top-rating"
+#define LS3_GETOPT_SPATH "lipe-getopt-spath"
static const char *ls3_device_path;
static const char *ls3_client_mount_path = LS3_CSTR_AUTO;
return scm_from_bool(old_warn);
}
-SCM_DEFINE(ls3_scm_gettid, "lipe-gettid", 0, 0, 0, (), "print caller's thread ID (not pthread id)")
+SCM_DEFINE(ls3_scm_gettid, "lipe-gettid", 0, 0, 0, (),
+ "print caller's thread ID (not pthread id)")
{
return scm_from_ulong(syscall(SYS_gettid));
}
}
#undef FUNC_NAME
-SCM_DEFINE(ls3_scm_getopt_device_path, LS3_GETOPT_DEVICE_PATH, 0, 0, 0, (), "return device path from options or #f")
+SCM_DEFINE(ls3_scm_getopt_device_path, LS3_GETOPT_DEVICE_PATH, 0, 0, 0, (),
+ "return device path from options or #f")
{
if (ls3_device_path != NULL)
return scm_from_latin1_string(ls3_device_path);
}
/* Global command line options accessors. */
-SCM_DEFINE(ls3_scm_getopt_client_mount_path, LS3_GETOPT_CLIENT_MOUNT_PATH, 0, 0, 0, (), "return client mount path from options")
+SCM_DEFINE(ls3_scm_getopt_client_mount_path, LS3_GETOPT_CLIENT_MOUNT_PATH, 0, 0,
+ 0, (), "return client mount path from options")
{
/* Normally this should just return #t to tell lipe-scan to
* try infer the client mount from the device.
return scm_from_latin1_string(ls3_client_mount_path);
}
-SCM_DEFINE(ls3_scm_getopt_required_attrs, LS3_GETOPT_REQUIRED_ATTRS, 0, 0, 0, (), "return required object attrs from options")
+SCM_DEFINE(ls3_scm_getopt_required_attrs, LS3_GETOPT_REQUIRED_ATTRS, 0, 0, 0, (),
+ "return required object attrs from options")
{
return scm_from_uint(ls3_required_attrs);
}
-SCM_DEFINE(ls3_scm_getopt_thread_count, LS3_GETOPT_THREAD_COUNT, 0, 0, 0, (), "return thread count from options")
+SCM_DEFINE(ls3_scm_getopt_thread_count, LS3_GETOPT_THREAD_COUNT, 0, 0, 0, (),
+ "return thread count from options")
{
return scm_from_int(ls3_thread_count);
}
+SCM_DEFINE(ls3_scm_getopt_stats_depth, LS3_GETOPT_STATS_DEPTH, 0, 0, 0, (),
+ "return depth for stats from options")
+{
+ return scm_from_int(0);
+}
+
+SCM_DEFINE(ls3_scm_getopt_top_rating, LS3_GETOPT_TOP_RATING, 0, 0, 0, (),
+ "return N for top rating directory in stats from options")
+{
+ return scm_from_int(0);
+}
+
+SCM_DEFINE(ls3_scm_getopt_spath, LS3_GETOPT_SPATH, 0, 0, 0, (),
+ "return filtr 'path' for directory stats")
+{
+ return scm_from_latin1_string("");
+}
+
/* Scanning context (instance and tread info) accessors. */
/* To be called when scheme procedures that depend on the scanning
return SCM_UNSPECIFIED;
}
-SCM_DEFINE(ls3_scm_scan, LS3_SCAN, 5, 0, 0,
+SCM_DEFINE(ls3_scm_scan, LS3_SCAN, 8, 0, 0,
(SCM s_device_path,
SCM s_client_mount_path,
SCM s_policy_thunk,
SCM s_required_attrs,
- SCM s_thread_count),
+ SCM s_thread_count,
+ SCM s_stats_depth,
+ SCM s_stats_top_rating,
+ SCM s_stats_spath),
"scan a device")
#define FUNC_NAME s_ls3_scm_scan
{
char *c_device_path = NULL;
+ char *c_stats_spath = NULL;
const char *c_client_mount_path = NULL;
char *c_client_mount_path_1 = NULL;
unsigned int c_required_attrs;
int c_thread_count;
+ int c_stats_depth;
+ int c_stats_top_rating;
int rc;
SCM_VALIDATE_STRING(1, s_device_path);
SCM_VALIDATE_THUNK(3, s_policy_thunk);
SCM_VALIDATE_UINT_COPY(4, s_required_attrs, c_required_attrs);
SCM_VALIDATE_INT_COPY(5, s_thread_count, c_thread_count);
+ SCM_VALIDATE_INT_COPY(6, s_stats_depth, c_stats_depth);
+ SCM_VALIDATE_INT_COPY(7, s_stats_top_rating, c_stats_top_rating);
+ SCM_VALIDATE_STRING(8, s_stats_spath);
+ c_stats_spath = scm_to_latin1_string(s_stats_spath);
LS3_DEBUG_S(c_device_path);
LS3_DEBUG_S(c_client_mount_path);
LS3_DEBUG_X(c_required_attrs);
LS3_DEBUG_D(c_thread_count);
+ LS3_DEBUG_D(c_stats_depth);
+ LS3_DEBUG_D(c_stats_top_rating);
+ LS3_DEBUG_D(c_stats_spath);
+
+ if (c_stats_spath[0] != '\0') {
+ size_t len = strlen(c_stats_spath);
+
+ if (len > 0 && c_stats_spath[len - 1] == '*') {
+ c_stats_spath[len - 1] = '\0';
+ dir_stats->lsdg_start_path = xstrdup(c_stats_spath);
+ }
+ } else {
+ dir_stats->lsdg_start_path = xstrdup("");
+ }
+
+ if (c_stats_depth == 0)
+ dir_stats->lsdg_max_depth = LS3_STATS_DEPTH_BY_DEFAULT;
+ else
+ dir_stats->lsdg_max_depth = c_stats_depth;
+
+ if (c_stats_top_rating == 0)
+ dir_stats->lsdg_top_rating_limit =
+ LS3_STATS_TOP_RATING_BY_DEFAULT;
+ else
+ dir_stats->lsdg_top_rating_limit = c_stats_top_rating;
rc = ls3_scan(c_device_path,
c_client_mount_path,
"lipe-getopt-device-path",
"lipe-getopt-required-attrs",
"lipe-getopt-thread-count",
+ "lipe-getopt-stats-depth",
+ "lipe-getopt-top-rating",
+ "lipe-getopt-spath",
"lipe-warnings-get-attr-enable",
"lipe-scan",
"lipe-scan-break",
int exit_status = EXIT_SUCCESS;
ls3_stats_init();
+ ls3_stats_dir_init();
if (policy != NULL) {
int i;
scm_call_0(X(LS3_GETOPT_CLIENT_MOUNT_PATH)),
X(policy),
scm_call_0(X(LS3_GETOPT_REQUIRED_ATTRS)),
- scm_call_0(X(LS3_GETOPT_THREAD_COUNT)));
+ scm_call_0(X(LS3_GETOPT_THREAD_COUNT)),
+ scm_call_0(X(LS3_GETOPT_STATS_DEPTH)),
+ scm_call_0(X(LS3_GETOPT_TOP_RATING)),
+ scm_call_0(X(LS3_GETOPT_SPATH)));
#undef X
scan_status = ls3_scm_to_exit_status(scan_rc);
LS3_DEBUG_D(scan_status);
ls3_counters_print();
ls3_stats_destroy();
+ ls3_stats_dir_destroy();
LS3_DEBUG_D(exit_status);
exit(exit_status);
}