Implemented file operations using our class hierarchy
This commit is contained in:
parent
21f1a294ab
commit
ca745bb3da
100
src/CryFuse.cpp
100
src/CryFuse.cpp
@ -43,6 +43,7 @@ int CryFuse::fgetattr(const path &path, struct stat *stbuf, fuse_file_info *file
|
||||
// opening it, and then using the FD for an fgetattr. So in the
|
||||
// special case of a path of "/", I need to do a getattr on the
|
||||
// underlying root directory instead of doing the fgetattr().
|
||||
// TODO Check if necessary
|
||||
if (path.native() == "/") {
|
||||
return getattr(path, stbuf);
|
||||
}
|
||||
@ -55,6 +56,7 @@ int CryFuse::fgetattr(const path &path, struct stat *stbuf, fuse_file_info *file
|
||||
}
|
||||
}
|
||||
|
||||
//TODO
|
||||
int CryFuse::readlink(const path &path, char *buf, size_t size) {
|
||||
//printf("readlink(%s, _, %zu)\n", path.c_str(), size);
|
||||
auto real_path = _device->RootDir() / path;
|
||||
@ -78,6 +80,7 @@ int CryFuse::mknod(const path &path, mode_t mode, dev_t rdev) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//TODO
|
||||
int CryFuse::mkdir(const path &path, mode_t mode) {
|
||||
//printf("mkdir(%s, %d)\n", path.c_str(), mode);
|
||||
auto real_path = _device->RootDir() / path;
|
||||
@ -85,6 +88,7 @@ int CryFuse::mkdir(const path &path, mode_t mode) {
|
||||
return errcode_map(retstat);
|
||||
}
|
||||
|
||||
//TODO
|
||||
int CryFuse::unlink(const path &path) {
|
||||
//printf("unlink(%s)\n", path.c_str());
|
||||
auto real_path = _device->RootDir() / path;
|
||||
@ -92,6 +96,7 @@ int CryFuse::unlink(const path &path) {
|
||||
return errcode_map(retstat);
|
||||
}
|
||||
|
||||
//TODO
|
||||
int CryFuse::rmdir(const path &path) {
|
||||
//printf("rmdir(%s)\n", path.c_str());
|
||||
auto real_path = _device->RootDir() / path;
|
||||
@ -99,6 +104,7 @@ int CryFuse::rmdir(const path &path) {
|
||||
return errcode_map(retstat);
|
||||
}
|
||||
|
||||
//TODO
|
||||
int CryFuse::symlink(const path &from, const path &to) {
|
||||
//printf("symlink(%s, %s)\n", from.c_str(), to.c_str());
|
||||
auto real_from = _device->RootDir() / from;
|
||||
@ -107,6 +113,7 @@ int CryFuse::symlink(const path &from, const path &to) {
|
||||
return errcode_map(retstat);
|
||||
}
|
||||
|
||||
//TODO
|
||||
int CryFuse::rename(const path &from, const path &to) {
|
||||
//printf("rename(%s, %s)\n", from.c_str(), to.c_str());
|
||||
auto real_from = _device->RootDir() / from;
|
||||
@ -115,6 +122,7 @@ int CryFuse::rename(const path &from, const path &to) {
|
||||
return errcode_map(retstat);
|
||||
}
|
||||
|
||||
//TODO
|
||||
int CryFuse::link(const path &from, const path &to) {
|
||||
//printf("link(%s, %s)\n", from.c_str(), to.c_str());
|
||||
auto real_from = _device->RootDir() / from;
|
||||
@ -123,6 +131,7 @@ int CryFuse::link(const path &from, const path &to) {
|
||||
return errcode_map(retstat);
|
||||
}
|
||||
|
||||
//TODO
|
||||
int CryFuse::chmod(const path &path, mode_t mode) {
|
||||
//printf("chmod(%s, %d)\n", path.c_str(), mode);
|
||||
auto real_path = _device->RootDir() / path;
|
||||
@ -130,6 +139,7 @@ int CryFuse::chmod(const path &path, mode_t mode) {
|
||||
return errcode_map(retstat);
|
||||
}
|
||||
|
||||
//TODO
|
||||
int CryFuse::chown(const path &path, uid_t uid, gid_t gid) {
|
||||
//printf("chown(%s, %d, %d)\n", path.c_str(), uid, gid);
|
||||
auto real_path = _device->RootDir() / path;
|
||||
@ -139,18 +149,26 @@ int CryFuse::chown(const path &path, uid_t uid, gid_t gid) {
|
||||
|
||||
int CryFuse::truncate(const path &path, off_t size) {
|
||||
//printf("truncate(%s, %zu)\n", path.c_str(), size);
|
||||
auto real_path = _device->RootDir() / path;
|
||||
int retstat = ::truncate(real_path.c_str(), size);
|
||||
return errcode_map(retstat);
|
||||
try {
|
||||
_device->truncate(path, size);
|
||||
return 0;
|
||||
} catch (CryErrnoException &e) {
|
||||
return -e.getErrno();
|
||||
}
|
||||
}
|
||||
|
||||
int CryFuse::ftruncate(const path &path, off_t size, fuse_file_info *fileinfo) {
|
||||
//printf("ftruncate(%s, %zu, _)\n", path.c_str(), size);
|
||||
UNUSED(path);
|
||||
int retstat = ::ftruncate(fileinfo->fh, size);
|
||||
return errcode_map(retstat);
|
||||
try {
|
||||
_device->ftruncate(fileinfo->fh, size);
|
||||
return 0;
|
||||
} catch (CryErrnoException &e) {
|
||||
return -e.getErrno();
|
||||
}
|
||||
}
|
||||
|
||||
//TODO
|
||||
int CryFuse::utimens(const path &path, const timespec times[2]) {
|
||||
//printf("utimens(%s, _)\n", path.c_str());
|
||||
auto real_path = _device->RootDir() / path;
|
||||
@ -165,36 +183,48 @@ int CryFuse::utimens(const path &path, const timespec times[2]) {
|
||||
|
||||
int CryFuse::open(const path &path, fuse_file_info *fileinfo) {
|
||||
//printf("open(%s, _)\n", path.c_str());
|
||||
auto real_path = _device->RootDir() / path;
|
||||
int fd = ::open(real_path.c_str(), fileinfo->flags);
|
||||
if (fd < 0) {
|
||||
return -errno;
|
||||
}
|
||||
fileinfo->fh = fd;
|
||||
try {
|
||||
fileinfo->fh = _device->openFile(path, fileinfo->flags);
|
||||
return 0;
|
||||
} catch (CryErrnoException &e) {
|
||||
return -e.getErrno();
|
||||
}
|
||||
}
|
||||
|
||||
int CryFuse::release(const path &path, fuse_file_info *fileinfo) {
|
||||
//printf("release(%s, _)\n", path.c_str());
|
||||
UNUSED(path);
|
||||
int retstat = ::close(fileinfo->fh);
|
||||
return errcode_map(retstat);
|
||||
try {
|
||||
_device->closeFile(fileinfo->fh);
|
||||
return 0;
|
||||
} catch (CryErrnoException &e) {
|
||||
return -e.getErrno();
|
||||
}
|
||||
}
|
||||
|
||||
int CryFuse::read(const path &path, char *buf, size_t size, off_t offset, fuse_file_info *fileinfo) {
|
||||
//printf("read(%s, _, %zu, %zu, _)\n", path.c_str(), size, offset);
|
||||
UNUSED(path);
|
||||
int retstat = ::pread(fileinfo->fh, buf, size, offset);
|
||||
return errcode_map(retstat);
|
||||
try {
|
||||
_device->read(fileinfo->fh, buf, size, offset);
|
||||
return 0;
|
||||
} catch (CryErrnoException &e) {
|
||||
return -e.getErrno();
|
||||
}
|
||||
}
|
||||
|
||||
int CryFuse::write(const path &path, const char *buf, size_t size, off_t offset, fuse_file_info *fileinfo) {
|
||||
//printf("write(%s, _, %zu, %zu, _)\n", path.c_str(), size, offset);
|
||||
UNUSED(path);
|
||||
int retstat = ::pwrite(fileinfo->fh, buf, size, offset);
|
||||
return errcode_map(retstat);
|
||||
try {
|
||||
_device->write(fileinfo->fh, buf, size, offset);
|
||||
return 0;
|
||||
} catch (CryErrnoException &e) {
|
||||
return -e.getErrno();
|
||||
}
|
||||
}
|
||||
|
||||
//TODO
|
||||
int CryFuse::statfs(const path &path, struct statvfs *fsstat) {
|
||||
//printf("statfs(%s, _)\n", path.c_str());
|
||||
auto real_path = _device->RootDir() / path;
|
||||
@ -202,6 +232,7 @@ int CryFuse::statfs(const path &path, struct statvfs *fsstat) {
|
||||
return errcode_map(retstat);
|
||||
}
|
||||
|
||||
//TODO
|
||||
int CryFuse::flush(const path &path, fuse_file_info *fileinfo) {
|
||||
//printf("Called non-implemented flush(%s, _)\n", path.c_str());
|
||||
UNUSED(path);
|
||||
@ -212,15 +243,19 @@ int CryFuse::flush(const path &path, fuse_file_info *fileinfo) {
|
||||
int CryFuse::fsync(const path &path, int datasync, fuse_file_info *fileinfo) {
|
||||
//printf("fsync(%s, %d, _)\n", path.c_str(), datasync);
|
||||
UNUSED(path);
|
||||
int retstat = 0;
|
||||
try {
|
||||
if (datasync) {
|
||||
retstat = ::fdatasync(fileinfo->fh);
|
||||
_device->fdatasync(fileinfo->fh);
|
||||
} else {
|
||||
retstat = ::fsync(fileinfo->fh);
|
||||
_device->fsync(fileinfo->fh);
|
||||
}
|
||||
return 0;
|
||||
} catch (CryErrnoException &e) {
|
||||
return -e.getErrno();
|
||||
}
|
||||
return errcode_map(retstat);
|
||||
}
|
||||
|
||||
//TODO
|
||||
int CryFuse::opendir(const path &path, fuse_file_info *fileinfo) {
|
||||
//printf("opendir(%s, _)\n", path.c_str());
|
||||
auto real_path = _device->RootDir() / path;
|
||||
@ -232,6 +267,7 @@ int CryFuse::opendir(const path &path, fuse_file_info *fileinfo) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//TODO
|
||||
int CryFuse::readdir(const path &path, void *buf, fuse_fill_dir_t filler, off_t offset, fuse_file_info *fileinfo) {
|
||||
//printf("readdir(%s, _, _, %zu, _)\n", path.c_str(), offset);
|
||||
UNUSED(offset);
|
||||
@ -252,6 +288,7 @@ int CryFuse::readdir(const path &path, void *buf, fuse_fill_dir_t filler, off_t
|
||||
return 0;
|
||||
}
|
||||
|
||||
//TODO
|
||||
int CryFuse::releasedir(const path &path, fuse_file_info *fileinfo) {
|
||||
//printf("releasedir(%s, _)\n", path.c_str());
|
||||
UNUSED(path);
|
||||
@ -259,6 +296,7 @@ int CryFuse::releasedir(const path &path, fuse_file_info *fileinfo) {
|
||||
return errcode_map(retstat);
|
||||
}
|
||||
|
||||
//TODO
|
||||
int CryFuse::fsyncdir(const path &path, int datasync, fuse_file_info *fileinfo) {
|
||||
UNUSED(fileinfo);
|
||||
UNUSED(datasync);
|
||||
@ -278,20 +316,22 @@ void CryFuse::destroy() {
|
||||
|
||||
int CryFuse::access(const path &path, int mask) {
|
||||
//printf("access(%s, %d)\n", path.c_str(), mask);
|
||||
auto real_path = _device->RootDir() / path;
|
||||
int retstat = ::access(real_path.c_str(), mask);
|
||||
return errcode_map(retstat);
|
||||
try {
|
||||
_device->access(path, mask);
|
||||
return 0;
|
||||
} catch (CryErrnoException &e) {
|
||||
return -e.getErrno();
|
||||
}
|
||||
}
|
||||
|
||||
int CryFuse::create(const path &path, mode_t mode, fuse_file_info *fileinfo) {
|
||||
//printf("create(%s, %d, _)\n", path.c_str(), mode);
|
||||
auto real_path = _device->RootDir() / path;
|
||||
int fd = ::creat(real_path.c_str(), mode);
|
||||
if (fd < 0) {
|
||||
return -errno;
|
||||
}
|
||||
fileinfo->fh = fd;
|
||||
try {
|
||||
fileinfo->fh = _device->createFile(path, mode);
|
||||
return 0;
|
||||
} catch (CryErrnoException &e) {
|
||||
return -e.getErrno();
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace cryfs */
|
||||
|
@ -31,7 +31,7 @@ unique_ptr<CryNode> CryDevice::Load(const bf::path &path) {
|
||||
throw CryErrnoException(ENOENT);
|
||||
}
|
||||
|
||||
std::unique_ptr<CryFile> CryDevice::LoadFile(const bf::path &path) {
|
||||
unique_ptr<CryFile> CryDevice::LoadFile(const bf::path &path) {
|
||||
auto node = Load(path);
|
||||
auto file = dynamic_pointer_move<CryFile>(node);
|
||||
if (!file) {
|
||||
@ -40,11 +40,24 @@ std::unique_ptr<CryFile> CryDevice::LoadFile(const bf::path &path) {
|
||||
return file;
|
||||
}
|
||||
|
||||
int CryDevice::OpenFile(const bf::path &path, int flags) {
|
||||
unique_ptr<CryDir> CryDevice::LoadDir(const bf::path &path) {
|
||||
auto node = Load(path);
|
||||
auto dir = dynamic_pointer_move<CryDir>(node);
|
||||
if (!dir) {
|
||||
throw CryErrnoException(ENOTDIR);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
int CryDevice::openFile(const bf::path &path, int flags) {
|
||||
auto file = LoadFile(path);
|
||||
return _open_files.open(*file, flags);
|
||||
}
|
||||
|
||||
void CryDevice::closeFile(int descriptor) {
|
||||
_open_files.close(descriptor);
|
||||
}
|
||||
|
||||
void CryDevice::lstat(const bf::path &path, struct ::stat *stbuf) {
|
||||
Load(path)->stat(stbuf);
|
||||
}
|
||||
@ -52,3 +65,39 @@ void CryDevice::lstat(const bf::path &path, struct ::stat *stbuf) {
|
||||
void CryDevice::fstat(int descriptor, struct ::stat *stbuf) {
|
||||
_open_files.get(descriptor)->stat(stbuf);
|
||||
}
|
||||
|
||||
void CryDevice::truncate(const bf::path &path, off_t size) {
|
||||
LoadFile(path)->truncate(size);
|
||||
}
|
||||
|
||||
void CryDevice::ftruncate(int descriptor, off_t size) {
|
||||
_open_files.get(descriptor)->truncate(size);
|
||||
}
|
||||
|
||||
void CryDevice::read(int descriptor, void *buf, size_t count, off_t offset) {
|
||||
_open_files.get(descriptor)->read(buf, count, offset);
|
||||
}
|
||||
|
||||
void CryDevice::write(int descriptor, const void *buf, size_t count, off_t offset) {
|
||||
_open_files.get(descriptor)->write(buf, count, offset);
|
||||
}
|
||||
|
||||
void CryDevice::fsync(int descriptor) {
|
||||
_open_files.get(descriptor)->fsync();
|
||||
}
|
||||
|
||||
void CryDevice::fdatasync(int descriptor) {
|
||||
_open_files.get(descriptor)->fdatasync();
|
||||
}
|
||||
|
||||
void CryDevice::access(const bf::path &path, int mask) {
|
||||
Load(path)->access(mask);
|
||||
}
|
||||
|
||||
int CryDevice::createFile(const bf::path &path, mode_t mode) {
|
||||
//TODO Creating the file opens and closes it. We then reopen it afterwards.
|
||||
// This is slow. Improve!
|
||||
auto dir = LoadDir(path.parent_path());
|
||||
dir->createFile(path.filename().native(), mode);
|
||||
return openFile(path, mode);
|
||||
}
|
||||
|
@ -12,6 +12,8 @@
|
||||
namespace cryfs {
|
||||
class CryNode;
|
||||
class CryFile;
|
||||
class CryOpenFile;
|
||||
class CryDir;
|
||||
|
||||
namespace bf = boost::filesystem;
|
||||
|
||||
@ -20,14 +22,24 @@ public:
|
||||
CryDevice(const bf::path &rootdir);
|
||||
virtual ~CryDevice();
|
||||
|
||||
int OpenFile(const bf::path &path, int flags);
|
||||
int openFile(const bf::path &path, int flags);
|
||||
void closeFile(int descriptor);
|
||||
void lstat(const bf::path &path, struct ::stat *stbuf);
|
||||
void fstat(int descriptor, struct ::stat *stbuf);
|
||||
void truncate(const bf::path &path, off_t size);
|
||||
void ftruncate(int descriptor, off_t size);
|
||||
void read(int descriptor, void *buf, size_t count, off_t offset);
|
||||
void write(int descriptor, const void *buf, size_t count, off_t offset);
|
||||
void fsync(int descriptor);
|
||||
void fdatasync(int descriptor);
|
||||
void access(const bf::path &path, int mask);
|
||||
int createFile(const bf::path &path, mode_t mode);
|
||||
|
||||
const bf::path &RootDir() const;
|
||||
private:
|
||||
std::unique_ptr<CryNode> Load(const bf::path &path);
|
||||
std::unique_ptr<CryFile> LoadFile(const bf::path &path);
|
||||
std::unique_ptr<CryDir> LoadDir(const bf::path &path);
|
||||
const bf::path _rootdir;
|
||||
CryOpenFileList _open_files;
|
||||
|
||||
|
@ -1,5 +1,14 @@
|
||||
#include "CryDir.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "CryDevice.h"
|
||||
#include "CryErrnoException.h"
|
||||
|
||||
using std::string;
|
||||
using std::unique_ptr;
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
@ -10,4 +19,12 @@ CryDir::CryDir(CryDevice *device, const bf::path &path)
|
||||
CryDir::~CryDir() {
|
||||
}
|
||||
|
||||
void CryDir::createFile(const string &name, mode_t mode) {
|
||||
auto file_path = base_path() / name;
|
||||
//Create file
|
||||
int fd = ::creat(file_path.c_str(), mode);
|
||||
CHECK_RETVAL(fd);
|
||||
::close(fd);
|
||||
}
|
||||
|
||||
} /* namespace cryfs */
|
||||
|
@ -2,6 +2,9 @@
|
||||
#ifndef CRYFS_LIB_CRYDIR_H_
|
||||
#define CRYFS_LIB_CRYDIR_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "CryNode.h"
|
||||
#include "utils/macros.h"
|
||||
|
||||
@ -12,6 +15,8 @@ class CryDir: public CryNode {
|
||||
public:
|
||||
CryDir(CryDevice *device, const bf::path &path);
|
||||
virtual ~CryDir();
|
||||
|
||||
void createFile(const std::string &name, mode_t mode);
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(CryDir);
|
||||
};
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "CryFile.h"
|
||||
#include "CryOpenFile.h"
|
||||
|
||||
#include "CryErrnoException.h"
|
||||
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
|
||||
@ -17,4 +19,9 @@ std::unique_ptr<CryOpenFile> CryFile::open(int flags) const {
|
||||
return make_unique<CryOpenFile>(base_path(), flags);
|
||||
}
|
||||
|
||||
void CryFile::truncate(off_t size) const {
|
||||
int retval = ::truncate(base_path().c_str(), size);
|
||||
CHECK_RETVAL(retval);
|
||||
}
|
||||
|
||||
} /* namespace cryfs */
|
||||
|
@ -17,6 +17,7 @@ public:
|
||||
virtual ~CryFile();
|
||||
|
||||
std::unique_ptr<CryOpenFile> open(int flags) const;
|
||||
void truncate(off_t size) const;
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(CryFile);
|
||||
};
|
||||
|
@ -17,4 +17,9 @@ void CryNode::stat(struct ::stat *result) const {
|
||||
CHECK_RETVAL(retval);
|
||||
}
|
||||
|
||||
void CryNode::access(int mask) const {
|
||||
int retval = ::access(base_path().c_str(), mask);
|
||||
CHECK_RETVAL(retval);
|
||||
}
|
||||
|
||||
} /* namespace cryfs */
|
||||
|
@ -18,6 +18,7 @@ public:
|
||||
virtual ~CryNode();
|
||||
|
||||
void stat(struct ::stat *result) const;
|
||||
void access(int mask) const;
|
||||
|
||||
protected:
|
||||
bf::path base_path() const;
|
||||
|
@ -22,3 +22,27 @@ void CryOpenFile::stat(struct ::stat *result) const {
|
||||
CHECK_RETVAL(retval);
|
||||
}
|
||||
|
||||
void CryOpenFile::truncate(off_t size) const {
|
||||
int retval = ::ftruncate(_descriptor, size);
|
||||
CHECK_RETVAL(retval);
|
||||
}
|
||||
|
||||
void CryOpenFile::read(void *buf, size_t count, off_t offset) {
|
||||
int retval = ::pread(_descriptor, buf, count, offset);
|
||||
CHECK_RETVAL(retval);
|
||||
}
|
||||
|
||||
void CryOpenFile::write(const void *buf, size_t count, off_t offset) {
|
||||
int retval = ::pwrite(_descriptor, buf, count, offset);
|
||||
CHECK_RETVAL(retval);
|
||||
}
|
||||
|
||||
void CryOpenFile::fsync() {
|
||||
int retval = ::fsync(_descriptor);
|
||||
CHECK_RETVAL(retval);
|
||||
}
|
||||
|
||||
void CryOpenFile::fdatasync() {
|
||||
int retval = ::fdatasync(_descriptor);
|
||||
CHECK_RETVAL(retval);
|
||||
}
|
||||
|
@ -16,6 +16,11 @@ public:
|
||||
virtual ~CryOpenFile();
|
||||
|
||||
void stat(struct ::stat *result) const;
|
||||
void truncate(off_t size) const;
|
||||
void read(void *buf, size_t count, off_t offset);
|
||||
void write(const void *buf, size_t count, off_t offset);
|
||||
void fsync();
|
||||
void fdatasync();
|
||||
private:
|
||||
int _descriptor;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user