1 // Copyright 2017 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 <utility>
6 
7 #include "fvm-host/format.h"
8 
Format()9 Format::Format() : fvm_ready_(false), vpart_index_(0),  flags_(0) {}
10 
Detect(int fd,off_t offset,disk_format_t * out)11 zx_status_t Format::Detect(int fd, off_t offset, disk_format_t* out) {
12     uint8_t data[HEADER_SIZE];
13     if (lseek(fd, offset, SEEK_SET) < 0) {
14         fprintf(stderr, "Error seeking block device\n");
15         return ZX_ERR_IO;
16     }
17 
18     if (read(fd, data, sizeof(data)) != sizeof(data)) {
19         fprintf(stderr, "Error reading block device\n");
20         return ZX_ERR_IO;
21     }
22 
23     if (!memcmp(data, minfs_magic, sizeof(minfs_magic))) {
24         *out = DISK_FORMAT_MINFS;
25     } else if (!memcmp(data, blobfs_magic, sizeof(blobfs_magic))) {
26         *out = DISK_FORMAT_BLOBFS;
27     } else {
28         *out = DISK_FORMAT_UNKNOWN;
29     }
30 
31     return ZX_OK;
32 }
33 
Create(const char * path,const char * type,fbl::unique_ptr<Format> * out)34 zx_status_t Format::Create(const char* path, const char* type, fbl::unique_ptr<Format>* out) {
35     fbl::unique_fd fd(open(path, O_RDONLY));
36     if (!fd) {
37         fprintf(stderr, "Format::Create: Could not open %s\n", path);
38         return ZX_ERR_IO;
39     }
40 
41     zx_status_t status;
42     disk_format_t part;
43     if ((status = Detect(fd.get(), 0, &part)) != ZX_OK) {
44         return status;
45     }
46 
47     if (part == DISK_FORMAT_MINFS) {
48         // Found minfs partition
49         fbl::unique_ptr<Format> minfsFormat(new MinfsFormat(std::move(fd), type));
50         *out = std::move(minfsFormat);
51         return ZX_OK;
52     } else if (part == DISK_FORMAT_BLOBFS) {
53         // Found blobfs partition
54         fbl::unique_ptr<Format> blobfsFormat(new  BlobfsFormat(std::move(fd), type));
55         *out = std::move(blobfsFormat);
56         return ZX_OK;
57     }
58 
59     fprintf(stderr, "Disk format not supported\n");
60     return ZX_ERR_NOT_SUPPORTED;
61 }
62 
Check(fbl::unique_fd fd,off_t start,off_t end,const fbl::Vector<size_t> & extent_lengths,disk_format_t part)63 zx_status_t Format::Check(fbl::unique_fd fd, off_t start, off_t end,
64                           const fbl::Vector<size_t>& extent_lengths, disk_format_t part) {
65     if (part == DISK_FORMAT_BLOBFS) {
66         return blobfs::blobfs_fsck(std::move(fd), start, end, extent_lengths);
67     } else if (part == DISK_FORMAT_MINFS) {
68         return minfs::SparseFsck(std::move(fd), start, end, extent_lengths);
69     }
70 
71     fprintf(stderr, "Format not supported\n");
72     return ZX_ERR_INVALID_ARGS;
73 }
74