zircon/system/ulib/fs/journal/test/journal_test.cc
// Tests that metadata operations are ordered at the time "WriteMetadata" is invoked.
Tests that metadata operations are ordered at the time "WriteMetadata" is invoked.
Tests that metadata operations are ordered at the time " WriteMetadata " is invoked .
TEST_F(JournalTest, MetadataOperationsAreOrderedGlobally) {
  storage::VmoBuffer metadata = registry()->InitializeBuffer(kJournalLength);
  const std::vector<storage::UnbufferedOperation> operations = {
      {
          zx::unowned_vmo(metadata.vmo().get()),
          {
              storage::OperationType::kWrite,
              .vmo_offset = 0,
              .dev_offset = 20,
              .length = 1,
          },
      },
      {
          zx::unowned_vmo(metadata.vmo().get()),
          {
              storage::OperationType::kWrite,
              .vmo_offset = 2,
              .dev_offset = 1234,
              .length = 1,
          },
      },
  };
  constexpr uint64_t kJournalStartBlock = 55;
  JournalRequestVerifier verifier(registry()->info(), registry()->journal(),
                                  registry()->writeback(), kJournalStartBlock);
  MockTransactionHandler::TransactionCallback callbacks[] = {
      [&](const std::vector<storage::BufferedOperation>& requests) {
        verifier.VerifyJournalWrite(operations[0], requests);
        return ZX_OK;
      },
      [&](const std::vector<storage::BufferedOperation>& requests) {
        verifier.VerifyMetadataWrite(operations[0], requests);
        verifier.ExtendJournalOffset(operations[0].op.length + kEntryMetadataBlocks);
        return ZX_OK;
      },
      [&](const std::vector<storage::BufferedOperation>& requests) {
        verifier.VerifyJournalWrite(operations[1], requests);
        return ZX_OK;
      },
      [&](const std::vector<storage::BufferedOperation>& requests) {
        verifier.VerifyMetadataWrite(operations[1], requests);
        verifier.ExtendJournalOffset(operations[1].op.length + kEntryMetadataBlocks);
        return ZX_OK;
      },
      [&](const std::vector<storage::BufferedOperation>& requests) {
        uint64_t sequence_number = 2;
        verifier.VerifyInfoBlockWrite(sequence_number, requests);
        return ZX_OK;
      },
  };
  MockTransactionHandler handler(registry(), callbacks, std::size(callbacks));
  {
    Journal journal(&handler, take_info(), take_journal_buffer(), take_data_buffer(),
                    kJournalStartBlock, Journal::Options());
    auto first_promise = journal.WriteMetadata({operations[0]});
    auto second_promise = journal.WriteMetadata({operations[1]});
    journal.schedule_task(std::move(second_promise));
    journal.schedule_task(std::move(first_promise));
  }
}
TEST_F ( JournalTest , MetadataOperationsAreOrderedGlobally ) { storage :: VmoBuffer metadata = registry ( ) -> InitializeBuffer ( kJournalLength ) ; const std :: vector < storage :: UnbufferedOperation > operations = { { zx :: unowned_vmo ( metadata . vmo ( ) . get ( ) ) , { storage :: OperationType :: kWrite , . vmo_offset = 0 , . dev_offset = 20 , . length = 1 , } , } , { zx :: unowned_vmo ( metadata . vmo ( ) . get ( ) ) , { storage :: OperationType :: kWrite , . vmo_offset = 2 , . dev_offset = 1234 , . length = 1 , } , } , } ; constexpr uint64_t kJournalStartBlock = 55 ; JournalRequestVerifier verifier ( registry ( ) -> info ( ) , registry ( ) -> journal ( ) , registry ( ) -> writeback ( ) , kJournalStartBlock ) ; MockTransactionHandler :: TransactionCallback callbacks [ ] = { [ & ] ( const std :: vector < storage :: BufferedOperation > & requests ) { verifier . VerifyJournalWrite ( operations [ 0 ] , requests ) ; return ZX_OK ; } , [ & ] ( const std :: vector < storage :: BufferedOperation > & requests ) { verifier . VerifyMetadataWrite ( operations [ 0 ] , requests ) ; verifier . ExtendJournalOffset ( operations [ 0 ] . op . length + kEntryMetadataBlocks ) ; return ZX_OK ; } , [ & ] ( const std :: vector < storage :: BufferedOperation > & requests ) { verifier . VerifyJournalWrite ( operations [ 1 ] , requests ) ; return ZX_OK ; } , [ & ] ( const std :: vector < storage :: BufferedOperation > & requests ) { verifier . VerifyMetadataWrite ( operations [ 1 ] , requests ) ; verifier . ExtendJournalOffset ( operations [ 1 ] . op . length + kEntryMetadataBlocks ) ; return ZX_OK ; } , [ & ] ( const std :: vector < storage :: BufferedOperation > & requests ) { uint64_t sequence_number = 2 ; verifier . VerifyInfoBlockWrite ( sequence_number , requests ) ; return ZX_OK ; } , } ; MockTransactionHandler handler ( registry ( ) , callbacks , std :: size ( callbacks ) ) ; { Journal journal ( & handler , take_info ( ) , take_journal_buffer ( ) , take_data_buffer ( ) , kJournalStartBlock , Journal :: Options ( ) ) ; auto first_promise = journal . WriteMetadata ( { operations [ 0 ] } ) ; auto second_promise = journal . WriteMetadata ( { operations [ 1 ] } ) ; journal . schedule_task ( std :: move ( second_promise ) ) ; journal . schedule_task ( std :: move ( first_promise ) ) ; } }
Tests that metadata operations are ordered at the time "WriteMetadata" is invoked.
Tests that metadata operations are ordered at the time " WriteMetadata " is invoked .
// Even though we schedule the second promise first, the first promise will still complete // before the second, and we will see the writes to disk completed in the expected order.