Loading fs_mgr/libsnapshot/cow_writer.cpp +30 −8 Original line number Diff line number Diff line Loading @@ -110,15 +110,28 @@ bool CowWriter::ParseOptions() { return true; } bool CowWriter::SetFd(android::base::borrowed_fd fd) { if (fd.get() < 0) { owned_fd_.reset(open("/dev/null", O_RDWR | O_CLOEXEC)); if (owned_fd_ < 0) { PLOG(ERROR) << "open /dev/null failed"; return false; } fd_ = owned_fd_; is_dev_null_ = true; } else { fd_ = fd; } return true; } bool CowWriter::Initialize(unique_fd&& fd, OpenMode mode) { owned_fd_ = std::move(fd); return Initialize(borrowed_fd{owned_fd_}, mode); } bool CowWriter::Initialize(borrowed_fd fd, OpenMode mode) { fd_ = fd; if (!ParseOptions()) { if (!SetFd(fd) || !ParseOptions()) { return false; } Loading @@ -139,9 +152,7 @@ bool CowWriter::InitializeAppend(android::base::unique_fd&& fd, uint64_t label) } bool CowWriter::InitializeAppend(android::base::borrowed_fd fd, uint64_t label) { fd_ = fd; if (!ParseOptions()) { if (!SetFd(fd) || !ParseOptions()) { return false; } Loading Loading @@ -304,7 +315,7 @@ bool CowWriter::EmitLabel(uint64_t label) { CowOperation op = {}; op.type = kCowLabelOp; op.source = label; return WriteOperation(op) && !fsync(fd_.get()); return WriteOperation(op) && Sync(); } std::basic_string<uint8_t> CowWriter::Compress(const void* data, size_t length) { Loading Loading @@ -383,7 +394,7 @@ bool CowWriter::Finalize() { PLOG(ERROR) << "lseek ops failed"; return false; } return !fsync(fd_.get()); return Sync(); } uint64_t CowWriter::GetCowSize() { Loading Loading @@ -424,5 +435,16 @@ bool CowWriter::WriteRawData(const void* data, size_t size) { return true; } bool CowWriter::Sync() { if (is_dev_null_) { return true; } if (fsync(fd_.get()) < 0) { PLOG(ERROR) << "fsync failed"; return false; } return true; } } // namespace snapshot } // namespace android fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h +7 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,9 @@ class CowWriter : public ICowWriter { // If opening for write, the file starts from the beginning. // If opening for append, if the file has a footer, we start appending to the last op. // If the footer isn't found, the last label is considered corrupt, and dropped. // // If fd is < 0, the CowWriter will be opened against /dev/null. This is for // computing COW sizes without using storage space. bool Initialize(android::base::unique_fd&& fd, OpenMode mode = OpenMode::WRITE); bool Initialize(android::base::borrowed_fd fd, OpenMode mode = OpenMode::WRITE); // Set up a writer, assuming that the given label is the last valid label. Loading Loading @@ -119,6 +122,9 @@ class CowWriter : public ICowWriter { void AddOperation(const CowOperation& op); std::basic_string<uint8_t> Compress(const void* data, size_t length); bool SetFd(android::base::borrowed_fd fd); bool Sync(); private: android::base::unique_fd owned_fd_; android::base::borrowed_fd fd_; Loading @@ -126,6 +132,7 @@ class CowWriter : public ICowWriter { CowFooter footer_{}; int compression_ = 0; uint64_t next_op_pos_ = 0; bool is_dev_null_ = false; // :TODO: this is not efficient, but stringstream ubsan aborts because some // bytes overflow a signed char. Loading Loading
fs_mgr/libsnapshot/cow_writer.cpp +30 −8 Original line number Diff line number Diff line Loading @@ -110,15 +110,28 @@ bool CowWriter::ParseOptions() { return true; } bool CowWriter::SetFd(android::base::borrowed_fd fd) { if (fd.get() < 0) { owned_fd_.reset(open("/dev/null", O_RDWR | O_CLOEXEC)); if (owned_fd_ < 0) { PLOG(ERROR) << "open /dev/null failed"; return false; } fd_ = owned_fd_; is_dev_null_ = true; } else { fd_ = fd; } return true; } bool CowWriter::Initialize(unique_fd&& fd, OpenMode mode) { owned_fd_ = std::move(fd); return Initialize(borrowed_fd{owned_fd_}, mode); } bool CowWriter::Initialize(borrowed_fd fd, OpenMode mode) { fd_ = fd; if (!ParseOptions()) { if (!SetFd(fd) || !ParseOptions()) { return false; } Loading @@ -139,9 +152,7 @@ bool CowWriter::InitializeAppend(android::base::unique_fd&& fd, uint64_t label) } bool CowWriter::InitializeAppend(android::base::borrowed_fd fd, uint64_t label) { fd_ = fd; if (!ParseOptions()) { if (!SetFd(fd) || !ParseOptions()) { return false; } Loading Loading @@ -304,7 +315,7 @@ bool CowWriter::EmitLabel(uint64_t label) { CowOperation op = {}; op.type = kCowLabelOp; op.source = label; return WriteOperation(op) && !fsync(fd_.get()); return WriteOperation(op) && Sync(); } std::basic_string<uint8_t> CowWriter::Compress(const void* data, size_t length) { Loading Loading @@ -383,7 +394,7 @@ bool CowWriter::Finalize() { PLOG(ERROR) << "lseek ops failed"; return false; } return !fsync(fd_.get()); return Sync(); } uint64_t CowWriter::GetCowSize() { Loading Loading @@ -424,5 +435,16 @@ bool CowWriter::WriteRawData(const void* data, size_t size) { return true; } bool CowWriter::Sync() { if (is_dev_null_) { return true; } if (fsync(fd_.get()) < 0) { PLOG(ERROR) << "fsync failed"; return false; } return true; } } // namespace snapshot } // namespace android
fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h +7 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,9 @@ class CowWriter : public ICowWriter { // If opening for write, the file starts from the beginning. // If opening for append, if the file has a footer, we start appending to the last op. // If the footer isn't found, the last label is considered corrupt, and dropped. // // If fd is < 0, the CowWriter will be opened against /dev/null. This is for // computing COW sizes without using storage space. bool Initialize(android::base::unique_fd&& fd, OpenMode mode = OpenMode::WRITE); bool Initialize(android::base::borrowed_fd fd, OpenMode mode = OpenMode::WRITE); // Set up a writer, assuming that the given label is the last valid label. Loading Loading @@ -119,6 +122,9 @@ class CowWriter : public ICowWriter { void AddOperation(const CowOperation& op); std::basic_string<uint8_t> Compress(const void* data, size_t length); bool SetFd(android::base::borrowed_fd fd); bool Sync(); private: android::base::unique_fd owned_fd_; android::base::borrowed_fd fd_; Loading @@ -126,6 +132,7 @@ class CowWriter : public ICowWriter { CowFooter footer_{}; int compression_ = 0; uint64_t next_op_pos_ = 0; bool is_dev_null_ = false; // :TODO: this is not efficient, but stringstream ubsan aborts because some // bytes overflow a signed char. Loading