M host-tools/genlittlefs/lfs_ioaccess.c => host-tools/genlittlefs/lfs_ioaccess.c +4 -0
@@ 171,6 171,7 @@ struct lfs_ioaccess_context *lfs_ioaccess_open(struct lfs_config *cfg,
}
ret->file_des = open(filename, O_RDWR);
if (ret->file_des < 0) {
+ free((void *)ret->empty_flash_mem);
free(ret);
return NULL;
}
@@ 178,6 179,7 @@ struct lfs_ioaccess_context *lfs_ioaccess_open(struct lfs_config *cfg,
int err = fstat(ret->file_des, &statbuf);
if (err < 0) {
close(ret->file_des);
+ free((void *)ret->empty_flash_mem);
free(ret);
return NULL;
}
@@ 186,6 188,7 @@ struct lfs_ioaccess_context *lfs_ioaccess_open(struct lfs_config *cfg,
err = ioctl(ret->file_des, BLKGETSIZE64, &blk_size);
if (err < 0) {
close(ret->file_des);
+ free((void *)ret->empty_flash_mem);
free(ret);
return NULL;
}
@@ 199,6 202,7 @@ struct lfs_ioaccess_context *lfs_ioaccess_open(struct lfs_config *cfg,
if (partition) {
if (partition->end > statbuf.st_size) {
close(ret->file_des);
+ free((void *)ret->empty_flash_mem);
free(ret);
errno = E2BIG;
return NULL;
M host-tools/genlittlefs/mklfs.c => host-tools/genlittlefs/mklfs.c +4 -1
@@ 308,6 308,7 @@ int main(int argc, char **argv)
err = ftruncate(fds, lopts.filesystem_size);
if (err) {
perror("Unable to truncate file");
+ close(fds);
free(lopts.src_dirs);
return EXIT_FAILURE;
}
@@ 364,6 365,7 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}
}
+ const lfs_ssize_t used_blocks = lfs_fs_size(&lfs);
err = lfs_unmount(&lfs);
if (err < 0) {
fprintf(stderr, "lfs umount error: error=%d\n", err);
@@ 375,11 377,12 @@ int main(int argc, char **argv)
lfs_ioaccess_close(ioctx);
printf("Littlefs summary:\n"
" Directories created: %lu, Files added: %lu, Transferred %lu kbytes.\n"
- " Littlefs block size: %i blocks count: %i.\n",
+ " Littlefs block size: %i blocks: %i/%i.\n",
prog_summary.directories_added,
prog_summary.files_added,
prog_summary.bytes_transferred / 1024UL,
cfg.block_size,
+ used_blocks,
cfg.block_count);
return EXIT_SUCCESS;
}
M host-tools/genlittlefs/parse_partitions.c => host-tools/genlittlefs/parse_partitions.c +45 -21
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <blkid.h>
#include "parse_partitions.h"
@@ 6,10 6,14 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
-
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <linux/fs.h>
+#include <fcntl.h>
+#include <unistd.h>
static const size_t sector_size = 512;
-static const size_t part_offset = 446;
-static const size_t part_size = 16;
+static const size_t bootstrap_offset = 0x00E0;
struct partition *find_partitions(const char *filename, part_type_t ptype, size_t *nelems)
{
@@ 80,35 84,55 @@ static inline unsigned calculate_shift(uint32_t v)
return mult_bruijn_bit_position[(uint32_t)(v * 0x07C4ACDDU) >> 27];
}
+static ssize_t sector_block_size(int filedes)
+{
+ struct stat statbuf;
+ int err = fstat(filedes, &statbuf);
+ if (err < 0) {
+ return err;
+ }
+ uint64_t blk_sz;
+ if (S_ISBLK(statbuf.st_mode)) {
+ err = ioctl(filedes, BLKSSZGET, &blk_sz);
+ if (err < 0) {
+ return err;
+ }
+ }
+ else {
+ blk_sz = 512;
+ }
+ return blk_sz;
+}
+
int write_partition_bootunit(const char *filename, int part_num, uint32_t block_size)
{
if (!filename) {
errno = EINVAL;
return -1;
}
- const uint8_t boot = calculate_shift(block_size);
- const loff_t fil_offs = part_offset + (part_num - 1) * part_size;
- FILE *fil = fopen(filename, "r+");
- if (!fil) {
- return -1;
- }
- if (fseek(fil, fil_offs, SEEK_SET) < 0) {
- fclose(fil);
+ const int fd = open(filename, O_RDWR);
+ if (fd < 0) {
return -1;
}
- uint8_t boot_rd;
- if (fread(&boot_rd, sizeof boot_rd, 1, fil) != 1) {
- fclose(fil);
+ const ssize_t sector_size = sector_block_size(fd);
+ char *const sect_buf = malloc(sector_size);
+ if (read(fd, sect_buf, sector_size) != sector_size) {
+ close(fd);
+ free(sect_buf);
return -1;
}
- if (fseek(fil, fil_offs, SEEK_SET) < 0) {
- fclose(fil);
+ const uint8_t log2_block_size = calculate_shift(block_size);
+ sect_buf[bootstrap_offset + part_num] = log2_block_size;
+ if (lseek(fd, 0, SEEK_SET) < 0) {
+ close(fd);
+ free(sect_buf);
return -1;
}
- uint8_t boot_wr = (boot_rd & 0x80) | (boot & 0x7f);
- if (fwrite(&boot_wr, sizeof boot_wr, 1, fil) != 1) {
- fclose(fil);
+ if (write(fd, sect_buf, sector_size) != sector_size) {
+ close(fd);
+ free(sect_buf);
return -1;
}
- return fclose(fil);
+ free(sect_buf);
+ return close(fd);
}
M module-vfs/src/newlib/vfs_io_syscalls.cpp => module-vfs/src/newlib/vfs_io_syscalls.cpp +7 -1
@@ 355,7 355,13 @@ namespace vfsn::internal::syscalls
unsigned long int rwflag,
const void *data)
{
- return invoke_fs(_errno_, &purefs::fs::filesystem::mount, special_file, dir, fstype, rwflag, data);
+ return invoke_fs(_errno_,
+ &purefs::fs::filesystem::mount,
+ special_file ? special_file : "",
+ dir ? dir : "",
+ fstype ? fstype : "",
+ rwflag,
+ data);
}
} // namespace vfsn::internal::syscalls
M module-vfs/src/purefs/blkdev/partition_parser.cpp => module-vfs/src/purefs/blkdev/partition_parser.cpp +7 -7
@@ 94,13 94,13 @@ namespace purefs::blkdev::internal
auto partition_parser::check_partition(const std::shared_ptr<disk> disk, const partition &part) -> bool
{
- auto sector_size = disk->get_info(info_type::sector_size);
- unsigned long this_size = disk->get_info(info_type::sector_count) * sector_size;
- const auto poffset = part.start_sector * sector_size;
- const auto psize = part.num_sectors * sector_size;
- const auto pnext = part.start_sector * sector_size + poffset;
- if ((poffset + psize > this_size) || // oversized
- (pnext < static_cast<unsigned long>(part.start_sector * sector_size)) // going backward
+ auto sector_size = disk->get_info(info_type::sector_size);
+ const auto this_size = uint64_t(disk->get_info(info_type::sector_count)) * uint64_t(sector_size);
+ const auto poffset = uint64_t(part.start_sector) * uint64_t(sector_size);
+ const auto psize = uint64_t(part.num_sectors) * uint64_t(sector_size);
+ const auto pnext = uint64_t(part.start_sector) * uint64_t(sector_size) + poffset;
+ if ((poffset + psize > this_size) || // oversized
+ (pnext < uint64_t(part.start_sector) * sector_size) // going backward
) {
LOG_WARN("Part %d looks strange: start_sector %u offset %u next %u\n",
unsigned(part.mbr_number),
M module-vfs/src/purefs/fs/filesystem.cpp => module-vfs/src/purefs/fs/filesystem.cpp +2 -2
@@ 55,7 55,7 @@ namespace purefs::fs
cpp_freertos::LockGuard _lck(*m_lock);
const auto it = m_fstypes.find(std::string(fsname));
if (it == std::end(m_fstypes)) {
- LOG_ERROR("VFS: filesystem %.*s doesn't exists in manager.", int(fsname.length()), fsname.data());
+ LOG_ERROR("VFS: filesystem %s doesn't exists in manager.", std::string(fsname).c_str());
return -ENOENT;
}
if (it->second->mount_count() > 0) {
@@ 74,7 74,7 @@ namespace purefs::fs
{
// Sanity check input data
if (target.size() <= 1 || target[0] != '/') {
- LOG_ERROR("VFS: Invalid target mountpoint path %.*s", int(target.length()), target.data());
+ LOG_ERROR("VFS: Invalid target mountpoint path %s", std::string(target).c_str());
return -EINVAL;
}
if (flags & ~(mount_flags::remount | mount_flags::read_only)) {
M module-vfs/src/purefs/vfs_subsystem.cpp => module-vfs/src/purefs/vfs_subsystem.cpp +29 -9
@@ 25,6 25,7 @@ namespace purefs::subsystem
constexpr auto new_layout_part_count = 3;
constexpr auto boot_size_limit = 16384L;
constexpr auto block_size_max_shift = 21;
+ constexpr auto block_size_min_shift = 8;
namespace json
{
constexpr auto os_type = "ostype";
@@ 90,6 91,27 @@ namespace purefs::subsystem
}
return json[json::main][json::os_type].string_value();
}
+
+ int read_mbr_lfs_erase_size(std::shared_ptr<blkdev::disk_manager> disk_mngr,
+ std::string_view dev_name,
+ int part_no)
+ {
+ static constexpr auto MBR_ERASE_BLK_OFFSET = 0x00E0;
+ if (part_no <= 0) {
+ return -EINVAL;
+ }
+ const auto sect_size = disk_mngr->get_info(dev_name, blkdev::info_type::sector_size);
+ if (sect_size <= MBR_ERASE_BLK_OFFSET + part_no) {
+ return (sect_size > 0) ? (-ERANGE) : (sect_size);
+ }
+ auto mbr_buf = std::make_unique<char[]>(sect_size);
+ int err = disk_mngr->read(dev_name, mbr_buf.get(), 0, 1);
+ if (err < 0) {
+ return err;
+ }
+ return mbr_buf[MBR_ERASE_BLK_OFFSET + part_no];
+ }
+
} // namespace
auto initialize() -> std::tuple<std::shared_ptr<blkdev::disk_manager>, std::shared_ptr<fs::filesystem>>
@@ 172,16 194,14 @@ namespace purefs::subsystem
return err;
}
if (lfs_it != std::end(parts)) {
- if (lfs_it->boot_unit > block_size_max_shift) {
- LOG_FATAL("Boot sector size is out of range");
- return -ERANGE;
- }
- else {
- const uint32_t lfs_block_size = 1U << lfs_it->boot_unit;
- const auto lfs_block_size_ptr = (lfs_it->boot_unit) ? (&lfs_block_size) : nullptr;
- err = vfs->mount(
- lfs_it->name, purefs::dir::getUserDiskPath().string(), "littlefs", 0, lfs_block_size_ptr);
+ int lfs_block_log2 = read_mbr_lfs_erase_size(disk, default_blkdev_name, lfs_it->physical_number);
+ uint32_t lfs_block_size = 0;
+ uint32_t *lfs_block_size_ptr = nullptr;
+ if (lfs_block_log2 >= block_size_min_shift && lfs_block_log2 <= block_size_max_shift) {
+ lfs_block_size = 1U << lfs_block_log2;
+ lfs_block_size_ptr = &lfs_block_size;
}
+ err = vfs->mount(lfs_it->name, purefs::dir::getUserDiskPath().string(), "littlefs", 0, lfs_block_size_ptr);
}
const std::string json_file = (dir::getRootDiskPath() / file::boot_json).string();
const auto boot_dir_name = parse_boot_json_directory(json_file);