blob: f45dd5cc64b79ded6fa7675e56b597c70982b892 [file] [log] [blame] [edit]
// 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.
#ifndef FS_TRANSACTION_LEGACY_TRANSACTION_HANDLER_H_
#define FS_TRANSACTION_LEGACY_TRANSACTION_HANDLER_H_
#include <fs/transaction/device_transaction_handler.h>
namespace fs {
// TODO(fxbug.dev/49392): remove this class.
class LegacyTransactionHandler : public DeviceTransactionHandler {
public:
// Acquire the block size of the mounted filesystem.
// It is assumed that all inputs to the TransactionHandler
// interface are in |FsBlockSize()|-sized blocks.
virtual uint32_t FsBlockSize() const = 0;
// Acquires the block size of the underlying device.
virtual uint32_t DeviceBlockSize() const = 0;
// Issues a group of requests to the underlying device and waits
// for them to complete.
virtual zx_status_t Transaction(block_fifo_request_t* requests, size_t count) = 0;
};
// Enqueue multiple writes (or reads) to the underlying block device
// by shoving them into a simple array, to avoid duplicated ops
// within a single operation.
//
// TODO(smklein): This obviously has plenty of room for
// improvement, including:
// - Sorting blocks, combining ranges
// - Writing from multiple buffers (instead of one)
// - Cross-operation writeback delays
class BlockTxn {
public:
DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(BlockTxn);
explicit BlockTxn(LegacyTransactionHandler* handler);
~BlockTxn();
// Identify that an operation should be committed to disk
// at a later point in time.
void EnqueueOperation(uint32_t op, vmoid_t id, uint64_t vmo_offset, uint64_t dev_offset,
uint64_t nblocks);
// Activate the transaction.
zx_status_t Transact();
private:
LegacyTransactionHandler* handler_;
fbl::Vector<block_fifo_request_t> requests_;
};
// Provides a type-safe, low-cost abstraction over the |BlockTxn| class,
// allowing clients to avoid intermingling distinct operation types
// unless explicitly requested.
template <typename IdType, uint32_t operation>
class TypedTxn {
public:
DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(TypedTxn);
explicit TypedTxn(LegacyTransactionHandler* handler) : txn_(handler) {}
inline void Enqueue(IdType id, uint64_t vmo_offset, uint64_t dev_offset, uint64_t nblocks) {
txn_.EnqueueOperation(operation, id, vmo_offset, dev_offset, nblocks);
}
inline void EnqueueFlush() {
IdType id = 0;
uint64_t vmo_offset = 0;
uint64_t dev_offset = 0;
uint64_t nblocks = 0;
txn_.EnqueueOperation(BLOCKIO_FLUSH, id, vmo_offset, dev_offset, nblocks);
}
inline zx_status_t Transact() { return txn_.Transact(); }
private:
BlockTxn txn_;
};
using WriteTxn = TypedTxn<vmoid_t, BLOCKIO_WRITE>;
using ReadTxn = TypedTxn<vmoid_t, BLOCKIO_READ>;
} // namespace fs
#endif // FS_TRANSACTION_DEVICE_TRANSACTION_HANDLER_H_