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

Commit 7c59f1ae authored by Daniel Rosenberg's avatar Daniel Rosenberg
Browse files

Set GC threshold when mounting with checkpointing

This steps up our garbage collection threshold over time when mounting
userdata with checkpointing=disable for f2fs. With this scheme, we step
up the percent of disk we will tolerate being unusable during
checkpointing. At 100%, the filesystem will be able to always mount.
This means we will attempt to mount at most 10 times, for a max time of
about 50 seconds.

Also logs mount time under ro.boottime.init.mount.[target]

If the device does not support checkpoint=disable:[n%], it will mount
with checkpoint=disable, which is equivalent to checkpoint=disable:0%

Test: Boot in checkpointing mode
Bug: 150506496
Change-Id: I047ff98513f4ea832e1216b91e454a57fd2e8bf6
parent fcdaee48
Loading
Loading
Loading
Loading
+24 −4
Original line number Diff line number Diff line
@@ -737,15 +737,33 @@ static int __mount(const std::string& source, const std::string& target, const F
    unsigned long mountflags = entry.flags;
    int ret = 0;
    int save_errno = 0;
    int gc_allowance = 0;
    std::string opts;
    bool try_f2fs_gc_allowance = is_f2fs(entry.fs_type) && entry.fs_checkpoint_opts.length() > 0;
    Timer t;

    do {
        if (save_errno == EINVAL && try_f2fs_gc_allowance) {
            PINFO << "Kernel does not support checkpoint=disable:[n]%, trying without.";
            try_f2fs_gc_allowance = false;
        }
        if (try_f2fs_gc_allowance) {
            opts = entry.fs_options + entry.fs_checkpoint_opts + ":" +
                   std::to_string(gc_allowance) + "%";
        } else {
            opts = entry.fs_options;
        }
        if (save_errno == EAGAIN) {
            PINFO << "Retrying mount (source=" << source << ",target=" << target
                  << ",type=" << entry.fs_type << ")=" << ret << "(" << save_errno << ")";
                  << ",type=" << entry.fs_type << ", gc_allowance=" << gc_allowance << "%)=" << ret
                  << "(" << save_errno << ")";
        }
        ret = mount(source.c_str(), target.c_str(), entry.fs_type.c_str(), mountflags,
                    entry.fs_options.c_str());
                    opts.c_str());
        save_errno = errno;
    } while (ret && save_errno == EAGAIN);
        if (try_f2fs_gc_allowance) gc_allowance += 10;
    } while ((ret && save_errno == EAGAIN && gc_allowance <= 100) ||
             (ret && save_errno == EINVAL && try_f2fs_gc_allowance));
    const char* target_missing = "";
    const char* source_missing = "";
    if (save_errno == ENOENT) {
@@ -761,6 +779,8 @@ static int __mount(const std::string& source, const std::string& target, const F
    if ((ret == 0) && (mountflags & MS_RDONLY) != 0) {
        fs_mgr_set_blk_ro(source);
    }
    android::base::SetProperty("ro.boottime.init.mount." + Basename(target),
                               std::to_string(t.duration().count()));
    errno = save_errno;
    return ret;
}
@@ -1075,7 +1095,7 @@ class CheckpointManager {
    bool UpdateCheckpointPartition(FstabEntry* entry, const std::string& block_device) {
        if (entry->fs_mgr_flags.checkpoint_fs) {
            if (is_f2fs(entry->fs_type)) {
                entry->fs_options += ",checkpoint=disable";
                entry->fs_checkpoint_opts = ",checkpoint=disable";
            } else {
                LERROR << entry->fs_type << " does not implement checkpoints.";
            }
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ struct FstabEntry {
    std::string fs_type;
    unsigned long flags = 0;
    std::string fs_options;
    std::string fs_checkpoint_opts;
    std::string key_loc;
    std::string metadata_key_dir;
    std::string metadata_encryption;