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