15e5c12b0Sopenharmony_ci/** 25e5c12b0Sopenharmony_ci * f2fs_format.c 35e5c12b0Sopenharmony_ci * 45e5c12b0Sopenharmony_ci * Copyright (c) 2012 Samsung Electronics Co., Ltd. 55e5c12b0Sopenharmony_ci * http://www.samsung.com/ 65e5c12b0Sopenharmony_ci * 75e5c12b0Sopenharmony_ci * Dual licensed under the GPL or LGPL version 2 licenses. 85e5c12b0Sopenharmony_ci */ 95e5c12b0Sopenharmony_ci#ifndef _LARGEFILE64_SOURCE 105e5c12b0Sopenharmony_ci#define _LARGEFILE64_SOURCE 115e5c12b0Sopenharmony_ci#endif 125e5c12b0Sopenharmony_ci 135e5c12b0Sopenharmony_ci#include <stdio.h> 145e5c12b0Sopenharmony_ci#include <stdlib.h> 155e5c12b0Sopenharmony_ci#include <fcntl.h> 165e5c12b0Sopenharmony_ci#include <string.h> 175e5c12b0Sopenharmony_ci#include <stdbool.h> 185e5c12b0Sopenharmony_ci#include <unistd.h> 195e5c12b0Sopenharmony_ci#include <sys/stat.h> 205e5c12b0Sopenharmony_ci#ifdef HAVE_SYS_MOUNT_H 215e5c12b0Sopenharmony_ci#include <sys/mount.h> 225e5c12b0Sopenharmony_ci#endif 235e5c12b0Sopenharmony_ci#include <time.h> 245e5c12b0Sopenharmony_ci#include <errno.h> 255e5c12b0Sopenharmony_ci#include <getopt.h> 265e5c12b0Sopenharmony_ci 275e5c12b0Sopenharmony_ci#include <f2fs_fs.h> 285e5c12b0Sopenharmony_ci 295e5c12b0Sopenharmony_ci#ifdef HAVE_LIBBLKID 305e5c12b0Sopenharmony_ci#include <blkid/blkid.h> 315e5c12b0Sopenharmony_ci#endif 325e5c12b0Sopenharmony_ci#ifdef HAVE_UUID_UUID_H 335e5c12b0Sopenharmony_ci#include <uuid.h> 345e5c12b0Sopenharmony_ci#endif 355e5c12b0Sopenharmony_ci 365e5c12b0Sopenharmony_ci#include "quota.h" 375e5c12b0Sopenharmony_ci#include "f2fs_format_utils.h" 385e5c12b0Sopenharmony_ci 395e5c12b0Sopenharmony_ci#ifdef HAVE_SYS_UTSNAME_H 405e5c12b0Sopenharmony_ci#include <sys/utsname.h> 415e5c12b0Sopenharmony_ci#endif 425e5c12b0Sopenharmony_ci#ifdef HAVE_SPARSE_SPARSE_H 435e5c12b0Sopenharmony_ci#include <sparse/sparse.h> 445e5c12b0Sopenharmony_ciextern struct sparse_file *f2fs_sparse_file; 455e5c12b0Sopenharmony_ci#endif 465e5c12b0Sopenharmony_ci 475e5c12b0Sopenharmony_ciextern struct f2fs_configuration c; 485e5c12b0Sopenharmony_cistatic int force_overwrite = 0; 495e5c12b0Sopenharmony_ci 505e5c12b0Sopenharmony_ciINIT_FEATURE_TABLE; 515e5c12b0Sopenharmony_ci 525e5c12b0Sopenharmony_cistatic void mkfs_usage() 535e5c12b0Sopenharmony_ci{ 545e5c12b0Sopenharmony_ci MSG(0, "\nUsage: mkfs.f2fs [options] device [sectors]\n"); 555e5c12b0Sopenharmony_ci MSG(0, "[options]:\n"); 565e5c12b0Sopenharmony_ci MSG(0, " -a heap-based allocation [default:0]\n"); 575e5c12b0Sopenharmony_ci MSG(0, " -c device1[,device2,...] up to 7 additional devices, except meta device\n"); 585e5c12b0Sopenharmony_ci MSG(0, " -d debug level [default:0]\n"); 595e5c12b0Sopenharmony_ci MSG(0, " -e [cold file ext list] e.g. \"mp3,gif,mov\"\n"); 605e5c12b0Sopenharmony_ci MSG(0, " -E [hot file ext list] e.g. \"db\"\n"); 615e5c12b0Sopenharmony_ci MSG(0, " -f force overwrite of the existing filesystem\n"); 625e5c12b0Sopenharmony_ci MSG(0, " -g add default options\n"); 635e5c12b0Sopenharmony_ci MSG(0, " -i extended node bitmap, node ratio is 20%% by default\n"); 645e5c12b0Sopenharmony_ci MSG(0, " -l label\n"); 655e5c12b0Sopenharmony_ci MSG(0, " -U uuid\n"); 665e5c12b0Sopenharmony_ci MSG(0, " -m support zoned block device [default:0]\n"); 675e5c12b0Sopenharmony_ci MSG(0, " -o overprovision percentage [default:auto]\n"); 685e5c12b0Sopenharmony_ci MSG(0, " -O feature1[,feature2,...] e.g. \"encrypt\"\n"); 695e5c12b0Sopenharmony_ci MSG(0, " -C [encoding[:flag1,...]] Support casefolding with optional flags\n"); 705e5c12b0Sopenharmony_ci MSG(0, " -q quiet mode\n"); 715e5c12b0Sopenharmony_ci MSG(0, " -r set checkpointing seed (srand()) to 0\n"); 725e5c12b0Sopenharmony_ci MSG(0, " -R root_owner [default: 0:0]\n"); 735e5c12b0Sopenharmony_ci MSG(0, " -s # of segments per section [default:1]\n"); 745e5c12b0Sopenharmony_ci MSG(0, " -S sparse mode\n"); 755e5c12b0Sopenharmony_ci MSG(0, " -t 0: nodiscard, 1: discard [default:1]\n"); 765e5c12b0Sopenharmony_ci MSG(0, " -T timestamps\n"); 775e5c12b0Sopenharmony_ci MSG(0, " -w wanted sector size\n"); 785e5c12b0Sopenharmony_ci MSG(0, " -z # of sections per zone [default:1]\n"); 795e5c12b0Sopenharmony_ci MSG(0, " -V print the version number and exit\n"); 805e5c12b0Sopenharmony_ci MSG(0, "sectors: number of sectors [default: determined by device size]\n"); 815e5c12b0Sopenharmony_ci exit(1); 825e5c12b0Sopenharmony_ci} 835e5c12b0Sopenharmony_ci 845e5c12b0Sopenharmony_cistatic void f2fs_show_info() 855e5c12b0Sopenharmony_ci{ 865e5c12b0Sopenharmony_ci MSG(0, "\n F2FS-tools: mkfs.f2fs Ver: %s (%s)\n\n", 875e5c12b0Sopenharmony_ci F2FS_TOOLS_VERSION, 885e5c12b0Sopenharmony_ci F2FS_TOOLS_DATE); 895e5c12b0Sopenharmony_ci if (c.heap == 0) 905e5c12b0Sopenharmony_ci MSG(0, "Info: Disable heap-based policy\n"); 915e5c12b0Sopenharmony_ci 925e5c12b0Sopenharmony_ci MSG(0, "Info: Debug level = %d\n", c.dbg_lv); 935e5c12b0Sopenharmony_ci if (c.extension_list[0]) 945e5c12b0Sopenharmony_ci MSG(0, "Info: Add new cold file extension list\n"); 955e5c12b0Sopenharmony_ci if (c.extension_list[1]) 965e5c12b0Sopenharmony_ci MSG(0, "Info: Add new hot file extension list\n"); 975e5c12b0Sopenharmony_ci 985e5c12b0Sopenharmony_ci if (strlen(c.vol_label)) 995e5c12b0Sopenharmony_ci MSG(0, "Info: Label = %s\n", c.vol_label); 1005e5c12b0Sopenharmony_ci MSG(0, "Info: Trim is %s\n", c.trim ? "enabled": "disabled"); 1015e5c12b0Sopenharmony_ci 1025e5c12b0Sopenharmony_ci if (c.defset == CONF_ANDROID) 1035e5c12b0Sopenharmony_ci MSG(0, "Info: Set conf for android\n"); 1045e5c12b0Sopenharmony_ci 1055e5c12b0Sopenharmony_ci if (c.feature & le32_to_cpu(F2FS_FEATURE_CASEFOLD)) 1065e5c12b0Sopenharmony_ci MSG(0, "Info: Enable %s with casefolding\n", 1075e5c12b0Sopenharmony_ci f2fs_encoding2str(c.s_encoding)); 1085e5c12b0Sopenharmony_ci if (c.feature & le32_to_cpu(F2FS_FEATURE_PRJQUOTA)) 1095e5c12b0Sopenharmony_ci MSG(0, "Info: Enable Project quota\n"); 1105e5c12b0Sopenharmony_ci 1115e5c12b0Sopenharmony_ci if (c.feature & le32_to_cpu(F2FS_FEATURE_COMPRESSION)) 1125e5c12b0Sopenharmony_ci MSG(0, "Info: Enable Compression\n"); 1135e5c12b0Sopenharmony_ci} 1145e5c12b0Sopenharmony_ci 1155e5c12b0Sopenharmony_ci#if defined(ANDROID_TARGET) && defined(HAVE_SYS_UTSNAME_H) 1165e5c12b0Sopenharmony_cistatic bool kernel_version_over(unsigned int min_major, unsigned int min_minor) 1175e5c12b0Sopenharmony_ci{ 1185e5c12b0Sopenharmony_ci unsigned int major, minor; 1195e5c12b0Sopenharmony_ci struct utsname uts; 1205e5c12b0Sopenharmony_ci 1215e5c12b0Sopenharmony_ci if ((uname(&uts) != 0) || 1225e5c12b0Sopenharmony_ci (sscanf(uts.release, "%u.%u", &major, &minor) != 2)) 1235e5c12b0Sopenharmony_ci return false; 1245e5c12b0Sopenharmony_ci if (major > min_major) 1255e5c12b0Sopenharmony_ci return true; 1265e5c12b0Sopenharmony_ci if (major == min_major && minor >= min_minor) 1275e5c12b0Sopenharmony_ci return true; 1285e5c12b0Sopenharmony_ci return false; 1295e5c12b0Sopenharmony_ci} 1305e5c12b0Sopenharmony_ci#else 1315e5c12b0Sopenharmony_cistatic bool kernel_version_over(unsigned int UNUSED(min_major), 1325e5c12b0Sopenharmony_ci unsigned int UNUSED(min_minor)) 1335e5c12b0Sopenharmony_ci{ 1345e5c12b0Sopenharmony_ci return false; 1355e5c12b0Sopenharmony_ci} 1365e5c12b0Sopenharmony_ci#endif 1375e5c12b0Sopenharmony_ci 1385e5c12b0Sopenharmony_cistatic void add_default_options(void) 1395e5c12b0Sopenharmony_ci{ 1405e5c12b0Sopenharmony_ci switch (c.defset) { 1415e5c12b0Sopenharmony_ci case CONF_ANDROID: 1425e5c12b0Sopenharmony_ci /* -d1 -f -w 4096 -R 0:0 */ 1435e5c12b0Sopenharmony_ci c.dbg_lv = 1; 1445e5c12b0Sopenharmony_ci force_overwrite = 1; 1455e5c12b0Sopenharmony_ci c.wanted_sector_size = 4096; 1465e5c12b0Sopenharmony_ci c.root_uid = c.root_gid = 0; 1475e5c12b0Sopenharmony_ci 1485e5c12b0Sopenharmony_ci /* RO doesn't need any other features */ 1495e5c12b0Sopenharmony_ci if (c.feature & cpu_to_le32(F2FS_FEATURE_RO)) 1505e5c12b0Sopenharmony_ci return; 1515e5c12b0Sopenharmony_ci 1525e5c12b0Sopenharmony_ci /* -O encrypt -O project_quota,extra_attr,{quota} -O verity */ 1535e5c12b0Sopenharmony_ci c.feature |= cpu_to_le32(F2FS_FEATURE_ENCRYPT); 1545e5c12b0Sopenharmony_ci if (!kernel_version_over(4, 14)) 1555e5c12b0Sopenharmony_ci c.feature |= cpu_to_le32(F2FS_FEATURE_QUOTA_INO); 1565e5c12b0Sopenharmony_ci c.feature |= cpu_to_le32(F2FS_FEATURE_PRJQUOTA); 1575e5c12b0Sopenharmony_ci c.feature |= cpu_to_le32(F2FS_FEATURE_EXTRA_ATTR); 1585e5c12b0Sopenharmony_ci c.feature |= cpu_to_le32(F2FS_FEATURE_VERITY); 1595e5c12b0Sopenharmony_ci break; 1605e5c12b0Sopenharmony_ci } 1615e5c12b0Sopenharmony_ci#ifdef CONF_CASEFOLD 1625e5c12b0Sopenharmony_ci c.s_encoding = F2FS_ENC_UTF8_12_1; 1635e5c12b0Sopenharmony_ci c.feature |= cpu_to_le32(F2FS_FEATURE_CASEFOLD); 1645e5c12b0Sopenharmony_ci#endif 1655e5c12b0Sopenharmony_ci#ifdef CONF_PROJID 1665e5c12b0Sopenharmony_ci c.feature |= cpu_to_le32(F2FS_FEATURE_QUOTA_INO); 1675e5c12b0Sopenharmony_ci c.feature |= cpu_to_le32(F2FS_FEATURE_PRJQUOTA); 1685e5c12b0Sopenharmony_ci c.feature |= cpu_to_le32(F2FS_FEATURE_EXTRA_ATTR); 1695e5c12b0Sopenharmony_ci#endif 1705e5c12b0Sopenharmony_ci 1715e5c12b0Sopenharmony_ci if (c.feature & cpu_to_le32(F2FS_FEATURE_QUOTA_INO)) 1725e5c12b0Sopenharmony_ci c.quota_bits = QUOTA_USR_BIT | QUOTA_GRP_BIT; 1735e5c12b0Sopenharmony_ci if (c.feature & cpu_to_le32(F2FS_FEATURE_PRJQUOTA)) { 1745e5c12b0Sopenharmony_ci c.feature |= cpu_to_le32(F2FS_FEATURE_QUOTA_INO); 1755e5c12b0Sopenharmony_ci c.quota_bits |= QUOTA_PRJ_BIT; 1765e5c12b0Sopenharmony_ci } 1775e5c12b0Sopenharmony_ci} 1785e5c12b0Sopenharmony_ci 1795e5c12b0Sopenharmony_cistatic void f2fs_parse_options(int argc, char *argv[]) 1805e5c12b0Sopenharmony_ci{ 1815e5c12b0Sopenharmony_ci static const char *option_string = "qa:c:C:d:e:E:g:hil:mo:O:rR:s:S:z:t:T:U:Vfw:"; 1825e5c12b0Sopenharmony_ci static const struct option long_opts[] = { 1835e5c12b0Sopenharmony_ci { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, 1845e5c12b0Sopenharmony_ci { .name = NULL, .has_arg = 0, .flag = NULL, .val = 0 } 1855e5c12b0Sopenharmony_ci }; 1865e5c12b0Sopenharmony_ci int32_t option=0; 1875e5c12b0Sopenharmony_ci int val; 1885e5c12b0Sopenharmony_ci char *token; 1895e5c12b0Sopenharmony_ci 1905e5c12b0Sopenharmony_ci while ((option = getopt_long(argc,argv,option_string,long_opts,NULL)) != EOF) { 1915e5c12b0Sopenharmony_ci switch (option) { 1925e5c12b0Sopenharmony_ci case 'q': 1935e5c12b0Sopenharmony_ci c.dbg_lv = -1; 1945e5c12b0Sopenharmony_ci break; 1955e5c12b0Sopenharmony_ci case 'a': 1965e5c12b0Sopenharmony_ci c.heap = atoi(optarg); 1975e5c12b0Sopenharmony_ci break; 1985e5c12b0Sopenharmony_ci case 'c': 1995e5c12b0Sopenharmony_ci if (c.ndevs >= MAX_DEVICES) { 2005e5c12b0Sopenharmony_ci MSG(0, "Error: Too many devices\n"); 2015e5c12b0Sopenharmony_ci mkfs_usage(); 2025e5c12b0Sopenharmony_ci } 2035e5c12b0Sopenharmony_ci 2045e5c12b0Sopenharmony_ci if (strlen(optarg) > MAX_PATH_LEN) { 2055e5c12b0Sopenharmony_ci MSG(0, "Error: device path should be less than " 2065e5c12b0Sopenharmony_ci "%d characters\n", MAX_PATH_LEN); 2075e5c12b0Sopenharmony_ci mkfs_usage(); 2085e5c12b0Sopenharmony_ci } 2095e5c12b0Sopenharmony_ci c.devices[c.ndevs++].path = strdup(optarg); 2105e5c12b0Sopenharmony_ci break; 2115e5c12b0Sopenharmony_ci case 'd': 2125e5c12b0Sopenharmony_ci c.dbg_lv = atoi(optarg); 2135e5c12b0Sopenharmony_ci break; 2145e5c12b0Sopenharmony_ci case 'e': 2155e5c12b0Sopenharmony_ci c.extension_list[0] = strdup(optarg); 2165e5c12b0Sopenharmony_ci break; 2175e5c12b0Sopenharmony_ci case 'E': 2185e5c12b0Sopenharmony_ci c.extension_list[1] = strdup(optarg); 2195e5c12b0Sopenharmony_ci break; 2205e5c12b0Sopenharmony_ci case 'g': 2215e5c12b0Sopenharmony_ci if (!strcmp(optarg, "android")) 2225e5c12b0Sopenharmony_ci c.defset = CONF_ANDROID; 2235e5c12b0Sopenharmony_ci break; 2245e5c12b0Sopenharmony_ci case 'h': 2255e5c12b0Sopenharmony_ci mkfs_usage(); 2265e5c12b0Sopenharmony_ci break; 2275e5c12b0Sopenharmony_ci case 'i': 2285e5c12b0Sopenharmony_ci c.large_nat_bitmap = 1; 2295e5c12b0Sopenharmony_ci break; 2305e5c12b0Sopenharmony_ci case 'l': /*v: volume label */ 2315e5c12b0Sopenharmony_ci if (strlen(optarg) > 512) { 2325e5c12b0Sopenharmony_ci MSG(0, "Error: Volume Label should be less than " 2335e5c12b0Sopenharmony_ci "512 characters\n"); 2345e5c12b0Sopenharmony_ci mkfs_usage(); 2355e5c12b0Sopenharmony_ci } 2365e5c12b0Sopenharmony_ci c.vol_label = optarg; 2375e5c12b0Sopenharmony_ci break; 2385e5c12b0Sopenharmony_ci case 'm': 2395e5c12b0Sopenharmony_ci c.zoned_mode = 1; 2405e5c12b0Sopenharmony_ci break; 2415e5c12b0Sopenharmony_ci case 'o': 2425e5c12b0Sopenharmony_ci c.overprovision = atof(optarg); 2435e5c12b0Sopenharmony_ci break; 2445e5c12b0Sopenharmony_ci case 'O': 2455e5c12b0Sopenharmony_ci if (parse_feature(feature_table, optarg)) 2465e5c12b0Sopenharmony_ci mkfs_usage(); 2475e5c12b0Sopenharmony_ci break; 2485e5c12b0Sopenharmony_ci case 'r': 2495e5c12b0Sopenharmony_ci c.fake_seed = 1; 2505e5c12b0Sopenharmony_ci break; 2515e5c12b0Sopenharmony_ci case 'R': 2525e5c12b0Sopenharmony_ci if (parse_root_owner(optarg, &c.root_uid, &c.root_gid)) 2535e5c12b0Sopenharmony_ci mkfs_usage(); 2545e5c12b0Sopenharmony_ci break; 2555e5c12b0Sopenharmony_ci case 's': 2565e5c12b0Sopenharmony_ci c.segs_per_sec = atoi(optarg); 2575e5c12b0Sopenharmony_ci break; 2585e5c12b0Sopenharmony_ci case 'S': 2595e5c12b0Sopenharmony_ci c.device_size = atoll(optarg); 2605e5c12b0Sopenharmony_ci c.device_size &= (~((uint64_t)(F2FS_BLKSIZE - 1))); 2615e5c12b0Sopenharmony_ci c.sparse_mode = 1; 2625e5c12b0Sopenharmony_ci break; 2635e5c12b0Sopenharmony_ci case 'z': 2645e5c12b0Sopenharmony_ci c.secs_per_zone = atoi(optarg); 2655e5c12b0Sopenharmony_ci break; 2665e5c12b0Sopenharmony_ci case 't': 2675e5c12b0Sopenharmony_ci c.trim = atoi(optarg); 2685e5c12b0Sopenharmony_ci break; 2695e5c12b0Sopenharmony_ci case 'T': 2705e5c12b0Sopenharmony_ci c.fixed_time = strtoul(optarg, NULL, 0); 2715e5c12b0Sopenharmony_ci break; 2725e5c12b0Sopenharmony_ci case 'U': 2735e5c12b0Sopenharmony_ci c.vol_uuid = strdup(optarg); 2745e5c12b0Sopenharmony_ci break; 2755e5c12b0Sopenharmony_ci case 'f': 2765e5c12b0Sopenharmony_ci force_overwrite = 1; 2775e5c12b0Sopenharmony_ci break; 2785e5c12b0Sopenharmony_ci case 'w': 2795e5c12b0Sopenharmony_ci c.wanted_sector_size = atoi(optarg); 2805e5c12b0Sopenharmony_ci break; 2815e5c12b0Sopenharmony_ci case 'V': 2825e5c12b0Sopenharmony_ci show_version("mkfs.f2fs"); 2835e5c12b0Sopenharmony_ci exit(0); 2845e5c12b0Sopenharmony_ci case 'C': 2855e5c12b0Sopenharmony_ci token = strtok(optarg, ":"); 2865e5c12b0Sopenharmony_ci val = f2fs_str2encoding(token); 2875e5c12b0Sopenharmony_ci if (val < 0) { 2885e5c12b0Sopenharmony_ci MSG(0, "\tError: Unknown encoding %s\n", token); 2895e5c12b0Sopenharmony_ci mkfs_usage(); 2905e5c12b0Sopenharmony_ci } 2915e5c12b0Sopenharmony_ci c.s_encoding = val; 2925e5c12b0Sopenharmony_ci token = strtok(NULL, ""); 2935e5c12b0Sopenharmony_ci val = f2fs_str2encoding_flags(&token, &c.s_encoding_flags); 2945e5c12b0Sopenharmony_ci if (val) { 2955e5c12b0Sopenharmony_ci MSG(0, "\tError: Unknown flag %s\n",token); 2965e5c12b0Sopenharmony_ci mkfs_usage(); 2975e5c12b0Sopenharmony_ci } 2985e5c12b0Sopenharmony_ci c.feature |= cpu_to_le32(F2FS_FEATURE_CASEFOLD); 2995e5c12b0Sopenharmony_ci break; 3005e5c12b0Sopenharmony_ci default: 3015e5c12b0Sopenharmony_ci MSG(0, "\tError: Unknown option %c\n",option); 3025e5c12b0Sopenharmony_ci mkfs_usage(); 3035e5c12b0Sopenharmony_ci break; 3045e5c12b0Sopenharmony_ci } 3055e5c12b0Sopenharmony_ci } 3065e5c12b0Sopenharmony_ci 3075e5c12b0Sopenharmony_ci add_default_options(); 3085e5c12b0Sopenharmony_ci 3095e5c12b0Sopenharmony_ci if (!(c.feature & cpu_to_le32(F2FS_FEATURE_EXTRA_ATTR))) { 3105e5c12b0Sopenharmony_ci if (c.feature & cpu_to_le32(F2FS_FEATURE_PRJQUOTA)) { 3115e5c12b0Sopenharmony_ci MSG(0, "\tInfo: project quota feature should always be " 3125e5c12b0Sopenharmony_ci "enabled with extra attr feature\n"); 3135e5c12b0Sopenharmony_ci exit(1); 3145e5c12b0Sopenharmony_ci } 3155e5c12b0Sopenharmony_ci if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM)) { 3165e5c12b0Sopenharmony_ci MSG(0, "\tInfo: inode checksum feature should always be " 3175e5c12b0Sopenharmony_ci "enabled with extra attr feature\n"); 3185e5c12b0Sopenharmony_ci exit(1); 3195e5c12b0Sopenharmony_ci } 3205e5c12b0Sopenharmony_ci if (c.feature & cpu_to_le32(F2FS_FEATURE_FLEXIBLE_INLINE_XATTR)) { 3215e5c12b0Sopenharmony_ci MSG(0, "\tInfo: flexible inline xattr feature should always be " 3225e5c12b0Sopenharmony_ci "enabled with extra attr feature\n"); 3235e5c12b0Sopenharmony_ci exit(1); 3245e5c12b0Sopenharmony_ci } 3255e5c12b0Sopenharmony_ci if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CRTIME)) { 3265e5c12b0Sopenharmony_ci MSG(0, "\tInfo: inode crtime feature should always be " 3275e5c12b0Sopenharmony_ci "enabled with extra attr feature\n"); 3285e5c12b0Sopenharmony_ci exit(1); 3295e5c12b0Sopenharmony_ci } 3305e5c12b0Sopenharmony_ci if (c.feature & cpu_to_le32(F2FS_FEATURE_COMPRESSION)) { 3315e5c12b0Sopenharmony_ci MSG(0, "\tInfo: compression feature should always be " 3325e5c12b0Sopenharmony_ci "enabled with extra attr feature\n"); 3335e5c12b0Sopenharmony_ci exit(1); 3345e5c12b0Sopenharmony_ci } 3355e5c12b0Sopenharmony_ci } 3365e5c12b0Sopenharmony_ci 3375e5c12b0Sopenharmony_ci if (optind >= argc) { 3385e5c12b0Sopenharmony_ci MSG(0, "\tError: Device not specified\n"); 3395e5c12b0Sopenharmony_ci mkfs_usage(); 3405e5c12b0Sopenharmony_ci } 3415e5c12b0Sopenharmony_ci 3425e5c12b0Sopenharmony_ci /* [0] : META, [1 to MAX_DEVICES - 1] : NODE/DATA */ 3435e5c12b0Sopenharmony_ci c.devices[0].path = strdup(argv[optind]); 3445e5c12b0Sopenharmony_ci 3455e5c12b0Sopenharmony_ci if ((optind + 1) < argc) { 3465e5c12b0Sopenharmony_ci if (c.ndevs > 1) { 3475e5c12b0Sopenharmony_ci MSG(0, "\tError: Not support custom size on multi-devs.\n"); 3485e5c12b0Sopenharmony_ci mkfs_usage(); 3495e5c12b0Sopenharmony_ci } 3505e5c12b0Sopenharmony_ci c.wanted_total_sectors = atoll(argv[optind+1]); 3515e5c12b0Sopenharmony_ci } 3525e5c12b0Sopenharmony_ci 3535e5c12b0Sopenharmony_ci if (c.sparse_mode) 3545e5c12b0Sopenharmony_ci c.trim = 0; 3555e5c12b0Sopenharmony_ci 3565e5c12b0Sopenharmony_ci if (c.zoned_mode) 3575e5c12b0Sopenharmony_ci c.feature |= cpu_to_le32(F2FS_FEATURE_BLKZONED); 3585e5c12b0Sopenharmony_ci} 3595e5c12b0Sopenharmony_ci 3605e5c12b0Sopenharmony_ci#ifdef HAVE_LIBBLKID 3615e5c12b0Sopenharmony_cistatic int f2fs_dev_is_overwrite(const char *device) 3625e5c12b0Sopenharmony_ci{ 3635e5c12b0Sopenharmony_ci const char *type; 3645e5c12b0Sopenharmony_ci blkid_probe pr = NULL; 3655e5c12b0Sopenharmony_ci int ret = -1; 3665e5c12b0Sopenharmony_ci 3675e5c12b0Sopenharmony_ci if (!device || !*device) 3685e5c12b0Sopenharmony_ci return 0; 3695e5c12b0Sopenharmony_ci 3705e5c12b0Sopenharmony_ci pr = blkid_new_probe_from_filename(device); 3715e5c12b0Sopenharmony_ci if (!pr) 3725e5c12b0Sopenharmony_ci goto out; 3735e5c12b0Sopenharmony_ci 3745e5c12b0Sopenharmony_ci ret = blkid_probe_enable_partitions(pr, 1); 3755e5c12b0Sopenharmony_ci if (ret < 0) 3765e5c12b0Sopenharmony_ci goto out; 3775e5c12b0Sopenharmony_ci 3785e5c12b0Sopenharmony_ci ret = blkid_do_fullprobe(pr); 3795e5c12b0Sopenharmony_ci if (ret < 0) 3805e5c12b0Sopenharmony_ci goto out; 3815e5c12b0Sopenharmony_ci 3825e5c12b0Sopenharmony_ci /* 3835e5c12b0Sopenharmony_ci * Blkid returns 1 for nothing found and 0 when it finds a signature, 3845e5c12b0Sopenharmony_ci * but we want the exact opposite, so reverse the return value here. 3855e5c12b0Sopenharmony_ci * 3865e5c12b0Sopenharmony_ci * In addition print some useful diagnostics about what actually is 3875e5c12b0Sopenharmony_ci * on the device. 3885e5c12b0Sopenharmony_ci */ 3895e5c12b0Sopenharmony_ci if (ret) { 3905e5c12b0Sopenharmony_ci ret = 0; 3915e5c12b0Sopenharmony_ci goto out; 3925e5c12b0Sopenharmony_ci } 3935e5c12b0Sopenharmony_ci 3945e5c12b0Sopenharmony_ci if (!blkid_probe_lookup_value(pr, "TYPE", &type, NULL)) { 3955e5c12b0Sopenharmony_ci MSG(0, "\t%s appears to contain an existing filesystem (%s).\n", 3965e5c12b0Sopenharmony_ci device, type); 3975e5c12b0Sopenharmony_ci } else if (!blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL)) { 3985e5c12b0Sopenharmony_ci MSG(0, "\t%s appears to contain a partition table (%s).\n", 3995e5c12b0Sopenharmony_ci device, type); 4005e5c12b0Sopenharmony_ci } else { 4015e5c12b0Sopenharmony_ci MSG(0, "\t%s appears to contain something weird according to blkid\n", 4025e5c12b0Sopenharmony_ci device); 4035e5c12b0Sopenharmony_ci } 4045e5c12b0Sopenharmony_ci ret = 1; 4055e5c12b0Sopenharmony_ciout: 4065e5c12b0Sopenharmony_ci if (pr) 4075e5c12b0Sopenharmony_ci blkid_free_probe(pr); 4085e5c12b0Sopenharmony_ci if (ret == -1) 4095e5c12b0Sopenharmony_ci MSG(0, "\tprobe of %s failed, cannot detect existing filesystem.\n", 4105e5c12b0Sopenharmony_ci device); 4115e5c12b0Sopenharmony_ci return ret; 4125e5c12b0Sopenharmony_ci} 4135e5c12b0Sopenharmony_ci 4145e5c12b0Sopenharmony_cistatic int f2fs_check_overwrite(void) 4155e5c12b0Sopenharmony_ci{ 4165e5c12b0Sopenharmony_ci int i; 4175e5c12b0Sopenharmony_ci 4185e5c12b0Sopenharmony_ci for (i = 0; i < c.ndevs; i++) 4195e5c12b0Sopenharmony_ci if (f2fs_dev_is_overwrite((char *)c.devices[i].path)) 4205e5c12b0Sopenharmony_ci return -1; 4215e5c12b0Sopenharmony_ci return 0; 4225e5c12b0Sopenharmony_ci} 4235e5c12b0Sopenharmony_ci 4245e5c12b0Sopenharmony_ci#else 4255e5c12b0Sopenharmony_ci 4265e5c12b0Sopenharmony_cistatic int f2fs_check_overwrite(void) 4275e5c12b0Sopenharmony_ci{ 4285e5c12b0Sopenharmony_ci return 0; 4295e5c12b0Sopenharmony_ci} 4305e5c12b0Sopenharmony_ci 4315e5c12b0Sopenharmony_ci#endif /* HAVE_LIBBLKID */ 4325e5c12b0Sopenharmony_ci 4335e5c12b0Sopenharmony_ciint main(int argc, char *argv[]) 4345e5c12b0Sopenharmony_ci{ 4355e5c12b0Sopenharmony_ci f2fs_init_configuration(); 4365e5c12b0Sopenharmony_ci 4375e5c12b0Sopenharmony_ci f2fs_parse_options(argc, argv); 4385e5c12b0Sopenharmony_ci 4395e5c12b0Sopenharmony_ci f2fs_show_info(); 4405e5c12b0Sopenharmony_ci 4415e5c12b0Sopenharmony_ci c.func = MKFS; 4425e5c12b0Sopenharmony_ci 4435e5c12b0Sopenharmony_ci if (f2fs_devs_are_umounted() < 0) { 4445e5c12b0Sopenharmony_ci if (errno != EBUSY) 4455e5c12b0Sopenharmony_ci MSG(0, "\tError: Not available on mounted device!\n"); 4465e5c12b0Sopenharmony_ci goto err_format; 4475e5c12b0Sopenharmony_ci } 4485e5c12b0Sopenharmony_ci 4495e5c12b0Sopenharmony_ci if (f2fs_get_device_info() < 0) 4505e5c12b0Sopenharmony_ci return -1; 4515e5c12b0Sopenharmony_ci 4525e5c12b0Sopenharmony_ci if (f2fs_check_overwrite()) { 4535e5c12b0Sopenharmony_ci char *zero_buf = NULL; 4545e5c12b0Sopenharmony_ci int i; 4555e5c12b0Sopenharmony_ci 4565e5c12b0Sopenharmony_ci if (!force_overwrite) { 4575e5c12b0Sopenharmony_ci MSG(0, "\tUse the -f option to force overwrite.\n"); 4585e5c12b0Sopenharmony_ci goto err_format; 4595e5c12b0Sopenharmony_ci } 4605e5c12b0Sopenharmony_ci zero_buf = calloc(F2FS_BLKSIZE, 1); 4615e5c12b0Sopenharmony_ci if (!zero_buf) { 4625e5c12b0Sopenharmony_ci MSG(0, "\tError: Fail to allocate zero buffer.\n"); 4635e5c12b0Sopenharmony_ci goto err_format; 4645e5c12b0Sopenharmony_ci } 4655e5c12b0Sopenharmony_ci /* wipe out other FS magics mostly first 4MB space */ 4665e5c12b0Sopenharmony_ci for (i = 0; i < 1024; i++) 4675e5c12b0Sopenharmony_ci if (dev_fill_block(zero_buf, i)) 4685e5c12b0Sopenharmony_ci break; 4695e5c12b0Sopenharmony_ci free(zero_buf); 4705e5c12b0Sopenharmony_ci if (i != 1024) { 4715e5c12b0Sopenharmony_ci MSG(0, "\tError: Fail to fill zeros till %d.\n", i); 4725e5c12b0Sopenharmony_ci goto err_format; 4735e5c12b0Sopenharmony_ci } 4745e5c12b0Sopenharmony_ci if (f2fs_fsync_device()) 4755e5c12b0Sopenharmony_ci goto err_format; 4765e5c12b0Sopenharmony_ci } 4775e5c12b0Sopenharmony_ci 4785e5c12b0Sopenharmony_ci if (f2fs_get_f2fs_info() < 0) 4795e5c12b0Sopenharmony_ci goto err_format; 4805e5c12b0Sopenharmony_ci 4815e5c12b0Sopenharmony_ci /* 4825e5c12b0Sopenharmony_ci * Some options are mandatory for host-managed 4835e5c12b0Sopenharmony_ci * zoned block devices. 4845e5c12b0Sopenharmony_ci */ 4855e5c12b0Sopenharmony_ci if (c.zoned_model != F2FS_ZONED_NONE && !c.zoned_mode) { 4865e5c12b0Sopenharmony_ci MSG(0, "\tError: zoned block device feature is required\n"); 4875e5c12b0Sopenharmony_ci goto err_format; 4885e5c12b0Sopenharmony_ci } 4895e5c12b0Sopenharmony_ci 4905e5c12b0Sopenharmony_ci if (c.zoned_mode && !c.trim) { 4915e5c12b0Sopenharmony_ci MSG(0, "\tError: Trim is required for zoned block devices\n"); 4925e5c12b0Sopenharmony_ci goto err_format; 4935e5c12b0Sopenharmony_ci } 4945e5c12b0Sopenharmony_ci 4955e5c12b0Sopenharmony_ci if (f2fs_format_device() < 0) 4965e5c12b0Sopenharmony_ci goto err_format; 4975e5c12b0Sopenharmony_ci 4985e5c12b0Sopenharmony_ci if (f2fs_finalize_device() < 0) 4995e5c12b0Sopenharmony_ci goto err_format; 5005e5c12b0Sopenharmony_ci 5015e5c12b0Sopenharmony_ci MSG(0, "Info: format successful\n"); 5025e5c12b0Sopenharmony_ci 5035e5c12b0Sopenharmony_ci return 0; 5045e5c12b0Sopenharmony_ci 5055e5c12b0Sopenharmony_cierr_format: 5065e5c12b0Sopenharmony_ci f2fs_release_sparse_resource(); 5075e5c12b0Sopenharmony_ci return -1; 5085e5c12b0Sopenharmony_ci} 509