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 #include <stdlib.h>
6 #include <string.h>
7 
8 #include <bitmap/raw-bitmap.h>
9 
10 #ifdef __Fuchsia__
11 #include <lib/fzl/owned-vmo-mapper.h>
12 #endif
13 
14 #include <minfs/block-txn.h>
15 #include <minfs/superblock.h>
16 
17 #include <utility>
18 
19 namespace minfs {
20 
21 #ifdef __Fuchsia__
22 
SuperblockManager(const Superblock * info,fzl::OwnedVmoMapper mapper)23 SuperblockManager::SuperblockManager(const Superblock* info, fzl::OwnedVmoMapper mapper) :
24     mapping_(std::move(mapper)) {}
25 
26 #else
27 
28 SuperblockManager::SuperblockManager(const Superblock* info) {
29     memcpy(&info_blk_[0], info, sizeof(Superblock));
30 }
31 
32 #endif
33 
34 SuperblockManager::~SuperblockManager() = default;
35 
Create(Bcache * bc,const Superblock * info,fbl::unique_ptr<SuperblockManager> * out)36 zx_status_t SuperblockManager::Create(Bcache* bc, const Superblock* info,
37                                       fbl::unique_ptr<SuperblockManager>* out) {
38     zx_status_t status = CheckSuperblock(info, bc);
39     if (status != ZX_OK) {
40         FS_TRACE_ERROR("Minfs::Create failed to check info: %d\n", status);
41         return status;
42     }
43 
44 #ifdef __Fuchsia__
45     fzl::OwnedVmoMapper mapper;
46     // Create the info vmo
47     if ((status = mapper.CreateAndMap(kMinfsBlockSize, "minfs-superblock")) != ZX_OK) {
48         return status;
49     }
50 
51     vmoid_t info_vmoid;
52     if ((status = bc->AttachVmo(mapper.vmo(), &info_vmoid)) != ZX_OK) {
53         return status;
54     }
55     memcpy(mapper.start(), info, sizeof(Superblock));
56 
57     auto sb = fbl::unique_ptr<SuperblockManager>(new SuperblockManager(info, std::move(mapper)));
58 #else
59     auto sb = fbl::unique_ptr<SuperblockManager>(new SuperblockManager(info));
60 #endif
61     *out = std::move(sb);
62     return ZX_OK;
63 }
64 
Write(WriteTxn * txn)65 void SuperblockManager::Write(WriteTxn* txn) {
66 #ifdef __Fuchsia__
67     auto data = mapping_.vmo().get();
68 #else
69     auto data = &info_blk_[0];
70 #endif
71     txn->Enqueue(data, 0, 0, 1);
72 }
73 
74 } // namespace minfs
75