blob: 8dc1bda11b0eb674bf1904068704ac837a7e7e74 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fs/transaction/device_transaction_handler.h>
namespace fs {
zx_status_t DeviceTransactionHandler::RunRequests(
const std::vector<storage::BufferedOperation>& operations) {
if (operations.empty()) {
return ZX_OK;
}
// Update all the outgoing transactions to be in disk blocks.
std::vector<block_fifo_request_t> block_requests(operations.size());
for (size_t i = 0; i < operations.size(); i++) {
auto& request = block_requests[i];
request.vmoid = operations[i].vmoid;
const auto& operation = operations[i].op;
switch (operation.type) {
case storage::OperationType::kRead:
request.opcode = BLOCKIO_READ;
break;
case storage::OperationType::kWrite:
request.opcode = BLOCKIO_WRITE;
break;
case storage::OperationType::kTrim:
request.opcode = BLOCKIO_TRIM;
break;
default:
ZX_DEBUG_ASSERT_MSG(false, "Unsupported operation");
}
// For the time being, restrict a transaction to operations of the same type.
// This probably can be relaxed, as the concept of a transaction implies the
// operations take place logically at the same time, so even if there's a
// mix of reads and writes, it doesn't make sense to depend on the relative
// order of the operations, which is what could break with the merging done
// by the request builder.
ZX_DEBUG_ASSERT(operation.type == operations[0].op.type);
request.vmo_offset = BlockNumberToDevice(operation.vmo_offset);
request.dev_offset = BlockNumberToDevice(operation.dev_offset);
uint64_t length = BlockNumberToDevice(operation.length);
if (length > std::numeric_limits<decltype(request.length)>::max()) {
return ZX_ERR_OUT_OF_RANGE;
}
request.length = static_cast<decltype(request.length)>(length);
}
return GetDevice()->FifoTransaction(&block_requests[0], operations.size());
}
zx_status_t DeviceTransactionHandler::Flush() {
block_fifo_request_t request = {.opcode = BLOCKIO_FLUSH};
return GetDevice()->FifoTransaction(&request, 1);
}
} // namespace fs