Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb28e0c4 authored by Sandeep Patil's avatar Sandeep Patil
Browse files

fiemap_writer: enforce filesystem optimal block size alignment



... instead of using the block size from the underlying block device.

Bug: 121211685
Test: fiemap_writer_test /dev/block/sda21 (on blueline)

Change-Id: I6038d3f06505a397280b0482e33814b4883be9a2
Signed-off-by: default avatarSandeep Patil <sspatil@google.com>
parent d2b2e21f
Loading
Loading
Loading
Loading
+14 −24
Original line number Original line Diff line number Diff line
@@ -165,23 +165,13 @@ static bool FileToBlockDevicePath(const std::string& file_path, std::string* bde
    return true;
    return true;
}
}


static bool GetBlockDeviceParams(int bdev_fd, const std::string& bdev_path, uint64_t* blocksz,
static bool GetBlockDeviceSize(int bdev_fd, const std::string& bdev_path, uint64_t* bdev_size) {
                                 uint64_t* bdev_size) {
    // TODO: For some reason, the block device ioctl require the argument to be initialized
    // to zero even if its the out parameter for the given ioctl cmd.
    uint64_t blksz = 0;
    if (ioctl(bdev_fd, BLKBSZGET, &blksz)) {
        PLOG(ERROR) << "Failed to get block size for: " << bdev_path;
        return false;
    }

    uint64_t size_in_bytes = 0;
    uint64_t size_in_bytes = 0;
    if (ioctl(bdev_fd, BLKGETSIZE64, &size_in_bytes)) {
    if (ioctl(bdev_fd, BLKGETSIZE64, &size_in_bytes)) {
        PLOG(ERROR) << "Failed to get total size for: " << bdev_path;
        PLOG(ERROR) << "Failed to get total size for: " << bdev_path;
        return false;
        return false;
    }
    }


    *blocksz = blksz;
    *bdev_size = size_in_bytes;
    *bdev_size = size_in_bytes;


    return true;
    return true;
@@ -197,22 +187,20 @@ static uint64_t GetFileSize(const std::string& file_path) {
    return sb.st_size;
    return sb.st_size;
}
}


static bool PerformFileChecks(const std::string& file_path, uint64_t file_size, uint64_t blocksz,
static bool PerformFileChecks(const std::string& file_path, uint64_t file_size, uint64_t* blocksz,
                              uint32_t* fs_type) {
                              uint32_t* fs_type) {
    // Check if the size aligned to the block size of the block device.
    // We need this to be true in order to be able to write the file using FIEMAP.
    if (file_size % blocksz) {
        LOG(ERROR) << "File size " << file_size << " is not aligned to block size " << blocksz
                   << " for file " << file_path;
        return false;
    }

    struct statfs64 sfs;
    struct statfs64 sfs;
    if (statfs64(file_path.c_str(), &sfs)) {
    if (statfs64(file_path.c_str(), &sfs)) {
        PLOG(ERROR) << "Failed to read file system status at: " << file_path;
        PLOG(ERROR) << "Failed to read file system status at: " << file_path;
        return false;
        return false;
    }
    }


    if (file_size % sfs.f_bsize) {
        LOG(ERROR) << "File size " << file_size << " is not aligned to optimal block size "
                   << sfs.f_bsize << " for file " << file_path;
        return false;
    }

    // Check if the filesystem is of supported types.
    // Check if the filesystem is of supported types.
    // Only ext4 and f2fs are tested and supported.
    // Only ext4 and f2fs are tested and supported.
    if ((sfs.f_type != EXT4_SUPER_MAGIC) && (sfs.f_type != F2FS_SUPER_MAGIC)) {
    if ((sfs.f_type != EXT4_SUPER_MAGIC) && (sfs.f_type != F2FS_SUPER_MAGIC)) {
@@ -226,6 +214,7 @@ static bool PerformFileChecks(const std::string& file_path, uint64_t file_size,
        return false;
        return false;
    }
    }


    *blocksz = sfs.f_bsize;
    *fs_type = sfs.f_type;
    *fs_type = sfs.f_type;
    return true;
    return true;
}
}
@@ -463,9 +452,9 @@ FiemapUniquePtr FiemapWriter::Open(const std::string& file_path, uint64_t file_s
        return nullptr;
        return nullptr;
    }
    }


    uint64_t blocksz, bdevsz;
    uint64_t bdevsz;
    if (!GetBlockDeviceParams(bdev_fd, bdev_path, &blocksz, &bdevsz)) {
    if (!GetBlockDeviceSize(bdev_fd, bdev_path, &bdevsz)) {
        LOG(ERROR) << "Failed to get block device params for: " << bdev_path;
        LOG(ERROR) << "Failed to get block device size for : " << bdev_path;
        cleanup(file_path, create);
        cleanup(file_path, create);
        return nullptr;
        return nullptr;
    }
    }
@@ -478,8 +467,9 @@ FiemapUniquePtr FiemapWriter::Open(const std::string& file_path, uint64_t file_s
        }
        }
    }
    }


    uint64_t blocksz;
    uint32_t fs_type;
    uint32_t fs_type;
    if (!PerformFileChecks(abs_path, file_size, blocksz, &fs_type)) {
    if (!PerformFileChecks(abs_path, file_size, &blocksz, &fs_type)) {
        LOG(ERROR) << "Failed to validate file or file system for file:" << abs_path;
        LOG(ERROR) << "Failed to validate file or file system for file:" << abs_path;
        cleanup(abs_path, create);
        cleanup(abs_path, create);
        return nullptr;
        return nullptr;