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 <inttypes.h> 6 7#include <fbl/unique_fd.h> 8 9#include "fvm/container.h" 10 11zx_status_t Container::Create(const char* path, off_t offset, off_t length, 12 uint32_t flags, fbl::unique_ptr<Container>* container) { 13 if ((flags & ~fvm::kSparseFlagAllValid) != 0) { 14 fprintf(stderr, "Invalid flags: %08" PRIx32 "\n", flags); 15 return -1; 16 } 17 18 fbl::unique_fd fd(open(path, O_RDONLY)); 19 if (!fd) { 20 fprintf(stderr, "Unable to open path %s\n", path); 21 return -1; 22 } 23 24 uint8_t data[HEADER_SIZE]; 25 if (lseek(fd.get(), offset, SEEK_SET) < 0) { 26 fprintf(stderr, "Error seeking block device\n"); 27 return -1; 28 } 29 30 if (read(fd.get(), data, sizeof(data)) != sizeof(data)) { 31 fprintf(stderr, "Error reading block device\n"); 32 return -1; 33 } 34 35 fbl::AllocChecker ac; 36 if (!memcmp(data, fvm_magic, sizeof(fvm_magic))) { 37 fvm::fvm_t* sb = reinterpret_cast<fvm::fvm_t*>(data); 38 39 // Found fvm container 40 fbl::unique_ptr<Container> fvmContainer(new (&ac) FvmContainer(path, sb->slice_size, 41 offset, length)); 42 if (!ac.check()) { 43 return ZX_ERR_NO_MEMORY; 44 } 45 *container = fbl::move(fvmContainer); 46 return ZX_OK; 47 } 48 49 fvm::sparse_image_t* image = reinterpret_cast<fvm::sparse_image_t*>(data); 50 if (image->magic == fvm::kSparseFormatMagic) { 51 if (offset > 0) { 52 fprintf(stderr, "Invalid offset for sparse file\n"); 53 return ZX_ERR_INVALID_ARGS; 54 } 55 56 // Found sparse container 57 fbl::unique_ptr<Container> sparseContainer(new (&ac) SparseContainer(path, 58 image->slice_size, 59 flags)); 60 if (!ac.check()) { 61 return ZX_ERR_NO_MEMORY; 62 } 63 64 *container = fbl::move(sparseContainer); 65 return ZX_OK; 66 } 67 68 fprintf(stderr, "File format not supported\n"); 69 return ZX_ERR_NOT_SUPPORTED; 70} 71 72Container::Container(const char* path, size_t slice_size, uint32_t flags) 73 : dirty_(false), slice_size_(slice_size), flags_(flags) { 74 snprintf(path_, sizeof(path_), "%s", path); 75} 76 77Container::~Container() {} 78