Loading fs_mgr/fs_mgr.c +107 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ioctl.h> #include <sys/mount.h> #include <sys/stat.h> #include <sys/swap.h> Loading @@ -38,6 +39,7 @@ #include <ext4_utils/ext4_sb.h> #include <ext4_utils/ext4_utils.h> #include <ext4_utils/wipe.h> #include <linux/fs.h> #include <linux/loop.h> #include <logwrap/logwrap.h> #include <private/android_filesystem_config.h> Loading @@ -52,6 +54,7 @@ #define E2FSCK_BIN "/system/bin/e2fsck" #define F2FS_FSCK_BIN "/system/bin/fsck.f2fs" #define MKSWAP_BIN "/system/bin/mkswap" #define TUNE2FS_BIN "/system/bin/tune2fs" #define FSCK_LOG_FILE "/dev/fscklogs/log" Loading Loading @@ -180,6 +183,99 @@ static void check_fs(char *blk_device, char *fs_type, char *target) return; } /* Function to read the primary superblock */ static int read_super_block(int fd, struct ext4_super_block *sb) { off64_t ret; ret = lseek64(fd, 1024, SEEK_SET); if (ret < 0) return ret; ret = read(fd, sb, sizeof(*sb)); if (ret < 0) return ret; if (ret != sizeof(*sb)) return ret; return 0; } static ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es) { return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) | le32_to_cpu(es->s_blocks_count_lo); } static ext4_fsblk_t ext4_r_blocks_count(struct ext4_super_block *es) { return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) | le32_to_cpu(es->s_r_blocks_count_lo); } static void do_reserved_size(char *blk_device, char *fs_type, struct fstab_rec *rec) { /* Check for the types of filesystems we know how to check */ if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) { /* * Some system images do not have tune2fs for licensing reasons * Detect these and skip reserve blocks. */ if (access(TUNE2FS_BIN, X_OK)) { ERROR("Not running %s on %s (executable not in system image)\n", TUNE2FS_BIN, blk_device); } else { INFO("Running %s on %s\n", TUNE2FS_BIN, blk_device); int status = 0; int ret = 0; unsigned long reserved_blocks = 0; int fd = TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC)); if (fd >= 0) { struct ext4_super_block sb; ret = read_super_block(fd, &sb); if (ret < 0) { ERROR("Can't read '%s' super block: %s\n", blk_device, strerror(errno)); goto out; } reserved_blocks = rec->reserved_size / EXT4_BLOCK_SIZE(&sb); unsigned long reserved_threshold = ext4_blocks_count(&sb) * 0.02; if (reserved_threshold < reserved_blocks) { WARNING("Reserved blocks %lu is too large\n", reserved_blocks); reserved_blocks = reserved_threshold; } if (ext4_r_blocks_count(&sb) == reserved_blocks) { INFO("Have reserved same blocks\n"); goto out; } } else { ERROR("Failed to open '%s': %s\n", blk_device, strerror(errno)); return; } char buf[16] = {0}; snprintf(buf, sizeof (buf), "-r %lu", reserved_blocks); char *tune2fs_argv[] = { TUNE2FS_BIN, buf, blk_device, }; ret = android_fork_execvp_ext(ARRAY_SIZE(tune2fs_argv), tune2fs_argv, &status, true, LOG_KLOG | LOG_FILE, true, NULL, NULL, 0); if (ret < 0) { /* No need to check for error in fork, we can't really handle it now */ ERROR("Failed trying to run %s\n", TUNE2FS_BIN); } out: close(fd); } } } static void remove_trailing_slashes(char *n) { int len; Loading Loading @@ -325,6 +421,12 @@ static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_ check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type, fstab->recs[i].mount_point); } if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) { do_reserved_size(fstab->recs[i].blk_device, fstab->recs[i].fs_type, &fstab->recs[i]); } if (!__mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point, &fstab->recs[i])) { *attempted_idx = i; mounted = 1; Loading Loading @@ -690,6 +792,10 @@ int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device, fstab->recs[i].mount_point); } if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) { do_reserved_size(n_blk_device, fstab->recs[i].fs_type, &fstab->recs[i]); } if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) { int rc = fs_mgr_setup_verity(&fstab->recs[i]); if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) { Loading fs_mgr/fs_mgr_fstab.c +22 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ struct fs_mgr_flag_values { int swap_prio; int max_comp_streams; unsigned int zram_size; uint64_t reserved_size; }; struct flag_list { Loading Loading @@ -80,6 +81,7 @@ static struct flag_list fs_mgr_flags[] = { { "slotselect", MF_SLOTSELECT }, { "nofail", MF_NOFAIL }, { "latemount", MF_LATEMOUNT }, { "reservedsize=", MF_RESERVEDSIZE }, { "defaults", 0 }, { 0, 0 }, }; Loading @@ -97,6 +99,20 @@ static uint64_t calculate_zram_size(unsigned int percentage) return total; } static uint64_t parse_size(const char *arg) { char *endptr; uint64_t size = strtoull(arg, &endptr, 10); if (*endptr == 'k' || *endptr == 'K') size *= 1024LL; else if (*endptr == 'm' || *endptr == 'M') size *= 1024LL * 1024LL; else if (*endptr == 'g' || *endptr == 'G') size *= 1024LL * 1024LL * 1024LL; return size; } static int parse_flags(char *flags, struct flag_list *fl, struct fs_mgr_flag_values *flag_vals, char *fs_options, int fs_options_len) Loading Loading @@ -191,6 +207,11 @@ static int parse_flags(char *flags, struct flag_list *fl, flag_vals->zram_size = calculate_zram_size(val); else flag_vals->zram_size = val; } else if ((fl[i].flag == MF_RESERVEDSIZE) && flag_vals) { /* The reserved flag is followed by an = and the * reserved size of the partition. Get it and return it. */ flag_vals->reserved_size = parse_size(strchr(p, '=') + 1); } break; } Loading Loading @@ -335,6 +356,7 @@ struct fstab *fs_mgr_read_fstab_file(FILE *fstab_file) fstab->recs[cnt].swap_prio = flag_vals.swap_prio; fstab->recs[cnt].max_comp_streams = flag_vals.max_comp_streams; fstab->recs[cnt].zram_size = flag_vals.zram_size; fstab->recs[cnt].reserved_size = flag_vals.reserved_size; cnt++; } /* If an A/B partition, modify block device to be the real block device */ Loading fs_mgr/fs_mgr_priv.h +1 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ __BEGIN_DECLS #define MF_LATEMOUNT 0x20000 #define MF_NOFAIL 0x40000 #define MF_MAX_COMP_STREAMS 0x100000 #define MF_RESERVEDSIZE 0x200000 #define DM_BUF_SIZE 4096 Loading fs_mgr/include/fs_mgr.h +1 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ struct fstab_rec { int swap_prio; int max_comp_streams; unsigned int zram_size; uint64_t reserved_size; }; // Callback function for verity status Loading Loading
fs_mgr/fs_mgr.c +107 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ioctl.h> #include <sys/mount.h> #include <sys/stat.h> #include <sys/swap.h> Loading @@ -38,6 +39,7 @@ #include <ext4_utils/ext4_sb.h> #include <ext4_utils/ext4_utils.h> #include <ext4_utils/wipe.h> #include <linux/fs.h> #include <linux/loop.h> #include <logwrap/logwrap.h> #include <private/android_filesystem_config.h> Loading @@ -52,6 +54,7 @@ #define E2FSCK_BIN "/system/bin/e2fsck" #define F2FS_FSCK_BIN "/system/bin/fsck.f2fs" #define MKSWAP_BIN "/system/bin/mkswap" #define TUNE2FS_BIN "/system/bin/tune2fs" #define FSCK_LOG_FILE "/dev/fscklogs/log" Loading Loading @@ -180,6 +183,99 @@ static void check_fs(char *blk_device, char *fs_type, char *target) return; } /* Function to read the primary superblock */ static int read_super_block(int fd, struct ext4_super_block *sb) { off64_t ret; ret = lseek64(fd, 1024, SEEK_SET); if (ret < 0) return ret; ret = read(fd, sb, sizeof(*sb)); if (ret < 0) return ret; if (ret != sizeof(*sb)) return ret; return 0; } static ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es) { return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) | le32_to_cpu(es->s_blocks_count_lo); } static ext4_fsblk_t ext4_r_blocks_count(struct ext4_super_block *es) { return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) | le32_to_cpu(es->s_r_blocks_count_lo); } static void do_reserved_size(char *blk_device, char *fs_type, struct fstab_rec *rec) { /* Check for the types of filesystems we know how to check */ if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) { /* * Some system images do not have tune2fs for licensing reasons * Detect these and skip reserve blocks. */ if (access(TUNE2FS_BIN, X_OK)) { ERROR("Not running %s on %s (executable not in system image)\n", TUNE2FS_BIN, blk_device); } else { INFO("Running %s on %s\n", TUNE2FS_BIN, blk_device); int status = 0; int ret = 0; unsigned long reserved_blocks = 0; int fd = TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC)); if (fd >= 0) { struct ext4_super_block sb; ret = read_super_block(fd, &sb); if (ret < 0) { ERROR("Can't read '%s' super block: %s\n", blk_device, strerror(errno)); goto out; } reserved_blocks = rec->reserved_size / EXT4_BLOCK_SIZE(&sb); unsigned long reserved_threshold = ext4_blocks_count(&sb) * 0.02; if (reserved_threshold < reserved_blocks) { WARNING("Reserved blocks %lu is too large\n", reserved_blocks); reserved_blocks = reserved_threshold; } if (ext4_r_blocks_count(&sb) == reserved_blocks) { INFO("Have reserved same blocks\n"); goto out; } } else { ERROR("Failed to open '%s': %s\n", blk_device, strerror(errno)); return; } char buf[16] = {0}; snprintf(buf, sizeof (buf), "-r %lu", reserved_blocks); char *tune2fs_argv[] = { TUNE2FS_BIN, buf, blk_device, }; ret = android_fork_execvp_ext(ARRAY_SIZE(tune2fs_argv), tune2fs_argv, &status, true, LOG_KLOG | LOG_FILE, true, NULL, NULL, 0); if (ret < 0) { /* No need to check for error in fork, we can't really handle it now */ ERROR("Failed trying to run %s\n", TUNE2FS_BIN); } out: close(fd); } } } static void remove_trailing_slashes(char *n) { int len; Loading Loading @@ -325,6 +421,12 @@ static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_ check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type, fstab->recs[i].mount_point); } if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) { do_reserved_size(fstab->recs[i].blk_device, fstab->recs[i].fs_type, &fstab->recs[i]); } if (!__mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point, &fstab->recs[i])) { *attempted_idx = i; mounted = 1; Loading Loading @@ -690,6 +792,10 @@ int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device, fstab->recs[i].mount_point); } if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) { do_reserved_size(n_blk_device, fstab->recs[i].fs_type, &fstab->recs[i]); } if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) { int rc = fs_mgr_setup_verity(&fstab->recs[i]); if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) { Loading
fs_mgr/fs_mgr_fstab.c +22 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ struct fs_mgr_flag_values { int swap_prio; int max_comp_streams; unsigned int zram_size; uint64_t reserved_size; }; struct flag_list { Loading Loading @@ -80,6 +81,7 @@ static struct flag_list fs_mgr_flags[] = { { "slotselect", MF_SLOTSELECT }, { "nofail", MF_NOFAIL }, { "latemount", MF_LATEMOUNT }, { "reservedsize=", MF_RESERVEDSIZE }, { "defaults", 0 }, { 0, 0 }, }; Loading @@ -97,6 +99,20 @@ static uint64_t calculate_zram_size(unsigned int percentage) return total; } static uint64_t parse_size(const char *arg) { char *endptr; uint64_t size = strtoull(arg, &endptr, 10); if (*endptr == 'k' || *endptr == 'K') size *= 1024LL; else if (*endptr == 'm' || *endptr == 'M') size *= 1024LL * 1024LL; else if (*endptr == 'g' || *endptr == 'G') size *= 1024LL * 1024LL * 1024LL; return size; } static int parse_flags(char *flags, struct flag_list *fl, struct fs_mgr_flag_values *flag_vals, char *fs_options, int fs_options_len) Loading Loading @@ -191,6 +207,11 @@ static int parse_flags(char *flags, struct flag_list *fl, flag_vals->zram_size = calculate_zram_size(val); else flag_vals->zram_size = val; } else if ((fl[i].flag == MF_RESERVEDSIZE) && flag_vals) { /* The reserved flag is followed by an = and the * reserved size of the partition. Get it and return it. */ flag_vals->reserved_size = parse_size(strchr(p, '=') + 1); } break; } Loading Loading @@ -335,6 +356,7 @@ struct fstab *fs_mgr_read_fstab_file(FILE *fstab_file) fstab->recs[cnt].swap_prio = flag_vals.swap_prio; fstab->recs[cnt].max_comp_streams = flag_vals.max_comp_streams; fstab->recs[cnt].zram_size = flag_vals.zram_size; fstab->recs[cnt].reserved_size = flag_vals.reserved_size; cnt++; } /* If an A/B partition, modify block device to be the real block device */ Loading
fs_mgr/fs_mgr_priv.h +1 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ __BEGIN_DECLS #define MF_LATEMOUNT 0x20000 #define MF_NOFAIL 0x40000 #define MF_MAX_COMP_STREAMS 0x100000 #define MF_RESERVEDSIZE 0x200000 #define DM_BUF_SIZE 4096 Loading
fs_mgr/include/fs_mgr.h +1 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ struct fstab_rec { int swap_prio; int max_comp_streams; unsigned int zram_size; uint64_t reserved_size; }; // Callback function for verity status Loading