Home | History | Annotate | Download | only in squashfs_utils
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "squashfs_utils.h"
     18 
     19 #include <cutils/fs.h>
     20 #include <cutils/klog.h>
     21 #include <errno.h>
     22 #include <fcntl.h>
     23 #include <stdlib.h>
     24 #include <string.h>
     25 #include <unistd.h>
     26 
     27 #include "squashfs_fs.h"
     28 
     29 #ifdef SQUASHFS_NO_KLOG
     30 #include <stdio.h>
     31 #define ERROR(x...)   fprintf(stderr, x)
     32 #else
     33 #define ERROR(x...)   KLOG_ERROR("squashfs_utils", x)
     34 #endif
     35 
     36 size_t squashfs_get_sb_size()
     37 {
     38     return sizeof(struct squashfs_super_block);
     39 }
     40 
     41 int squashfs_parse_sb_buffer(const void *buf, struct squashfs_info *info)
     42 {
     43     const struct squashfs_super_block *sb =
     44         (const struct squashfs_super_block *)buf;
     45 
     46     if (sb->s_magic != SQUASHFS_MAGIC) {
     47         return -1;
     48     }
     49 
     50     info->block_size = sb->block_size;
     51     info->inodes = sb->inodes;
     52     info->bytes_used = sb->bytes_used;
     53     // by default mksquashfs pads the filesystem to 4K blocks
     54     info->bytes_used_4K_padded =
     55         sb->bytes_used + (4096 - (sb->bytes_used & (4096 - 1)));
     56 
     57     return 0;
     58 }
     59 
     60 int squashfs_parse_sb(const char *blk_device, struct squashfs_info *info)
     61 {
     62     int ret = 0;
     63     struct squashfs_super_block sb;
     64     int data_device;
     65 
     66     data_device = TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC));
     67     if (data_device == -1) {
     68         ERROR("Error opening block device (%s)\n", strerror(errno));
     69         return -1;
     70     }
     71 
     72     if (TEMP_FAILURE_RETRY(read(data_device, &sb, sizeof(sb)))
     73             != sizeof(sb)) {
     74         ERROR("Error reading superblock\n");
     75         ret = -1;
     76         goto cleanup;
     77     }
     78 
     79     if (squashfs_parse_sb_buffer(&sb, info) == -1) {
     80         ERROR("Not a valid squashfs filesystem\n");
     81         ret = -1;
     82         goto cleanup;
     83     }
     84 
     85 cleanup:
     86     close(data_device);
     87     return ret;
     88 }
     89