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

Commit e14efeac authored by JP Abgrall's avatar JP Abgrall Committed by Android (Google) Code Review
Browse files

Merge topic 'f2fs'

* changes:
  fsmgr: allow for a multiple fs-types for a mount point.
  F2FS support for fastboot format and fsmgr
parents 429502d4 a794f865
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -17,7 +17,8 @@ LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../mkbootimg \
  $(LOCAL_PATH)/../../extras/ext4_utils
  $(LOCAL_PATH)/../../extras/ext4_utils \
  $(LOCAL_PATH)/../../extras/f2fs_utils
LOCAL_SRC_FILES := protocol.c engine.c bootimg.c fastboot.c util.c fs.c
LOCAL_MODULE := fastboot
LOCAL_MODULE_TAGS := debug
@@ -50,14 +51,20 @@ ifeq ($(HOST_OS),windows)
  LOCAL_C_INCLUDES += development/host/windows/usb/api
endif

# The following libf2fs_* are from system/extras/f2fs_utils,
# and do not use code in external/f2fs-tools.
LOCAL_STATIC_LIBRARIES := \
    $(EXTRA_STATIC_LIBS) \
    libzipfile \
    libunz \
    libext4_utils_host \
    libf2fs_utils_host \
    libf2fs_dlutils_host \
    libsparse_host \
    libz

# libf2fs_dlutils_host will dlopen("libf2fs_fmt_host_dyn")
LOCAL_LDLIBS := -ldl
LOCAL_SHARED_LIBRARIES := libf2fs_fmt_host_dyn
ifneq ($(HOST_OS),windows)
LOCAL_STATIC_LIBRARIES += libselinux
endif # HOST_OS != windows
+9 −3
Original line number Diff line number Diff line
#include "fastboot.h"
#include "make_ext4fs.h"
#include "make_f2fs.h"
#include "fs.h"

#include <errno.h>
@@ -28,15 +29,20 @@ static int generate_ext4_image(int fd, long long partSize)
    return 0;
}

int generate_f2fs_image(int fd, long long partSize)
{
    make_f2fs_sparse_fd(fd, partSize, NULL, NULL);
    return 0;
}

static const struct fs_generator {

    char *fs_type;  //must match what fastboot reports for partition type
    int (*generate)(int fd, long long partSize); //returns 0 or error value

} generators[] = {

    { "ext4", generate_ext4_image}

    { "ext4", generate_ext4_image},
    { "f2fs", generate_f2fs_image},
};

const struct fs_generator* fs_get_generator(const char *fs_type)
+62 −22
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@
#define KEY_IN_FOOTER  "footer"

#define E2FSCK_BIN      "/system/bin/e2fsck"
#define F2FS_FSCK_BIN  "/system/bin/fsck.f2fs"
#define MKSWAP_BIN      "/system/bin/mkswap"

#define FSCK_LOG_FILE   "/dev/fscklogs/log"
@@ -135,6 +136,20 @@ static void check_fs(char *blk_device, char *fs_type, char *target)
                ERROR("Failed trying to run %s\n", E2FSCK_BIN);
            }
        }
    } else if (!strcmp(fs_type, "f2fs")) {
            char *f2fs_fsck_argv[] = {
                    F2FS_FSCK_BIN,
                    blk_device
            };
        INFO("Running %s on %s\n", F2FS_FSCK_BIN, blk_device);

        ret = android_fork_execvp_ext(ARRAY_SIZE(f2fs_fsck_argv), f2fs_fsck_argv,
                                      &status, true, LOG_KLOG | LOG_FILE,
                                      true, FSCK_LOG_FILE);
        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", F2FS_FSCK_BIN);
        }
    }

    return;
@@ -175,12 +190,12 @@ static void fs_set_blk_ro(const char *blockdev)
 * sets the underlying block device to read-only if the mount is read-only.
 * See "man 2 mount" for return values.
 */
static int __mount(const char *source, const char *target,
                   const char *filesystemtype, unsigned long mountflags,
                   const void *data)
static int __mount(const char *source, const char *target, const struct fstab_rec *rec)
{
    int ret = mount(source, target, filesystemtype, mountflags, data);
    unsigned long mountflags = rec->flags;
    int ret;

    ret = mount(source, target, rec->fs_type, mountflags, rec->fs_options);
    if ((ret == 0) && (mountflags & MS_RDONLY) != 0) {
        fs_set_blk_ro(source);
    }
@@ -217,13 +232,18 @@ static int device_is_debuggable() {
    return strcmp(value, "1") ? 0 : 1;
}

/* When multiple fstab records share the same mount_point, it will
 * try to mount each one in turn, and ignore any duplicates after a
 * first successful mount.
 */
int fs_mgr_mount_all(struct fstab *fstab)
{
    int i = 0;
    int i = 0, j = 0;
    int encryptable = 0;
    int error_count = 0;
    int mret;
    int mount_errno;
    const char *last_ok_mount_point = NULL;

    if (!fstab) {
        return -1;
@@ -259,10 +279,26 @@ int fs_mgr_mount_all(struct fstab *fstab)
            }
        }

        mret = __mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point,
                       fstab->recs[i].fs_type, fstab->recs[i].flags,
                       fstab->recs[i].fs_options);

        /*
         * Don't try to mount/encrypt the same mount point again.
         * Deal with alternate entries for the same point which are required to be all following
         * each other.
         */
        if (last_ok_mount_point && !strcmp(last_ok_mount_point, fstab->recs[i].mount_point)) {
            continue;
        }
        /* Hunt down an fstab entry for the same mount point that might succeed */
        for (j = i, mret = -1;
             /* We required that fstab entries for the same mountpoint be consecutive */
             mret && j < fstab->num_entries && !strcmp(fstab->recs[i].mount_point, fstab->recs[j].mount_point);
             j++) {
                mret = __mount(fstab->recs[j].blk_device, fstab->recs[j].mount_point, &fstab->recs[j]);
        }
        /* Did one of the same mount points mount? If so pick it. */
        if (!mret) {
            i = j;
            last_ok_mount_point = fstab->recs[i].mount_point;
        }
        if (!mret) {
            /* If this is encryptable, need to trigger encryption */
            if ((fstab->recs[i].fs_mgr_flags & MF_FORCECRYPT)) {
@@ -279,7 +315,6 @@ int fs_mgr_mount_all(struct fstab *fstab)
                    continue;
                }
            }

            /* Success!  Go get the next one */
            continue;
        }
@@ -293,10 +328,7 @@ int fs_mgr_mount_all(struct fstab *fstab)
            /* Need to mount a tmpfs at this mountpoint for now, and set
             * properties that vold will query later for decrypting
             */
            if (mount("tmpfs", fstab->recs[i].mount_point, "tmpfs",
                      MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS) < 0) {
                ERROR("Cannot mount tmpfs filesystem for encryptable fs at %s error: %s\n",
                       fstab->recs[i].mount_point, strerror(errno));
            if (fs_mgr_do_tmpfs_mount(fstab->recs[i].mount_point) < 0) {
                ++error_count;
                continue;
            }
@@ -320,12 +352,16 @@ int fs_mgr_mount_all(struct fstab *fstab)

/* If tmp_mount_point is non-null, mount the filesystem there.  This is for the
 * tmp mount we do to check the user password
 * If multiple fstab entries are to be mounted on "n_name", it will try to mount each one
 * in turn, and stop on 1st success, or no more match.
 */
int fs_mgr_do_mount(struct fstab *fstab, char *n_name, char *n_blk_device,
                    char *tmp_mount_point)
{
    int i = 0;
    int ret = -1;
    int mount_errors = 0;
    int first_mount_errno = 0;
    char *m;

    if (!fstab) {
@@ -371,19 +407,23 @@ int fs_mgr_do_mount(struct fstab *fstab, char *n_name, char *n_blk_device,
        } else {
            m = fstab->recs[i].mount_point;
        }
        if (__mount(n_blk_device, m, fstab->recs[i].fs_type,
                    fstab->recs[i].flags, fstab->recs[i].fs_options)) {
            ERROR("Cannot mount filesystem on %s at %s options: %s error: %s\n",
                n_blk_device, m, fstab->recs[i].fs_options, strerror(errno));
            goto out;
        if (__mount(n_blk_device, m, &fstab->recs[i])) {
            if (!first_mount_errno) first_mount_errno = errno;
            mount_errors++;
            continue;
        } else {
            ret = 0;
            goto out;
        }
    }

    if (mount_errors) {
        ERROR("Cannot mount filesystem on %s at %s. error: %s\n",
            n_blk_device, m, strerror(first_mount_errno));
        ret = -1;
    } else {
        /* We didn't find a match, say so and return an error */
        ERROR("Cannot find mount point %s in fstab\n", fstab->recs[i].mount_point);
    }

out:
    return ret;
+26 −4
Original line number Diff line number Diff line
@@ -367,25 +367,47 @@ int fs_mgr_add_entry(struct fstab *fstab,
     return 0;
}

struct fstab_rec *fs_mgr_get_entry_for_mount_point(struct fstab *fstab, const char *path)
/*
 * Returns the 1st matching fstab_rec that follows the start_rec.
 * start_rec is the result of a previous search or NULL.
 */
struct fstab_rec *fs_mgr_get_entry_for_mount_point_after(struct fstab_rec *start_rec, struct fstab *fstab, const char *path)
{
    int i;

    if (!fstab) {
        return NULL;
    }

    if (start_rec) {
        for (i = 0; i < fstab->num_entries; i++) {
            if (&fstab->recs[i] == start_rec) {
                i++;
                break;
            }
        }
    } else {
        i = 0;
    }
    for (; i < fstab->num_entries; i++) {
        int len = strlen(fstab->recs[i].mount_point);
        if (strncmp(path, fstab->recs[i].mount_point, len) == 0 &&
            (path[len] == '\0' || path[len] == '/')) {
            return &fstab->recs[i];
        }
    }

    return NULL;
}

/*
 * Returns the 1st matching mount point.
 * There might be more. To look for others, use fs_mgr_get_entry_for_mount_point_after()
 * and give the fstab_rec from the previous search.
 */
struct fstab_rec *fs_mgr_get_entry_for_mount_point(struct fstab *fstab, const char *path)
{
    return fs_mgr_get_entry_for_mount_point_after(NULL, fstab, path);
}

int fs_mgr_is_voldmanaged(struct fstab_rec *fstab)
{
    return fstab->fs_mgr_flags & MF_VOLDMANAGED;
+5 −0
Original line number Diff line number Diff line
@@ -24,6 +24,11 @@
extern "C" {
#endif

/*
 * The entries must be kept in the same order as they were seen in the fstab.
 * Unless explicitly requested, a lookup on mount point should always
 * return the 1st one.
 */
struct fstab {
    int num_entries;
    struct fstab_rec *recs;