Home | History | Annotate | Download | only in filesystems
      1 // Copyright 2014 The Android Open Source Project
      2 //
      3 // This software is licensed under the terms of the GNU General Public
      4 // License version 2, as published by the Free Software Foundation, and
      5 // may be copied, distributed, and modified under those terms.
      6 //
      7 // This program is distributed in the hope that it will be useful,
      8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
      9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     10 // GNU General Public License for more details.
     11 
     12 #include "android/filesystems/ext4_utils.h"
     13 
     14 #include "android/base/Log.h"
     15 #include "android/base/files/ScopedStdioFile.h"
     16 
     17 #include "make_ext4fs.h"
     18 
     19 #include <stdint.h>
     20 #include <string.h>
     21 
     22 #define DEBUG_EXT4  0
     23 
     24 #define EXT4_LOG     LOG_IF(INFO, DEBUG_EXT4)
     25 #define EXT4_PLOG    PLOG_IF(INFO, DEBUG_EXT4)
     26 #define EXT4_ERROR   LOG_IF(ERROR, DEBUG_EXT4)
     27 #define EXT4_PERROR  PLOG_IF(ERROR, DEBUG_EXT4)
     28 
     29 struct Ext4Magic {
     30     static const size_t kOffset = 0x438U;
     31     static const size_t kSize = 2U;
     32     static const uint8_t kExpected[kSize];
     33 };
     34 
     35 const uint8_t Ext4Magic::kExpected[kSize] = { 0x53, 0xef };
     36 
     37 bool android_pathIsExt4PartitionImage(const char* path) {
     38     if (!path) {
     39         EXT4_ERROR << "NULL path parameter";
     40         return false;
     41     }
     42 
     43     android::base::ScopedStdioFile file(::fopen(path, "rb"));
     44     if (!file.get()) {
     45         EXT4_PERROR << "Could not open file: " << path;
     46         return false;
     47     }
     48 
     49     if (::fseek(file.get(), Ext4Magic::kOffset, SEEK_SET) != 0) {
     50         EXT4_LOG << "Can't seek to byte " << Ext4Magic::kOffset
     51                  << " of " << path;
     52         return false;
     53     }
     54 
     55     char magic[Ext4Magic::kSize];
     56     if (::fread(magic, sizeof(magic), 1, file.get()) != 1) {
     57         EXT4_PLOG << "Could not read " << sizeof(magic)
     58                   << " bytes from " << path;
     59         return false;
     60     }
     61 
     62     if (!::memcmp(magic, Ext4Magic::kExpected, sizeof(magic))) {
     63         EXT4_LOG << "File is Ext4 partition image: " << path;
     64         return true;
     65     }
     66 
     67     EXT4_LOG << "Not an Ext4 partition image: " << path;
     68     return false;
     69 }
     70 
     71 int android_createEmptyExt4Image(const char *filePath,
     72                                  uint64_t size,
     73                                  const char *mountpoint) {
     74     int ret = ::make_ext4fs(filePath, size, mountpoint, NULL);
     75     if (ret < 0)
     76         EXT4_ERROR << "Failed to create ext4 image at: " << filePath;
     77     return ret;
     78 }
     79