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