Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ce69f298 authored by Daniel Rosenberg's avatar Daniel Rosenberg Committed by David Anderson
Browse files

libsnapshot: Don't try to truncate block devices

When we're writing to a block device, we can't truncate. Ignore those
commands. Truncate mostly just saves time in the read phase by chopping
off unused data in the event finalize wasn't called.

Bug: 172026020
Test: cow_api_test
Change-Id: I3befc71fa9597edf8243d0f9e17440db91409aea
parent 99ed2152
Loading
Loading
Loading
Loading
+21 −4
Original line number Diff line number Diff line
@@ -122,6 +122,13 @@ bool CowWriter::SetFd(android::base::borrowed_fd fd) {
        is_dev_null_ = true;
    } else {
        fd_ = fd;

        struct stat stat;
        if (fstat(fd.get(), &stat) < 0) {
            PLOG(ERROR) << "fstat failed";
            return false;
        }
        is_block_device_ = S_ISBLK(stat.st_mode);
    }
    return true;
}
@@ -217,12 +224,11 @@ bool CowWriter::OpenForAppend(uint64_t label) {
    // Free reader so we own the descriptor position again.
    reader = nullptr;

    // Position for new writing
    if (ftruncate(fd_.get(), next_op_pos_) != 0) {
        PLOG(ERROR) << "Failed to trim file";
    // Remove excess data
    if (!Truncate(next_op_pos_)) {
        return false;
    }
    if (lseek(fd_.get(), 0, SEEK_END) < 0) {
    if (lseek(fd_.get(), next_op_pos_, SEEK_SET) < 0) {
        PLOG(ERROR) << "lseek failed";
        return false;
    }
@@ -445,5 +451,16 @@ bool CowWriter::CommitMerge(int merged_ops) {
    return Sync();
}

bool CowWriter::Truncate(off_t length) {
    if (is_dev_null_ || is_block_device_) {
        return true;
    }
    if (ftruncate(fd_.get(), length) < 0) {
        PLOG(ERROR) << "Failed to truncate.";
        return false;
    }
    return true;
}

}  // namespace snapshot
}  // namespace android
+2 −0
Original line number Diff line number Diff line
@@ -123,6 +123,7 @@ class CowWriter : public ICowWriter {

    bool SetFd(android::base::borrowed_fd fd);
    bool Sync();
    bool Truncate(off_t length);

  private:
    android::base::unique_fd owned_fd_;
@@ -133,6 +134,7 @@ class CowWriter : public ICowWriter {
    uint64_t next_op_pos_ = 0;
    bool is_dev_null_ = false;
    bool merge_in_progress_ = false;
    bool is_block_device_ = false;

    // :TODO: this is not efficient, but stringstream ubsan aborts because some
    // bytes overflow a signed char.