diff options
author | Alessio Balsini <balsini@google.com> | 2021-11-29 16:33:03 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-11-29 16:33:03 +0000 |
commit | 819883ecfa11e3caba6121c2f630111a5e2accca (patch) | |
tree | 0cab7dc8faceb97b5ac2ffa27ef996ec5a9118af /lib | |
parent | cbee8ee746e10d3163ff7bfb2c325e7699c92577 (diff) | |
parent | 7e5a12d6de30f111d8eff8c669c9b6ed074fa583 (diff) | |
download | libfuse-819883ecfa11e3caba6121c2f630111a5e2accca.tar.gz |
Support fuse-bpf am: 7e5a12d6de
Original change: https://android-review.googlesource.com/c/platform/external/libfuse/+/1894112
Change-Id: I200d0ff210eae1ecb372f031702a7db35c7b57aa
Diffstat (limited to 'lib')
-rw-r--r-- | lib/fuse_lowlevel.c | 73 |
1 files changed, 60 insertions, 13 deletions
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index a4a4df0..459fca5 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -400,20 +400,45 @@ static void fill_open(struct fuse_open_out *arg, arg->open_flags |= FOPEN_NONSEEKABLE; } -int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e) -{ - struct fuse_entry_out arg; - size_t size = req->se->conn.proto_minor < 9 ? - FUSE_COMPAT_ENTRY_OUT_SIZE : sizeof(arg); +int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param* e) { + struct { + struct fuse_entry_out arg; + struct fuse_entry_bpf_out bpf_arg; + } __attribute__((packed)) arg_ext = {0}; - /* before ABI 7.4 e->ino == 0 was invalid, only ENOENT meant - negative entry */ - if (!e->ino && req->se->conn.proto_minor < 4) - return fuse_reply_err(req, ENOENT); + struct fuse_entry_out arg; + struct fuse_entry_bpf_out bpf_arg; + size_t size; + int extended_args = e->bpf_action || bpf_arg.bpf_fd || e->backing_action || e->backing_fd; - memset(&arg, 0, sizeof(arg)); - fill_entry(&arg, e); - return send_reply_ok(req, &arg, size); + if (extended_args) { + size = req->se->conn.proto_minor < 9 ? FUSE_COMPAT_ENTRY_OUT_SIZE : sizeof(arg_ext); + } else { + size = req->se->conn.proto_minor < 9 ? FUSE_COMPAT_ENTRY_OUT_SIZE : sizeof(arg); + } + + /* before ABI 7.4 e->ino == 0 was invalid, only ENOENT meant + negative entry */ + if (!e->ino && req->se->conn.proto_minor < 4) return fuse_reply_err(req, ENOENT); + + memset(&arg, 0, sizeof(arg)); + + if (extended_args) { + memset(&bpf_arg, 0, sizeof(bpf_arg)); + + bpf_arg.bpf_action = e->bpf_action; + bpf_arg.bpf_fd = e->bpf_fd; + bpf_arg.backing_action = e->backing_action; + bpf_arg.backing_fd = e->backing_fd; + + arg_ext.arg = arg; + arg_ext.bpf_arg = bpf_arg; + + return send_reply_ok(req, &arg_ext, size); + } else { + fill_entry(&arg, e); + return send_reply_ok(req, &arg, size); + } } int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e, @@ -2604,6 +2629,22 @@ static const char *opname(enum fuse_opcode opcode) return fuse_ll_ops[opcode].name; } +static const char *opfiltername(int filter) +{ + switch (filter) { + case 0: + return "NONE"; + case FUSE_PREFILTER: + return "FUSE_PREFILTER"; + case FUSE_POSTFILTER: + return "FUSE_POSTFILTER"; + case FUSE_PREFILTER | FUSE_POSTFILTER: + return "FUSE_PREFILTER | FUSE_POSTFILTER"; + default: + return "???"; + } +} + static int fuse_ll_copy_from_pipe(struct fuse_bufvec *dst, struct fuse_bufvec *src) { @@ -2638,6 +2679,7 @@ void fuse_session_process_buf_int(struct fuse_session *se, void *mbuf = NULL; int err; int res; + int opcode_filter; if (buf->flags & FUSE_BUF_IS_FD) { if (buf->size < tmpbuf.buf[0].size) @@ -2659,11 +2701,16 @@ void fuse_session_process_buf_int(struct fuse_session *se, in = buf->mem; } + /* Cleanup opcode most significant bits used by FUSE BPF */ + opcode_filter = in->opcode & ~FUSE_OPCODE_FILTER; + in->opcode &= FUSE_OPCODE_FILTER; + if (se->debug) { fuse_log(FUSE_LOG_DEBUG, - "unique: %llu, opcode: %s (%i), nodeid: %llu, insize: %zu, pid: %u\n", + "unique: %llu, opcode: %s (%i), opcode filter: %s (%i), nodeid: %llu, insize: %zu, pid: %u\n", (unsigned long long) in->unique, opname((enum fuse_opcode) in->opcode), in->opcode, + opfiltername((enum fuse_opcode) opcode_filter), opcode_filter, (unsigned long long) in->nodeid, buf->size, in->pid); } |