summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/tools/virtiofsd.rst6
-rw-r--r--tools/virtiofsd/passthrough_ll.c17
2 files changed, 20 insertions, 3 deletions
diff --git a/docs/tools/virtiofsd.rst b/docs/tools/virtiofsd.rst
index b208f2a6f0..cc31402830 100644
--- a/docs/tools/virtiofsd.rst
+++ b/docs/tools/virtiofsd.rst
@@ -183,6 +183,12 @@ Using ':' as the separator a rule is of the form:
'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.
diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
index 38b2af8599..64b5b4fbb1 100644
--- a/tools/virtiofsd/passthrough_ll.c
+++ b/tools/virtiofsd/passthrough_ll.c
@@ -2465,6 +2465,11 @@ static void lo_flock(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi,
* 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 */
@@ -2636,6 +2641,8 @@ static void parse_xattrmap(struct lo_data *lo)
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
@@ -2646,8 +2653,8 @@ static void parse_xattrmap(struct lo_data *lo)
} 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);
}
@@ -2749,6 +2756,9 @@ static int xattr_map_client(const struct lo_data *lo, const char *client_name,
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;
@@ -2788,7 +2798,8 @@ static int xattr_map_server(const struct lo_data *lo, const char *server_name,
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) {