'ok' as either an explicit terminator or for special handling of certain
patterns.
+- 'unsupported' - If a client tries to use a name matching 'key' it's
+ denied using ENOTSUP; when the server passes an attribute
+ name matching 'prepend' it's hidden. In many ways it's use is very like
+ 'ok' as either an explicit terminator or for special handling of certain
+ patterns.
+
**key** is a string tested as a prefix on an attribute name originating
on the client. It maybe empty in which case a 'client' rule
will always match on client names.
* Automatically reversed on read
*/
#define XATTR_MAP_FLAG_PREFIX (1 << 2)
+/*
+ * The attribute is unsupported;
+ * ENOTSUP on write, hidden on read.
+ */
+#define XATTR_MAP_FLAG_UNSUPPORTED (1 << 3)
/* scopes */
/* Apply rule to get/set/remove */
tmp_entry.flags |= XATTR_MAP_FLAG_OK;
} else if (strstart(map, "bad", &map)) {
tmp_entry.flags |= XATTR_MAP_FLAG_BAD;
+ } else if (strstart(map, "unsupported", &map)) {
+ tmp_entry.flags |= XATTR_MAP_FLAG_UNSUPPORTED;
} else if (strstart(map, "map", &map)) {
/*
* map is sugar that adds a number of rules, and must be
} else {
fuse_log(FUSE_LOG_ERR,
"%s: Unexpected type;"
- "Expecting 'prefix', 'ok', 'bad' or 'map' in rule %zu\n",
- __func__, lo->xattr_map_nentries);
+ "Expecting 'prefix', 'ok', 'bad', 'unsupported' or 'map'"
+ " in rule %zu\n", __func__, lo->xattr_map_nentries);
exit(1);
}
if (cur_entry->flags & XATTR_MAP_FLAG_BAD) {
return -EPERM;
}
+ if (cur_entry->flags & XATTR_MAP_FLAG_UNSUPPORTED) {
+ return -ENOTSUP;
+ }
if (cur_entry->flags & XATTR_MAP_FLAG_OK) {
/* Unmodified name */
return 0;
if ((cur_entry->flags & XATTR_MAP_FLAG_SERVER) &&
(strstart(server_name, cur_entry->prepend, &end))) {
- if (cur_entry->flags & XATTR_MAP_FLAG_BAD) {
+ if (cur_entry->flags & XATTR_MAP_FLAG_BAD ||
+ cur_entry->flags & XATTR_MAP_FLAG_UNSUPPORTED) {
return -ENODATA;
}
if (cur_entry->flags & XATTR_MAP_FLAG_OK) {