diff --git a/src/cryfs/filesystem/CryDevice.cpp b/src/cryfs/filesystem/CryDevice.cpp index d57d9289..8dbf0fdf 100644 --- a/src/cryfs/filesystem/CryDevice.cpp +++ b/src/cryfs/filesystem/CryDevice.cpp @@ -235,21 +235,27 @@ CryDevice::BlobWithParent CryDevice::LoadBlobWithParent(const bf::path &path) { // Possible reason: Many parallel changes to a directory blob are a race condition. Need something like ParallelAccessStore! } -void CryDevice::statfs(const bf::path &path, struct statvfs *fsstat) { +CryDevice::statvfs CryDevice::statfs(const bf::path &path) { // TODO Do we need path for something? What does it represent from fuse side? UNUSED(path); callFsActionCallbacks(); + uint64_t numUsedBlocks = _fsBlobStore->numBlocks(); uint64_t numFreeBlocks = _fsBlobStore->estimateSpaceForNumBlocksLeft(); - fsstat->f_bsize = _fsBlobStore->virtualBlocksizeBytes(); - fsstat->f_blocks = numUsedBlocks + numFreeBlocks; - fsstat->f_bfree = numFreeBlocks; - fsstat->f_bavail = numFreeBlocks; - fsstat->f_files = numUsedBlocks + numFreeBlocks; - fsstat->f_ffree = numFreeBlocks; - fsstat->f_namemax = 255; // We theoretically support unlimited file name length, but this is default for many Linux file systems, so probably also makes sense for CryFS. - //f_frsize, f_favail, f_fsid and f_flag are ignored in fuse, see http://fuse.sourcearchive.com/documentation/2.7.0/structfuse__operations_4e765e29122e7b6b533dc99849a52655.html#4e765e29122e7b6b533dc99849a52655 - fsstat->f_frsize = fsstat->f_bsize; // even though this is supposed to be ignored, osxfuse needs it. + + statvfs result; + result.max_filename_length = 255; // We theoretically support unlimited file name length, but this is default for many Linux file systems, so probably also makes sense for CryFS. + + result.blocksize = _fsBlobStore->virtualBlocksizeBytes(); + result.num_total_blocks = numUsedBlocks + numFreeBlocks; + result.num_free_blocks = numFreeBlocks; + result.num_available_blocks = numFreeBlocks; + + result.num_total_inodes = numUsedBlocks + numFreeBlocks; + result.num_free_inodes = numFreeBlocks; + result.num_available_inodes = numFreeBlocks; + + return result; } unique_ref CryDevice::CreateFileBlob(const blockstore::BlockId &parent) { diff --git a/src/cryfs/filesystem/CryDevice.h b/src/cryfs/filesystem/CryDevice.h index 3759d028..44b2ad03 100644 --- a/src/cryfs/filesystem/CryDevice.h +++ b/src/cryfs/filesystem/CryDevice.h @@ -21,7 +21,7 @@ class CryDevice final: public fspp::Device { public: CryDevice(CryConfigFile config, cpputils::unique_ref blockStore, const LocalStateDir& localStateDir, uint32_t myClientId, bool allowIntegrityViolations, bool missingBlockIsIntegrityViolation); - void statfs(const boost::filesystem::path &path, struct ::statvfs *fsstat) override; + statvfs statfs(const boost::filesystem::path &path) override; cpputils::unique_ref CreateFileBlob(const blockstore::BlockId &parent); cpputils::unique_ref CreateDirBlob(const blockstore::BlockId &parent); diff --git a/src/fspp/fs_interface/Device.h b/src/fspp/fs_interface/Device.h index 6e8ef666..e6987eed 100644 --- a/src/fspp/fs_interface/Device.h +++ b/src/fspp/fs_interface/Device.h @@ -4,7 +4,6 @@ #include #include -#include namespace fspp { class Node; @@ -16,7 +15,20 @@ class Device { public: virtual ~Device() {} - virtual void statfs(const boost::filesystem::path &path, struct ::statvfs *fsstat) = 0; + struct statvfs final { + uint32_t max_filename_length; + + uint32_t blocksize; + uint64_t num_total_blocks; + uint64_t num_free_blocks; + uint64_t num_available_blocks; // free blocks for unprivileged users + + uint64_t num_total_inodes; + uint64_t num_free_inodes; + uint64_t num_available_inodes; // free inodes for unprivileged users + }; + + virtual statvfs statfs(const boost::filesystem::path &path) = 0; virtual boost::optional> Load(const boost::filesystem::path &path) = 0; //TODO Test default implementation (Device.cpp) diff --git a/src/fspp/fuse/Filesystem.h b/src/fspp/fuse/Filesystem.h index 770cda6f..2527e343 100644 --- a/src/fspp/fuse/Filesystem.h +++ b/src/fspp/fuse/Filesystem.h @@ -38,7 +38,7 @@ public: virtual void unlink(const boost::filesystem::path &path) = 0; virtual void rename(const boost::filesystem::path &from, const boost::filesystem::path &to) = 0; virtual void utimens(const boost::filesystem::path &path, timespec lastAccessTime, timespec lastModificationTime) = 0; - virtual void statfs(const boost::filesystem::path &path, struct statvfs *fsstat) = 0; + virtual void statfs(const boost::filesystem::path &path, struct ::statvfs *fsstat) = 0; //TODO We shouldn't use Dir::Entry here, that's in another layer virtual cpputils::unique_ref> readDir(const boost::filesystem::path &path) = 0; //TODO Test createSymlink diff --git a/src/fspp/impl/FilesystemImpl.cpp b/src/fspp/impl/FilesystemImpl.cpp index e63415da..f72d0df9 100644 --- a/src/fspp/impl/FilesystemImpl.cpp +++ b/src/fspp/impl/FilesystemImpl.cpp @@ -276,9 +276,21 @@ void FilesystemImpl::utimens(const bf::path &path, timespec lastAccessTime, time } } -void FilesystemImpl::statfs(const bf::path &path, struct statvfs *fsstat) { +void FilesystemImpl::statfs(const bf::path &path, struct ::statvfs *fsstat) { PROFILE(_statfsNanosec); - _device->statfs(path, fsstat); + Device::statvfs stat = _device->statfs(path); + + fsstat->f_bsize = stat.blocksize; + fsstat->f_blocks = stat.num_total_blocks; + fsstat->f_bfree = stat.num_free_blocks; + fsstat->f_bavail = stat.num_available_blocks; + fsstat->f_files = stat.num_total_inodes; + fsstat->f_ffree = stat.num_free_inodes; + fsstat->f_favail = stat.num_available_inodes; + fsstat->f_namemax = stat.max_filename_length; + + //f_frsize, f_favail, f_fsid and f_flag are ignored in fuse, see http://fuse.sourcearchive.com/documentation/2.7.0/structfuse__operations_4e765e29122e7b6b533dc99849a52655.html#4e765e29122e7b6b533dc99849a52655 + fsstat->f_frsize = fsstat->f_bsize; // even though this is supposed to be ignored, osxfuse needs it. } void FilesystemImpl::createSymlink(const bf::path &to, const bf::path &from, uid_t uid, gid_t gid) { diff --git a/src/fspp/impl/FilesystemImpl.h b/src/fspp/impl/FilesystemImpl.h index 489bab16..e6756ffd 100644 --- a/src/fspp/impl/FilesystemImpl.h +++ b/src/fspp/impl/FilesystemImpl.h @@ -45,7 +45,7 @@ public: void rename(const boost::filesystem::path &from, const boost::filesystem::path &to) override; cpputils::unique_ref> readDir(const boost::filesystem::path &path) override; void utimens(const boost::filesystem::path &path, timespec lastAccessTime, timespec lastModificationTime) override; - void statfs(const boost::filesystem::path &path, struct statvfs *fsstat) override; + void statfs(const boost::filesystem::path &path, struct ::statvfs *fsstat) override; void createSymlink(const boost::filesystem::path &to, const boost::filesystem::path &from, uid_t uid, gid_t gid) override; void readSymlink(const boost::filesystem::path &path, char *buf, size_t size) override; diff --git a/test/fspp/fuse/statfs/testutils/FuseStatfsTest.h b/test/fspp/fuse/statfs/testutils/FuseStatfsTest.h index 65278bd1..803f46a6 100644 --- a/test/fspp/fuse/statfs/testutils/FuseStatfsTest.h +++ b/test/fspp/fuse/statfs/testutils/FuseStatfsTest.h @@ -4,7 +4,6 @@ #include #include -#include #include "../../../testutils/FuseTest.h"