1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#pragma once
6
7#include <vector>
8
9#include <blobfs/host.h>
10#include <digest/digest.h>
11#include <fbl/array.h>
12#include <fbl/vector.h>
13#include <fs-host/common.h>
14#include <lib/fit/defer.h>
15
16// Merkle Tree information associated with a file.
17struct MerkleInfo {
18    // Merkle-Tree related information.
19    digest::Digest digest;
20    fbl::Array<uint8_t> merkle;
21
22    // The path which generated this file, and a cached file length.
23    fbl::String path;
24    uint64_t length;
25};
26
27class BlobfsCreator : public FsCreator {
28public:
29    BlobfsCreator()
30        : FsCreator(blobfs::kStartBlockMinimum) {}
31
32private:
33    // Parent overrides:
34    zx_status_t Usage() override;
35    const char* GetToolName() override { return "blobfs"; }
36    bool IsCommandValid(Command command) override;
37    bool IsOptionValid(Option option) override;
38    bool IsArgumentValid(Argument argument) override;
39
40    // Identify blobs to be operated on, populating the internal
41    // |blob_list_|.
42    zx_status_t ProcessManifestLine(FILE* manifest, const char* dir_path) override;
43    zx_status_t ProcessCustom(int argc, char** argv, uint8_t* processed) override;
44
45    // Calculates merkle trees for the processed blobs, and determines
46    // the total size of the underlying storage necessary to contain them.
47    zx_status_t CalculateRequiredSize(off_t* out) override;
48
49    //TODO(planders): Add ls support for blobfs.
50    zx_status_t Mkfs() override;
51    zx_status_t Fsck() override;
52    zx_status_t Add() override;
53
54    // A comparison function used to quickly compare MerkleInfo.
55    struct DigestCompare {
56        inline bool operator()(const MerkleInfo& lhs, const MerkleInfo& rhs) const {
57            const uint8_t* lhs_bytes = lhs.digest.AcquireBytes();
58            const uint8_t* rhs_bytes = rhs.digest.AcquireBytes();
59            auto auto_release = fit::defer([&]() {
60                lhs.digest.ReleaseBytes();
61                rhs.digest.ReleaseBytes();
62            });
63
64            for (size_t i = 0; i < digest::Digest::kLength; i++) {
65                if (lhs_bytes[i] < rhs_bytes[i]) {
66                    return true;
67                }
68            }
69            return false;
70        }
71    };
72
73    // List of all blobs to be copied into blobfs.
74    fbl::Vector<fbl::String> blob_list_;
75
76    // A list of Merkle Information for blobs in |blob_list_|.
77    std::vector<MerkleInfo> merkle_list_;
78};
79
80