15e5c12b0Sopenharmony_ci/**
25e5c12b0Sopenharmony_ci * sload.c
35e5c12b0Sopenharmony_ci *
45e5c12b0Sopenharmony_ci * Copyright (C) 2015 Huawei Ltd.
55e5c12b0Sopenharmony_ci * Witten by:
65e5c12b0Sopenharmony_ci *   Hou Pengyang <houpengyang@huawei.com>
75e5c12b0Sopenharmony_ci *   Liu Shuoran <liushuoran@huawei.com>
85e5c12b0Sopenharmony_ci *   Jaegeuk Kim <jaegeuk@kernel.org>
95e5c12b0Sopenharmony_ci *
105e5c12b0Sopenharmony_ci * This program is free software; you can redistribute it and/or modify
115e5c12b0Sopenharmony_ci * it under the terms of the GNU General Public License version 2 as
125e5c12b0Sopenharmony_ci * published by the Free Software Foundation.
135e5c12b0Sopenharmony_ci */
145e5c12b0Sopenharmony_ci#ifndef _GNU_SOURCE
155e5c12b0Sopenharmony_ci#define _GNU_SOURCE
165e5c12b0Sopenharmony_ci#endif
175e5c12b0Sopenharmony_ci#include "fsck.h"
185e5c12b0Sopenharmony_ci#include <libgen.h>
195e5c12b0Sopenharmony_ci#include <dirent.h>
205e5c12b0Sopenharmony_ci#ifdef HAVE_MNTENT_H
215e5c12b0Sopenharmony_ci#include <mntent.h>
225e5c12b0Sopenharmony_ci#endif
235e5c12b0Sopenharmony_ci
245e5c12b0Sopenharmony_ci#ifdef HAVE_LIBSELINUX
255e5c12b0Sopenharmony_cistatic struct selabel_handle *sehnd = NULL;
265e5c12b0Sopenharmony_ci#endif
275e5c12b0Sopenharmony_ci
285e5c12b0Sopenharmony_citypedef void (*fs_config_f)(const char *path, int dir,
295e5c12b0Sopenharmony_ci			    const char *target_out_path,
305e5c12b0Sopenharmony_ci			    unsigned *uid, unsigned *gid,
315e5c12b0Sopenharmony_ci			    unsigned *mode, uint64_t *capabilities);
325e5c12b0Sopenharmony_ci
335e5c12b0Sopenharmony_ci#ifndef _WIN32
345e5c12b0Sopenharmony_cistatic fs_config_f fs_config_func = NULL;
355e5c12b0Sopenharmony_ci
365e5c12b0Sopenharmony_ci#ifdef HAVE_SELINUX_ANDROID_H
375e5c12b0Sopenharmony_ci#include <selinux/android.h>
385e5c12b0Sopenharmony_ci#include <private/android_filesystem_config.h>
395e5c12b0Sopenharmony_ci#include <private/canned_fs_config.h>
405e5c12b0Sopenharmony_ci#include <private/fs_config.h>
415e5c12b0Sopenharmony_ci#endif
425e5c12b0Sopenharmony_ci
435e5c12b0Sopenharmony_cistatic int filter_dot(const struct dirent *d)
445e5c12b0Sopenharmony_ci{
455e5c12b0Sopenharmony_ci	return (strcmp(d->d_name, "..") && strcmp(d->d_name, "."));
465e5c12b0Sopenharmony_ci}
475e5c12b0Sopenharmony_ci
485e5c12b0Sopenharmony_cistatic int f2fs_make_directory(struct f2fs_sb_info *sbi,
495e5c12b0Sopenharmony_ci				int entries, struct dentry *de)
505e5c12b0Sopenharmony_ci{
515e5c12b0Sopenharmony_ci	int ret = 0;
525e5c12b0Sopenharmony_ci	int i = 0;
535e5c12b0Sopenharmony_ci
545e5c12b0Sopenharmony_ci	for (i = 0; i < entries; i++) {
555e5c12b0Sopenharmony_ci		if (de[i].file_type == F2FS_FT_DIR)
565e5c12b0Sopenharmony_ci			ret = f2fs_mkdir(sbi, de + i);
575e5c12b0Sopenharmony_ci		else if (de[i].file_type == F2FS_FT_REG_FILE)
585e5c12b0Sopenharmony_ci			ret = f2fs_create(sbi, de + i);
595e5c12b0Sopenharmony_ci		else if (de[i].file_type == F2FS_FT_SYMLINK)
605e5c12b0Sopenharmony_ci			ret = f2fs_symlink(sbi, de + i);
615e5c12b0Sopenharmony_ci
625e5c12b0Sopenharmony_ci		if (ret)
635e5c12b0Sopenharmony_ci			break;
645e5c12b0Sopenharmony_ci	}
655e5c12b0Sopenharmony_ci
665e5c12b0Sopenharmony_ci	return ret;
675e5c12b0Sopenharmony_ci}
685e5c12b0Sopenharmony_ci#endif
695e5c12b0Sopenharmony_ci
705e5c12b0Sopenharmony_ci#ifdef HAVE_LIBSELINUX
715e5c12b0Sopenharmony_cistatic int set_selinux_xattr(struct f2fs_sb_info *sbi, const char *path,
725e5c12b0Sopenharmony_ci							nid_t ino, int mode)
735e5c12b0Sopenharmony_ci{
745e5c12b0Sopenharmony_ci	char *secontext = NULL;
755e5c12b0Sopenharmony_ci	char *mnt_path = NULL;
765e5c12b0Sopenharmony_ci
775e5c12b0Sopenharmony_ci	if (!sehnd)
785e5c12b0Sopenharmony_ci		return 0;
795e5c12b0Sopenharmony_ci
805e5c12b0Sopenharmony_ci	if (asprintf(&mnt_path, "%s%s", c.mount_point, path) <= 0) {
815e5c12b0Sopenharmony_ci		ERR_MSG("cannot allocate security path for %s%s\n",
825e5c12b0Sopenharmony_ci						c.mount_point, path);
835e5c12b0Sopenharmony_ci		return -ENOMEM;
845e5c12b0Sopenharmony_ci	}
855e5c12b0Sopenharmony_ci
865e5c12b0Sopenharmony_ci	/* set root inode selinux context */
875e5c12b0Sopenharmony_ci	if (selabel_lookup(sehnd, &secontext, mnt_path, mode) < 0) {
885e5c12b0Sopenharmony_ci		ERR_MSG("cannot lookup security context for %s\n", mnt_path);
895e5c12b0Sopenharmony_ci		free(mnt_path);
905e5c12b0Sopenharmony_ci		return -EINVAL;
915e5c12b0Sopenharmony_ci	}
925e5c12b0Sopenharmony_ci
935e5c12b0Sopenharmony_ci	if (secontext) {
945e5c12b0Sopenharmony_ci		MSG(2, "%s (%d) -> SELinux context = %s\n",
955e5c12b0Sopenharmony_ci						mnt_path, ino, secontext);
965e5c12b0Sopenharmony_ci		inode_set_selinux(sbi, ino, secontext);
975e5c12b0Sopenharmony_ci	}
985e5c12b0Sopenharmony_ci	freecon(secontext);
995e5c12b0Sopenharmony_ci	free(mnt_path);
1005e5c12b0Sopenharmony_ci	return 0;
1015e5c12b0Sopenharmony_ci}
1025e5c12b0Sopenharmony_ci#else
1035e5c12b0Sopenharmony_ci#define set_selinux_xattr(...)	0
1045e5c12b0Sopenharmony_ci#endif
1055e5c12b0Sopenharmony_ci
1065e5c12b0Sopenharmony_ci#ifndef _WIN32
1075e5c12b0Sopenharmony_cistatic int set_perms_and_caps(struct dentry *de)
1085e5c12b0Sopenharmony_ci{
1095e5c12b0Sopenharmony_ci	uint64_t capabilities = 0;
1105e5c12b0Sopenharmony_ci	unsigned int uid = 0, gid = 0, imode = 0;
1115e5c12b0Sopenharmony_ci	char *mnt_path = NULL;
1125e5c12b0Sopenharmony_ci	char *mount_path = c.mount_point;
1135e5c12b0Sopenharmony_ci
1145e5c12b0Sopenharmony_ci	/*
1155e5c12b0Sopenharmony_ci	 * de->path already has "/" in the beginning of it.
1165e5c12b0Sopenharmony_ci	 * Need to remove "/" when c.mount_point is "/", not to add it twice.
1175e5c12b0Sopenharmony_ci	 */
1185e5c12b0Sopenharmony_ci	if (strlen(c.mount_point) == 1 && c.mount_point[0] == '/')
1195e5c12b0Sopenharmony_ci		mount_path = "";
1205e5c12b0Sopenharmony_ci
1215e5c12b0Sopenharmony_ci	if (asprintf(&mnt_path, "%s%s", mount_path, de->path) <= 0) {
1225e5c12b0Sopenharmony_ci		ERR_MSG("cannot allocate mount path for %s%s\n",
1235e5c12b0Sopenharmony_ci				mount_path, de->path);
1245e5c12b0Sopenharmony_ci		return -ENOMEM;
1255e5c12b0Sopenharmony_ci	}
1265e5c12b0Sopenharmony_ci
1275e5c12b0Sopenharmony_ci	/* Permissions */
1285e5c12b0Sopenharmony_ci	if (fs_config_func != NULL) {
1295e5c12b0Sopenharmony_ci		fs_config_func(mnt_path, de->file_type == F2FS_FT_DIR,
1305e5c12b0Sopenharmony_ci				c.target_out_dir, &uid, &gid, &imode,
1315e5c12b0Sopenharmony_ci				&capabilities);
1325e5c12b0Sopenharmony_ci		de->uid = uid & 0xffff;
1335e5c12b0Sopenharmony_ci		de->gid = gid & 0xffff;
1345e5c12b0Sopenharmony_ci		de->mode = (de->mode & S_IFMT) | (imode & 0xffff);
1355e5c12b0Sopenharmony_ci		de->capabilities = capabilities;
1365e5c12b0Sopenharmony_ci	}
1375e5c12b0Sopenharmony_ci	MSG(2, "%s -> mode = 0x%x, uid = 0x%x, gid = 0x%x, "
1385e5c12b0Sopenharmony_ci			"capabilities = 0x%"PRIx64"\n",
1395e5c12b0Sopenharmony_ci		mnt_path, de->mode, de->uid, de->gid, de->capabilities);
1405e5c12b0Sopenharmony_ci	free(mnt_path);
1415e5c12b0Sopenharmony_ci	return 0;
1425e5c12b0Sopenharmony_ci}
1435e5c12b0Sopenharmony_ci
1445e5c12b0Sopenharmony_cistatic void set_inode_metadata(struct dentry *de)
1455e5c12b0Sopenharmony_ci{
1465e5c12b0Sopenharmony_ci	struct stat stat;
1475e5c12b0Sopenharmony_ci	int ret;
1485e5c12b0Sopenharmony_ci
1495e5c12b0Sopenharmony_ci	ret = lstat(de->full_path, &stat);
1505e5c12b0Sopenharmony_ci	if (ret < 0) {
1515e5c12b0Sopenharmony_ci		ERR_MSG("lstat failure\n");
1525e5c12b0Sopenharmony_ci		ASSERT(0);
1535e5c12b0Sopenharmony_ci	}
1545e5c12b0Sopenharmony_ci
1555e5c12b0Sopenharmony_ci	if (S_ISREG(stat.st_mode)) {
1565e5c12b0Sopenharmony_ci		if (stat.st_nlink > 1) {
1575e5c12b0Sopenharmony_ci			/*
1585e5c12b0Sopenharmony_ci			 * This file might have multiple links to it, so remember
1595e5c12b0Sopenharmony_ci			 * device and inode.
1605e5c12b0Sopenharmony_ci			 */
1615e5c12b0Sopenharmony_ci			de->from_devino = stat.st_dev;
1625e5c12b0Sopenharmony_ci			de->from_devino <<= 32;
1635e5c12b0Sopenharmony_ci			de->from_devino |= stat.st_ino;
1645e5c12b0Sopenharmony_ci		}
1655e5c12b0Sopenharmony_ci		de->file_type = F2FS_FT_REG_FILE;
1665e5c12b0Sopenharmony_ci	} else if (S_ISDIR(stat.st_mode)) {
1675e5c12b0Sopenharmony_ci		de->file_type = F2FS_FT_DIR;
1685e5c12b0Sopenharmony_ci	} else if (S_ISCHR(stat.st_mode)) {
1695e5c12b0Sopenharmony_ci		de->file_type = F2FS_FT_CHRDEV;
1705e5c12b0Sopenharmony_ci	} else if (S_ISBLK(stat.st_mode)) {
1715e5c12b0Sopenharmony_ci		de->file_type = F2FS_FT_BLKDEV;
1725e5c12b0Sopenharmony_ci	} else if (S_ISFIFO(stat.st_mode)) {
1735e5c12b0Sopenharmony_ci		de->file_type = F2FS_FT_FIFO;
1745e5c12b0Sopenharmony_ci	} else if (S_ISSOCK(stat.st_mode)) {
1755e5c12b0Sopenharmony_ci		de->file_type = F2FS_FT_SOCK;
1765e5c12b0Sopenharmony_ci	} else if (S_ISLNK(stat.st_mode)) {
1775e5c12b0Sopenharmony_ci		de->file_type = F2FS_FT_SYMLINK;
1785e5c12b0Sopenharmony_ci		de->link = calloc(F2FS_BLKSIZE, 1);
1795e5c12b0Sopenharmony_ci		ASSERT(de->link);
1805e5c12b0Sopenharmony_ci		ret = readlink(de->full_path, de->link, F2FS_BLKSIZE - 1);
1815e5c12b0Sopenharmony_ci		ASSERT(ret >= 0);
1825e5c12b0Sopenharmony_ci	} else {
1835e5c12b0Sopenharmony_ci		ERR_MSG("unknown file type on %s", de->path);
1845e5c12b0Sopenharmony_ci		ASSERT(0);
1855e5c12b0Sopenharmony_ci	}
1865e5c12b0Sopenharmony_ci
1875e5c12b0Sopenharmony_ci	de->size = stat.st_size;
1885e5c12b0Sopenharmony_ci	de->mode = stat.st_mode &
1895e5c12b0Sopenharmony_ci			(S_IFMT|S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO);
1905e5c12b0Sopenharmony_ci	if (c.fixed_time == -1 && c.from_dir)
1915e5c12b0Sopenharmony_ci		de->mtime = stat.st_mtime;
1925e5c12b0Sopenharmony_ci	else
1935e5c12b0Sopenharmony_ci		de->mtime = c.fixed_time;
1945e5c12b0Sopenharmony_ci
1955e5c12b0Sopenharmony_ci	if (c.preserve_perms) {
1965e5c12b0Sopenharmony_ci		de->uid = stat.st_uid;
1975e5c12b0Sopenharmony_ci		de->gid = stat.st_gid;
1985e5c12b0Sopenharmony_ci	}
1995e5c12b0Sopenharmony_ci
2005e5c12b0Sopenharmony_ci	set_perms_and_caps(de);
2015e5c12b0Sopenharmony_ci}
2025e5c12b0Sopenharmony_ci
2035e5c12b0Sopenharmony_cistatic int build_directory(struct f2fs_sb_info *sbi, const char *full_path,
2045e5c12b0Sopenharmony_ci			const char *dir_path, const char *target_out_dir,
2055e5c12b0Sopenharmony_ci			nid_t dir_ino)
2065e5c12b0Sopenharmony_ci{
2075e5c12b0Sopenharmony_ci	int entries = 0;
2085e5c12b0Sopenharmony_ci	struct dentry *dentries;
2095e5c12b0Sopenharmony_ci	struct dirent **namelist = NULL;
2105e5c12b0Sopenharmony_ci	int i = 0, ret = 0;
2115e5c12b0Sopenharmony_ci
2125e5c12b0Sopenharmony_ci	entries = scandir(full_path, &namelist, filter_dot, (void *)alphasort);
2135e5c12b0Sopenharmony_ci	if (entries < 0) {
2145e5c12b0Sopenharmony_ci		ERR_MSG("No entries in %s\n", full_path);
2155e5c12b0Sopenharmony_ci		return -ENOENT;
2165e5c12b0Sopenharmony_ci	}
2175e5c12b0Sopenharmony_ci
2185e5c12b0Sopenharmony_ci	dentries = calloc(entries, sizeof(struct dentry));
2195e5c12b0Sopenharmony_ci	ASSERT(dentries);
2205e5c12b0Sopenharmony_ci
2215e5c12b0Sopenharmony_ci	for (i = 0; i < entries; i++) {
2225e5c12b0Sopenharmony_ci		dentries[i].name = (unsigned char *)strdup(namelist[i]->d_name);
2235e5c12b0Sopenharmony_ci		if (dentries[i].name == NULL) {
2245e5c12b0Sopenharmony_ci			ERR_MSG("Skip: ENOMEM\n");
2255e5c12b0Sopenharmony_ci			continue;
2265e5c12b0Sopenharmony_ci		}
2275e5c12b0Sopenharmony_ci		dentries[i].len = strlen((char *)dentries[i].name);
2285e5c12b0Sopenharmony_ci
2295e5c12b0Sopenharmony_ci		ret = asprintf(&dentries[i].path, "%s%s",
2305e5c12b0Sopenharmony_ci					dir_path, namelist[i]->d_name);
2315e5c12b0Sopenharmony_ci		ASSERT(ret > 0);
2325e5c12b0Sopenharmony_ci		ret = asprintf(&dentries[i].full_path, "%s/%s",
2335e5c12b0Sopenharmony_ci					full_path, namelist[i]->d_name);
2345e5c12b0Sopenharmony_ci		ASSERT(ret > 0);
2355e5c12b0Sopenharmony_ci		free(namelist[i]);
2365e5c12b0Sopenharmony_ci
2375e5c12b0Sopenharmony_ci		set_inode_metadata(dentries + i);
2385e5c12b0Sopenharmony_ci
2395e5c12b0Sopenharmony_ci		dentries[i].pino = dir_ino;
2405e5c12b0Sopenharmony_ci	}
2415e5c12b0Sopenharmony_ci
2425e5c12b0Sopenharmony_ci	free(namelist);
2435e5c12b0Sopenharmony_ci
2445e5c12b0Sopenharmony_ci	ret = f2fs_make_directory(sbi, entries, dentries);
2455e5c12b0Sopenharmony_ci	if (ret)
2465e5c12b0Sopenharmony_ci		goto out_free;
2475e5c12b0Sopenharmony_ci
2485e5c12b0Sopenharmony_ci	for (i = 0; i < entries; i++) {
2495e5c12b0Sopenharmony_ci		if (dentries[i].file_type == F2FS_FT_REG_FILE) {
2505e5c12b0Sopenharmony_ci			f2fs_build_file(sbi, dentries + i);
2515e5c12b0Sopenharmony_ci		} else if (dentries[i].file_type == F2FS_FT_DIR) {
2525e5c12b0Sopenharmony_ci			char *subdir_full_path = NULL;
2535e5c12b0Sopenharmony_ci			char *subdir_dir_path = NULL;
2545e5c12b0Sopenharmony_ci
2555e5c12b0Sopenharmony_ci			ret = asprintf(&subdir_full_path, "%s",
2565e5c12b0Sopenharmony_ci							dentries[i].full_path);
2575e5c12b0Sopenharmony_ci			ASSERT(ret > 0);
2585e5c12b0Sopenharmony_ci			ret = asprintf(&subdir_dir_path, "%s/",
2595e5c12b0Sopenharmony_ci							dentries[i].path);
2605e5c12b0Sopenharmony_ci			ASSERT(ret > 0);
2615e5c12b0Sopenharmony_ci
2625e5c12b0Sopenharmony_ci			ret = build_directory(sbi, subdir_full_path,
2635e5c12b0Sopenharmony_ci						subdir_dir_path,
2645e5c12b0Sopenharmony_ci						target_out_dir,
2655e5c12b0Sopenharmony_ci						dentries[i].ino);
2665e5c12b0Sopenharmony_ci			free(subdir_full_path);
2675e5c12b0Sopenharmony_ci			free(subdir_dir_path);
2685e5c12b0Sopenharmony_ci
2695e5c12b0Sopenharmony_ci			if (ret)
2705e5c12b0Sopenharmony_ci				goto out_free;
2715e5c12b0Sopenharmony_ci		} else if (dentries[i].file_type == F2FS_FT_SYMLINK) {
2725e5c12b0Sopenharmony_ci			/*
2735e5c12b0Sopenharmony_ci			 * It is already done in f2fs_make_directory
2745e5c12b0Sopenharmony_ci			 * f2fs_make_symlink(sbi, dir_ino, &dentries[i]);
2755e5c12b0Sopenharmony_ci			 */
2765e5c12b0Sopenharmony_ci		} else {
2775e5c12b0Sopenharmony_ci			MSG(1, "Error unknown file type\n");
2785e5c12b0Sopenharmony_ci		}
2795e5c12b0Sopenharmony_ci
2805e5c12b0Sopenharmony_ci		ret = set_selinux_xattr(sbi, dentries[i].path,
2815e5c12b0Sopenharmony_ci					dentries[i].ino, dentries[i].mode);
2825e5c12b0Sopenharmony_ci		if (ret)
2835e5c12b0Sopenharmony_ci			goto out_free;
2845e5c12b0Sopenharmony_ci
2855e5c12b0Sopenharmony_ci		free(dentries[i].path);
2865e5c12b0Sopenharmony_ci		free(dentries[i].full_path);
2875e5c12b0Sopenharmony_ci		free((void *)dentries[i].name);
2885e5c12b0Sopenharmony_ci	}
2895e5c12b0Sopenharmony_ciout_free:
2905e5c12b0Sopenharmony_ci	for (; i < entries; i++) {
2915e5c12b0Sopenharmony_ci		free(dentries[i].path);
2925e5c12b0Sopenharmony_ci		free(dentries[i].full_path);
2935e5c12b0Sopenharmony_ci		free((void *)dentries[i].name);
2945e5c12b0Sopenharmony_ci	}
2955e5c12b0Sopenharmony_ci
2965e5c12b0Sopenharmony_ci	free(dentries);
2975e5c12b0Sopenharmony_ci	return 0;
2985e5c12b0Sopenharmony_ci}
2995e5c12b0Sopenharmony_ci#else
3005e5c12b0Sopenharmony_cistatic int build_directory(struct f2fs_sb_info *sbi, const char *full_path,
3015e5c12b0Sopenharmony_ci			const char *dir_path, const char *target_out_dir,
3025e5c12b0Sopenharmony_ci			nid_t dir_ino)
3035e5c12b0Sopenharmony_ci{
3045e5c12b0Sopenharmony_ci	return -1;
3055e5c12b0Sopenharmony_ci}
3065e5c12b0Sopenharmony_ci#endif
3075e5c12b0Sopenharmony_ci
3085e5c12b0Sopenharmony_cistatic int configure_files(void)
3095e5c12b0Sopenharmony_ci{
3105e5c12b0Sopenharmony_ci#ifdef HAVE_LIBSELINUX
3115e5c12b0Sopenharmony_ci	if (!c.nr_opt)
3125e5c12b0Sopenharmony_ci		goto skip;
3135e5c12b0Sopenharmony_ci#if !defined(__ANDROID__)
3145e5c12b0Sopenharmony_ci	sehnd = selabel_open(SELABEL_CTX_FILE, c.seopt_file, c.nr_opt);
3155e5c12b0Sopenharmony_ci	if (!sehnd) {
3165e5c12b0Sopenharmony_ci		ERR_MSG("Failed to open file contexts \"%s\"",
3175e5c12b0Sopenharmony_ci					c.seopt_file[0].value);
3185e5c12b0Sopenharmony_ci			return -EINVAL;
3195e5c12b0Sopenharmony_ci	}
3205e5c12b0Sopenharmony_ci#else
3215e5c12b0Sopenharmony_ci	sehnd = selinux_android_file_context_handle();
3225e5c12b0Sopenharmony_ci	if (!sehnd) {
3235e5c12b0Sopenharmony_ci		ERR_MSG("Failed to get android file_contexts\n");
3245e5c12b0Sopenharmony_ci		return -EINVAL;
3255e5c12b0Sopenharmony_ci	}
3265e5c12b0Sopenharmony_ci#endif
3275e5c12b0Sopenharmony_ciskip:
3285e5c12b0Sopenharmony_ci#endif
3295e5c12b0Sopenharmony_ci#ifdef HAVE_SELINUX_ANDROID_H
3305e5c12b0Sopenharmony_ci	/* Load the FS config */
3315e5c12b0Sopenharmony_ci	if (c.fs_config_file) {
3325e5c12b0Sopenharmony_ci		int ret = load_canned_fs_config(c.fs_config_file);
3335e5c12b0Sopenharmony_ci
3345e5c12b0Sopenharmony_ci		if (ret < 0) {
3355e5c12b0Sopenharmony_ci			ERR_MSG("Failed to load fs_config \"%s\"",
3365e5c12b0Sopenharmony_ci						c.fs_config_file);
3375e5c12b0Sopenharmony_ci			return ret;
3385e5c12b0Sopenharmony_ci		}
3395e5c12b0Sopenharmony_ci		fs_config_func = canned_fs_config;
3405e5c12b0Sopenharmony_ci	} else {
3415e5c12b0Sopenharmony_ci		fs_config_func = fs_config;
3425e5c12b0Sopenharmony_ci	}
3435e5c12b0Sopenharmony_ci#endif
3445e5c12b0Sopenharmony_ci	return 0;
3455e5c12b0Sopenharmony_ci}
3465e5c12b0Sopenharmony_ci
3475e5c12b0Sopenharmony_ciint f2fs_sload(struct f2fs_sb_info *sbi)
3485e5c12b0Sopenharmony_ci{
3495e5c12b0Sopenharmony_ci	int ret = 0;
3505e5c12b0Sopenharmony_ci
3515e5c12b0Sopenharmony_ci	/* this requires for the below sanity checks */
3525e5c12b0Sopenharmony_ci	fsck_init(sbi);
3535e5c12b0Sopenharmony_ci
3545e5c12b0Sopenharmony_ci	ret = configure_files();
3555e5c12b0Sopenharmony_ci	if (ret) {
3565e5c12b0Sopenharmony_ci		ERR_MSG("Failed to configure files\n");
3575e5c12b0Sopenharmony_ci		return ret;
3585e5c12b0Sopenharmony_ci	}
3595e5c12b0Sopenharmony_ci
3605e5c12b0Sopenharmony_ci	/* flush NAT/SIT journal entries */
3615e5c12b0Sopenharmony_ci	flush_journal_entries(sbi);
3625e5c12b0Sopenharmony_ci
3635e5c12b0Sopenharmony_ci	/* initialize empty hardlink cache */
3645e5c12b0Sopenharmony_ci	sbi->hardlink_cache = 0;
3655e5c12b0Sopenharmony_ci
3665e5c12b0Sopenharmony_ci	ret = build_directory(sbi, c.from_dir, "/",
3675e5c12b0Sopenharmony_ci					c.target_out_dir, F2FS_ROOT_INO(sbi));
3685e5c12b0Sopenharmony_ci	if (ret) {
3695e5c12b0Sopenharmony_ci		ERR_MSG("Failed to build due to %d\n", ret);
3705e5c12b0Sopenharmony_ci		return ret;
3715e5c12b0Sopenharmony_ci	}
3725e5c12b0Sopenharmony_ci
3735e5c12b0Sopenharmony_ci	ret = set_selinux_xattr(sbi, c.mount_point,
3745e5c12b0Sopenharmony_ci					F2FS_ROOT_INO(sbi), S_IFDIR);
3755e5c12b0Sopenharmony_ci	if (ret) {
3765e5c12b0Sopenharmony_ci		ERR_MSG("Failed to set selinux for root: %d\n", ret);
3775e5c12b0Sopenharmony_ci		return ret;
3785e5c12b0Sopenharmony_ci	}
3795e5c12b0Sopenharmony_ci
3805e5c12b0Sopenharmony_ci	/* update curseg info; can update sit->types */
3815e5c12b0Sopenharmony_ci	move_curseg_info(sbi, SM_I(sbi)->main_blkaddr, 0);
3825e5c12b0Sopenharmony_ci	zero_journal_entries(sbi);
3835e5c12b0Sopenharmony_ci	write_curseg_info(sbi);
3845e5c12b0Sopenharmony_ci
3855e5c12b0Sopenharmony_ci	/* flush dirty sit entries */
3865e5c12b0Sopenharmony_ci	flush_sit_entries(sbi);
3875e5c12b0Sopenharmony_ci
3885e5c12b0Sopenharmony_ci	write_checkpoint(sbi);
3895e5c12b0Sopenharmony_ci	return 0;
3905e5c12b0Sopenharmony_ci}
391