int FuseLink::write(const char *path, const char *in, size_t length, off_t offset, struct fuse_file_info *options) { FuseLink::filesystem->setuid(fuse_get_context()->uid); FuseLink::filesystem->setgid(fuse_get_context()->gid); // Write data to the file. try { if (offset > MSIZE_FILE || ((uint64_t) offset + (uint64_t) length) > MSIZE_FILE) return -EFBIG; FuseLink::filesystem->touch(path, "cma"); FSFile file = FuseLink::filesystem->open(path); file.seekp(offset); file.write(in, length); file.close(); if (file.fail() || file.bad()) return -EIO; return length; } catch (std::exception& e) { return FuseLink::handleException(e, "write"); } }
int FuseLink::read(const char *path, char *out, size_t length, off_t offset, struct fuse_file_info *options) { FuseLink::filesystem->setuid(fuse_get_context()->uid); FuseLink::filesystem->setgid(fuse_get_context()->gid); // Read data from the file. try { if (offset > MSIZE_FILE || ((uint64_t) offset + (uint64_t) length) > MSIZE_FILE) return -EFBIG; FuseLink::filesystem->touch(path, "a"); FSFile file = FuseLink::filesystem->open(path); file.seekg(offset); uint32_t read = file.read(out, length); file.close(); if (file.fail() || file.bad()) return -EIO; return read; } catch (std::exception& e) { return FuseLink::handleException(e, "read"); } }
void FS::symlink(std::string linkPath, std::string targetPath) { auto configuration = [&](LowLevel::INode& buf) { }; this->performCreation(LowLevel::INodeType::INT_SYMLINK, linkPath, 0755, configuration); // We just created the file, so if this fails then // it's an internal inconsistency. LowLevel::INode buf; if (!this->retrievePathToINode(linkPath, buf)) throw Exception::FileNotFound(); try { FSFile f = this->filesystem->getFile(buf.inodeid); f.open(); f.write(targetPath.c_str(), targetPath.length()); f.close(); if (f.fail() || f.bad()) throw Exception::InternalInconsistency(); } catch (...) { // Delete the file from disk since we failed to // write to it (at least in some manner). Then // rethrow the exception. this->unlink(linkPath); throw; } }
void FS::truncate(std::string path, off_t size) { if (size > MSIZE_FILE) throw Exception::FileTooBig(); this->ensurePathExists(path); LowLevel::INode buf; if (!this->retrievePathToINode(path, buf)) throw Exception::FileNotFound(); this->touchINode(buf, "cma"); this->saveINode(buf); // Truncate the file to the desired size. FSFile file = this->filesystem->getFile(buf.inodeid); file.open(); file.truncate(size); file.close(); if (file.fail() || file.bad()) throw Exception::InternalInconsistency(); }