/* * Copyright (c) Facebook, Inc. and its affiliates. * * This software may be used and distributed according to the terms of the * GNU General Public License version 2. */ #ifndef _WIN32 #include "eden/fs/inodes/OverlayFile.h" #include #include "eden/fs/inodes/Overlay.h" namespace facebook { namespace eden { OverlayFile::OverlayFile(folly::File file, std::weak_ptr overlay) : file_{std::move(file)}, overlay_{overlay} {} folly::Expected OverlayFile::fstat() const { std::shared_ptr overlay = overlay_.lock(); if (!overlay) { return folly::makeUnexpected(EIO); } IORequest req{overlay.get()}; struct stat st {}; if (::fstat(file_.fd(), &st)) { return folly::makeUnexpected(errno); } return st; } folly::Expected OverlayFile::preadNoInt(void* buf, size_t n, off_t offset) const { std::shared_ptr overlay = overlay_.lock(); if (!overlay) { return folly::makeUnexpected(EIO); } IORequest req{overlay.get()}; auto ret = folly::preadNoInt(file_.fd(), buf, n, offset); if (ret == -1) { return folly::makeUnexpected(errno); } return ret; } folly::Expected OverlayFile::lseek(off_t offset, int whence) const { std::shared_ptr overlay = overlay_.lock(); if (!overlay) { return folly::makeUnexpected(EIO); } IORequest req{overlay.get()}; auto ret = ::lseek(file_.fd(), offset, whence); if (ret == -1) { return folly::makeUnexpected(errno); } return ret; } folly::Expected OverlayFile::pwritev(const iovec* iov, int iovcnt, off_t offset) const { std::shared_ptr overlay = overlay_.lock(); if (!overlay) { return folly::makeUnexpected(EIO); } IORequest req{overlay.get()}; auto ret = folly::pwritevNoInt(file_.fd(), iov, iovcnt, offset); if (ret == -1) { return folly::makeUnexpected(errno); } return ret; } folly::Expected OverlayFile::ftruncate(off_t length) const { std::shared_ptr overlay = overlay_.lock(); if (!overlay) { return folly::makeUnexpected(EIO); } IORequest req{overlay.get()}; auto ret = ::ftruncate(file_.fd(), length); if (ret == -1) { return folly::makeUnexpected(errno); } return folly::makeExpected(ret); } folly::Expected OverlayFile::fsync() const { std::shared_ptr overlay = overlay_.lock(); if (!overlay) { return folly::makeUnexpected(EIO); } IORequest req{overlay.get()}; auto ret = ::fsync(file_.fd()); if (ret == -1) { return folly::makeUnexpected(errno); } return folly::makeExpected(ret); } folly::Expected OverlayFile::fallocate(off_t offset, off_t length) const { #ifdef __linux__ std::shared_ptr overlay = overlay_.lock(); if (!overlay) { return folly::makeUnexpected(EIO); } IORequest req{overlay.get()}; // Don't use posix_fallocate, because glibc may try to emulate it with writes // to each chunk, and we definitely don't want that. auto ret = ::fallocate(file_.fd(), 0, offset, length); if (ret == -1) { return folly::makeUnexpected(errno); } return folly::makeExpected(ret); #else (void)offset; (void)length; return folly::makeUnexpected(ENOSYS); #endif } folly::Expected OverlayFile::fdatasync() const { #ifndef __APPLE__ std::shared_ptr overlay = overlay_.lock(); if (!overlay) { return folly::makeUnexpected(EIO); } IORequest req{overlay.get()}; auto ret = ::fdatasync(file_.fd()); if (ret == -1) { return folly::makeUnexpected(errno); } return folly::makeExpected(ret); #else return fsync(); #endif } folly::Expected OverlayFile::readFile() const { std::shared_ptr overlay = overlay_.lock(); if (!overlay) { return folly::makeUnexpected(EIO); } IORequest req{overlay.get()}; std::string out; if (!folly::readFile(file_.fd(), out)) { return folly::makeUnexpected(errno); } return folly::makeExpected(std::move(out)); } } // namespace eden } // namespace facebook #endif