aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/src/fuseconnector.cpp37
-rw-r--r--src/src/vfs/mo2filesystem.cpp56
-rw-r--r--src/src/vfs/mo2filesystem.h6
3 files changed, 99 insertions, 0 deletions
diff --git a/src/src/fuseconnector.cpp b/src/src/fuseconnector.cpp
index 81a653c..8b7d206 100644
--- a/src/src/fuseconnector.cpp
+++ b/src/src/fuseconnector.cpp
@@ -329,6 +329,12 @@ void wrap_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
MO2_TRY_REPLY(req, "fsync", ino, EIO)
}
+void wrap_statfs(fuse_req_t req, fuse_ino_t ino) noexcept
+{
+ try { mo2_statfs(req, ino); }
+ MO2_TRY_REPLY(req, "statfs", ino, EIO)
+}
+
void wrap_getlk(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info* fi,
struct flock* lock) noexcept
{
@@ -376,6 +382,32 @@ void wrap_lseek(fuse_req_t req, fuse_ino_t ino, off_t off, int whence,
MO2_TRY_REPLY(req, "lseek", ino, EIO)
}
+void wrap_getxattr(fuse_req_t req, fuse_ino_t ino, const char* name,
+ size_t size) noexcept
+{
+ try { mo2_getxattr(req, ino, name, size); }
+ MO2_TRY_REPLY(req, "getxattr", ino, EIO)
+}
+
+void wrap_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size) noexcept
+{
+ try { mo2_listxattr(req, ino, size); }
+ MO2_TRY_REPLY(req, "listxattr", ino, EIO)
+}
+
+void wrap_setxattr(fuse_req_t req, fuse_ino_t ino, const char* name,
+ const char* value, size_t size, int flags) noexcept
+{
+ try { mo2_setxattr(req, ino, name, value, size, flags); }
+ MO2_TRY_REPLY(req, "setxattr", ino, EIO)
+}
+
+void wrap_removexattr(fuse_req_t req, fuse_ino_t ino, const char* name) noexcept
+{
+ try { mo2_removexattr(req, ino, name); }
+ MO2_TRY_REPLY(req, "removexattr", ino, EIO)
+}
+
#if FUSE_USE_VERSION < 35
void wrap_ioctl(fuse_req_t req, fuse_ino_t ino, int cmd, void* arg,
struct fuse_file_info* fi, unsigned flags, const void* in_buf,
@@ -417,12 +449,17 @@ void setupFuseOps(struct fuse_lowlevel_ops* ops)
ops->releasedir = wrap_releasedir;
ops->flush = wrap_flush;
ops->fsync = wrap_fsync;
+ ops->statfs = wrap_statfs;
ops->getlk = wrap_getlk;
ops->setlk = wrap_setlk;
ops->flock = wrap_flock;
ops->fallocate = wrap_fallocate;
ops->copy_file_range = wrap_copy_file_range;
ops->lseek = wrap_lseek;
+ ops->getxattr = wrap_getxattr;
+ ops->listxattr = wrap_listxattr;
+ ops->setxattr = wrap_setxattr;
+ ops->removexattr = wrap_removexattr;
ops->ioctl = wrap_ioctl;
// access handler removed: default_permissions mount option lets the kernel
// handle permission checks in-kernel, eliminating access() round-trips.
diff --git a/src/src/vfs/mo2filesystem.cpp b/src/src/vfs/mo2filesystem.cpp
index 3ae81de..dd701df 100644
--- a/src/src/vfs/mo2filesystem.cpp
+++ b/src/src/vfs/mo2filesystem.cpp
@@ -5,6 +5,7 @@
#include <linux/fs.h>
#include <sys/file.h>
#include <sys/resource.h>
+#include <sys/statvfs.h>
#include <sys/time.h>
#include <unistd.h>
@@ -3079,6 +3080,35 @@ void mo2_fsync(fuse_req_t req, fuse_ino_t /*ino*/, int datasync,
fuse_reply_err(req, 0);
}
+void mo2_statfs(fuse_req_t req, fuse_ino_t /*ino*/)
+{
+ Mo2FsContext* ctx = getContext(req);
+ if (ctx == nullptr) {
+ fuse_reply_err(req, EINVAL);
+ return;
+ }
+
+ struct statvfs st {};
+ if (ctx->backing_dir_fd >= 0 && fstatvfs(ctx->backing_dir_fd, &st) == 0) {
+ if (st.f_namemax == 0) {
+ st.f_namemax = 255;
+ }
+ fuse_reply_statfs(req, &st);
+ return;
+ }
+
+ st.f_bsize = 4096;
+ st.f_frsize = 4096;
+ st.f_blocks = 1024ull * 1024ull;
+ st.f_bfree = st.f_blocks / 2;
+ st.f_bavail = st.f_bfree;
+ st.f_files = 1024ull * 1024ull;
+ st.f_ffree = st.f_files / 2;
+ st.f_favail = st.f_ffree;
+ st.f_namemax = 255;
+ fuse_reply_statfs(req, &st);
+}
+
void mo2_getlk(fuse_req_t req, fuse_ino_t /*ino*/, struct fuse_file_info* /*fi*/,
struct flock* lock)
{
@@ -3344,6 +3374,32 @@ void mo2_lseek(fuse_req_t req, fuse_ino_t ino, off_t off, int whence,
}
}
+void mo2_getxattr(fuse_req_t req, fuse_ino_t /*ino*/, const char* /*name*/,
+ size_t /*size*/)
+{
+ fuse_reply_err(req, ENODATA);
+}
+
+void mo2_listxattr(fuse_req_t req, fuse_ino_t /*ino*/, size_t size)
+{
+ if (size == 0) {
+ fuse_reply_xattr(req, 0);
+ return;
+ }
+ fuse_reply_buf(req, nullptr, 0);
+}
+
+void mo2_setxattr(fuse_req_t req, fuse_ino_t /*ino*/, const char* /*name*/,
+ const char* /*value*/, size_t /*size*/, int /*flags*/)
+{
+ fuse_reply_err(req, 0);
+}
+
+void mo2_removexattr(fuse_req_t req, fuse_ino_t /*ino*/, const char* /*name*/)
+{
+ fuse_reply_err(req, 0);
+}
+
#if FUSE_USE_VERSION < 35
void mo2_ioctl(fuse_req_t req, fuse_ino_t /*ino*/, int cmd, void* /*arg*/,
struct fuse_file_info* /*fi*/, unsigned /*flags*/,
diff --git a/src/src/vfs/mo2filesystem.h b/src/src/vfs/mo2filesystem.h
index 3efedf9..df2a9c1 100644
--- a/src/src/vfs/mo2filesystem.h
+++ b/src/src/vfs/mo2filesystem.h
@@ -207,6 +207,7 @@ void mo2_forget(fuse_req_t req, fuse_ino_t ino, uint64_t nlookup);
void mo2_flush(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info* fi);
void mo2_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
struct fuse_file_info* fi);
+void mo2_statfs(fuse_req_t req, fuse_ino_t ino);
void mo2_getlk(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info* fi,
struct flock* lock);
void mo2_setlk(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info* fi,
@@ -220,6 +221,11 @@ void mo2_copy_file_range(fuse_req_t req, fuse_ino_t ino_in, off_t off_in,
size_t len, int flags);
void mo2_lseek(fuse_req_t req, fuse_ino_t ino, off_t off, int whence,
struct fuse_file_info* fi);
+void mo2_getxattr(fuse_req_t req, fuse_ino_t ino, const char* name, size_t size);
+void mo2_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size);
+void mo2_setxattr(fuse_req_t req, fuse_ino_t ino, const char* name,
+ const char* value, size_t size, int flags);
+void mo2_removexattr(fuse_req_t req, fuse_ino_t ino, const char* name);
#if FUSE_USE_VERSION < 35
void mo2_ioctl(fuse_req_t req, fuse_ino_t ino, int cmd, void* arg,
struct fuse_file_info* fi, unsigned flags, const void* in_buf,