return TOKEN_TEST;
}
--(amin|atime|blocks|cmin|crtime|ctime|gid|group|iname|inum|links|mirror-count|mmin|mtime|name|path|perm|pool|projid|size|stripe-count|type|uid|user)\0 {
+-(amin|atime|blocks|cmin|crtime|ctime|gid|group|iname|inum|links|mirror-count|mmin|mtime|name|path|perm|pool|projid|size|stripe-count|type|uid|user|xattr)\0 {
LF3_DEBUG("unary '%s'\n", yytext);
expr_arg_begin = lf3_arg_index;
expr_arg_end = lf3_arg_index + 2;
BEGIN ARG;
}
+-(xattr-match)\0 {
+ LF3_DEBUG("binary '%s'\n", yytext);
+ expr_arg_begin = lf3_arg_index;
+ expr_arg_end = lf3_arg_index + 3;
+ expr_arg_type = TOKEN_TEST;
+ BEGIN ARG;
+}
+
-(fprint|fprint0|print-json|printf)\0 {
LF3_DEBUG("unary '%s'\n", yytext);
expr_arg_begin = lf3_arg_index;
return xsprintf("(member %Q (lov-pools))", lf3_arg[begin + 1]);
}
+static char *lf3_xattr_expr(int begin, int end)
+{
+ assert(begin + 2 == end);
+
+ return xsprintf("(xattr? %Q)", lf3_arg[begin + 1]);
+}
+
+static char *lf3_xattr_match_expr(int begin, int end)
+{
+ const char *name = lf3_arg[begin + 1];
+ const char *value = lf3_arg[begin + 2];
+
+ assert(begin + 3 == end);
+
+ /* Strength reduction. Note we use equal? instead of string=?
+ * since xattr-ref-string will return #f when xattr is not
+ * present. */
+ if (strpbrk(name, "?*[") == NULL && strpbrk(value, "?*[") == NULL)
+ return xsprintf("(equal? (xattr-ref-string %Q) %Q)", name, value);
+
+ return xsprintf("(xattr-match? %Q %Q)", name, value);
+}
+
static char *lf3_exec_plus_expr(int begin, int end)
{
char *expr = NULL;
X2("false", xstrdup("#f"));
X2("wholename", lf3_path_expr(begin, end));
X2("iwholename", lf3_ipath_expr(begin, end));
+ X2("xattr", lf3_xattr_expr(begin, end));
+ X2("xattr-match", lf3_xattr_match_expr(begin, end));
X2("print-json", lf3_print_json_expr(begin, end));
X2("quit", "(lipe-scan-break 0)");
strcmp(ext, "mirror-count") == 0)
LF3_EMIT_N('d', "(%s)", ext);
else if (strstartswith(ext, "xattr:"))
- LF3_EMIT_S('a', "(xattr-ref-string %Q)", ext + strlen("xattr:"));
+ LF3_EMIT_S('a', "(or (xattr-ref-string %Q) %Q)", ext + strlen("xattr:"), "");
else
LF3_FATAL_AT_OFFSET(index, n, "unrecognized format directive '%s'\n", ext);
user
group
xattr-ref-string
+ xattr-match?
))
(define-inlinable (any1 proc lis)
(define (group)
(%lipe-gid->group (gid)))
+(define (bytevector->latin1 bv)
+ (bytevector->string bv "latin1"))
+
+(define (xattr-match? name value)
+ (any1 (lambda (par)
+ (and (fnmatch? name (car par))
+ (fnmatch? value (bytevector->latin1 (cdr par)))))
+ (xattrs)))
+
(define (xattr-ref-string name)
- (utf8->string (or (xattr-ref name) #vu8())))
+ (and=> (xattr-ref name) bytevector->latin1))
snprintf(buf, sizeof(buf), DFID, PFID(fid));
if (scm_is_eq(port, SCM_BOOL_F))
- return scm_from_locale_string(buf);
+ return scm_from_latin1_string(buf);
if (scm_is_eq(port, SCM_BOOL_T))
port = scm_current_output_port();
char *c_pattern = NULL;
char *c_string = NULL;
int c_flags;
+ int rc;
SCM_VALIDATE_STRING(1, pattern);
- c_pattern = scm_to_locale_string(pattern);
+ c_pattern = scm_to_latin1_string(pattern);
SCM_VALIDATE_STRING(2, string);
- c_string = scm_to_locale_string(string);
+ c_string = scm_to_latin1_string(string);
if (SCM_UNBNDP(flags))
c_flags = 0;
else
SCM_VALIDATE_INT_COPY(3, flags, c_flags);
- return fnmatch(c_pattern, c_string, c_flags) == 0 ? SCM_BOOL_T : SCM_BOOL_F;
+ rc = fnmatch(c_pattern, c_string, c_flags);
+
+ free(c_pattern);
+ free(c_string);
+
+ return rc == 0 ? SCM_BOOL_T : SCM_BOOL_F;
}
#undef FUNC_NAME
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_locale_string(ls3_device_path);
+ return scm_from_latin1_string(ls3_device_path);
return SCM_BOOL_F;
}
else if (ls3_client_mount_path == LS3_CSTR_NONE)
return SCM_BOOL_F;
else
- return scm_from_locale_string(ls3_client_mount_path);
+ 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")
lipe_list_for_each_entry_reverse(lle, &loa->loa_links, lle_linkage)
lis = scm_cons(scm_cons(ls3_scm_from_fid(&lle->lle_parent_fid),
- scm_from_locale_string(lle->lle_name)),
+ scm_from_latin1_string(lle->lle_name)),
lis);
return lis;
lipe_list_for_each_entry_reverse(lpe, &loa->loa_paths, lpe_linkage) {
path = path_append_2(li->li_client_mount_path, lpe->lpe_path);
- lis = scm_cons(scm_from_locale_string(path), lis);
+ lis = scm_cons(scm_from_latin1_string(path), lis);
free(path);
}
SCM lis = SCM_EOL;
lipe_list_for_each_entry_reverse(lpe, &loa->loa_paths, lpe_linkage)
- lis = scm_cons(scm_from_locale_string(lpe->lpe_path), lis);
+ lis = scm_cons(scm_from_latin1_string(lpe->lpe_path), lis);
return lis;
}
+SCM_DEFINE(ls3_scm_xattr_p, "xattr?", 1, 0, 0,
+ (SCM s_name), "return #f if current file has xattr name")
+#define FUNC_NAME s_ls3_scm_xattr_p
+{
+ struct ls3_object_attrs *loa = ls3_attrs(LS3_OBJECT_ATTR_XATTRS);
+ const struct lipe_xattr *lx;
+ char *c_name = NULL;
+ SCM rc = SCM_BOOL_F;
+
+ SCM_VALIDATE_STRING(1, s_name);
+ c_name = scm_to_latin1_string(s_name);
+
+ lipe_list_for_each_entry(lx, &loa->loa_xattrs, lx_linkage) {
+ if (strcmp(c_name, lx->lx_name) == 0) {
+ rc = SCM_BOOL_T;
+ goto out;
+ }
+ }
+out:
+ free(c_name);
+
+ return rc;
+}
+#undef FUNC_NAME
+
static SCM ls3_scm_c_xattr_value(const void *value, unsigned int value_len)
{
SCM bv;
SCM lis = SCM_EOL;
lipe_list_for_each_entry_reverse(lx, &loa->loa_xattrs, lx_linkage)
- lis = scm_cons(scm_cons(scm_from_locale_string(lx->lx_name),
+ lis = scm_cons(scm_cons(scm_from_latin1_string(lx->lx_name),
ls3_scm_c_xattr_value(lx->lx_value, lx->lx_value_len)),
lis);
SCM bv_or_false = SCM_BOOL_F;
SCM_VALIDATE_STRING(1, s_name);
- c_name = scm_to_locale_string(s_name);
+ c_name = scm_to_latin1_string(s_name);
lipe_list_for_each_entry(lx, &loa->loa_xattrs, lx_linkage) {
if (strcmp(c_name, lx->lx_name) != 0)
goto out;
if (buf[0] != '\0')
- lis = scm_cons(scm_from_locale_string(buf), lis);
+ lis = scm_cons(scm_from_latin1_string(buf), lis);
rc = llapi_layout_comp_use(ll, LLAPI_LAYOUT_COMP_USE_PREV);
if (rc < 0)
"scan a device")
#define FUNC_NAME s_ls3_scm_scan
{
- const char *c_device_path;
- const char *c_client_mount_path;
+ char *c_device_path = 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 rc;
SCM_VALIDATE_STRING(1, s_device_path);
- c_device_path = scm_to_locale_string(s_device_path);
+ c_device_path = scm_to_latin1_string(s_device_path);
if (scm_is_eq(s_client_mount_path, SCM_BOOL_F)) {
c_client_mount_path = LS3_CSTR_NONE;
c_client_mount_path = LS3_CSTR_AUTO;
} else {
SCM_VALIDATE_STRING(2, s_client_mount_path);
- c_client_mount_path = scm_to_locale_string(s_client_mount_path);
+ c_client_mount_path = c_client_mount_path_1 = scm_to_latin1_string(s_client_mount_path);
}
SCM_VALIDATE_THUNK(3, s_policy_thunk);
c_thread_count);
LS3_DEBUG_D(rc);
+ free(c_device_path);
+ free(c_client_mount_path_1);
+
return scm_from_int(rc);
}
#undef FUNC_NAME
"links",
"absolute-paths",
"relative-paths",
+ "xattr?",
"xattrs",
"xattr-ref",
"lov-mirror-count",
}
li->li_client_mount_path = path_canon;
- li->li_scm_client_mount_path = scm_from_locale_string(li->li_client_mount_path);
+ li->li_scm_client_mount_path = scm_from_latin1_string(li->li_client_mount_path);
li->li_client_mount_fd = fd;
li->li_scm_client_mount_fd = scm_from_int(fd);
path_canon = NULL;
struct ls3_instance li = {
.li_device_path = xstrdup(device_path),
.li_client_mount_fd = -1,
- .li_scm_device_path = scm_from_locale_string(device_path),
- .li_scm_device_name = scm_from_locale_string(""),
- .li_scm_fsname = scm_from_locale_string(""),
- .li_scm_client_mount_path = scm_from_locale_string(""),
+ .li_scm_device_path = scm_from_latin1_string(device_path),
+ .li_scm_device_name = scm_from_latin1_string(""),
+ .li_scm_fsname = scm_from_latin1_string(""),
+ .li_scm_client_mount_path = scm_from_latin1_string(""),
.li_scm_client_mount_fd = scm_from_int(-1),
.li_scm_policy_thunk = policy_thunk,
.li_scm_thread_count = scm_from_int(0),
li.li_device_name = xstrdup((const char *)fs->super->s_volume_name);
LS3_DEBUG_S(li.li_device_name);
- li.li_scm_device_name = scm_from_locale_string(li.li_device_name);
+ li.li_scm_device_name = scm_from_latin1_string(li.li_device_name);
rc = ls3_read_ldd(device_path, fs, &ldd);
if (rc != 0)
LS3_DEBUG_S(ldd.ldd_fsname);
LS3_DEBUG_S(ldd.ldd_svname);
- li.li_scm_fsname = scm_from_locale_string(ldd.ldd_fsname);
+ li.li_scm_fsname = scm_from_latin1_string(ldd.ldd_fsname);
switch (ldd.ldd_flags & (LDD_F_SV_TYPE_MDT | LDD_F_SV_TYPE_OST)) {
case LDD_F_SV_TYPE_MDT:
} else if (scm_is_eq(key, ls3_sym_scan_continue)) {
/* OK */
} else {
- SCM fmt = scm_from_locale_string("ERROR: caught ~a ~s\n");
+ SCM fmt = scm_from_latin1_string("ERROR: caught ~a ~s\n");
scm_simple_format(scm_current_error_port(), fmt,
scm_list_2(key, args));
}
run_test 110 "lipe_find3 -pool does the right thing"
+test_111() {
+ local file=$MOUNT/$tfile
+ local name="user.$TESTNAME"
+ local fid
+
+ init_lipe_find3_env "$file"
+ fid=$($LFS path2fid "$file")
+
+ setfattr -n "$name" "$file"
+ expect1 "$fid" lipe_find3_facet mds1 -xattr "$name" -print-file-fid
+ expect1 "$fid" lipe_find3_facet mds1 -xattr-match "$name" '' -print-file-fid
+ expect_empty lipe_find3_facet mds1 -xattr-match "$name" XXX -print-file-fid
+
+ expect1 "$fid" lipe_find3_facet mds1 -xattr trusted.lma -print-file-fid
+ expect1 "$fid" lipe_find3_facet mds1 -xattr trusted.lov -print-file-fid
+
+ setfattr -n "$name" -v XXX "$file"
+ expect1 "$fid" lipe_find3_facet mds1 -xattr "$name" -print-file-fid
+ expect1 "$fid" lipe_find3_facet mds1 -xattr-match "$name" XXX -print-file-fid
+ expect1 "$fid" lipe_find3_facet mds1 -xattr-match '*' XXX -print-file-fid
+ expect1 "$fid" lipe_find3_facet mds1 -xattr-match "$name" '*' -print-file-fid
+ expect1 "$fid" lipe_find3_facet mds1 -xattr-match "$name" 'X*' -print-file-fid
+ expect_empty lipe_find3_facet mds1 -xattr-match "$name" '' -print-file-fid
+
+ expect_empty lipe_find3_facet mds1 -xattr "${name}-1" -print-file-fid
+ expect_empty lipe_find3_facet mds1 -xattr-match "${name}-1" '*' -print-file-fid
+
+ expect_error lipe_find3_facet mds1 -xattr
+}
+run_test 111 "lipe_find3 -xattr does the right thing"
+
test_130() {
local file=$MOUNT/$tfile
local xtime