1*59bfda1fSAndroid Build Coastguard Worker /**
2*59bfda1fSAndroid Build Coastguard Worker * f2fs_format.c
3*59bfda1fSAndroid Build Coastguard Worker *
4*59bfda1fSAndroid Build Coastguard Worker * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5*59bfda1fSAndroid Build Coastguard Worker * http://www.samsung.com/
6*59bfda1fSAndroid Build Coastguard Worker *
7*59bfda1fSAndroid Build Coastguard Worker * Dual licensed under the GPL or LGPL version 2 licenses.
8*59bfda1fSAndroid Build Coastguard Worker */
9*59bfda1fSAndroid Build Coastguard Worker #include <stdio.h>
10*59bfda1fSAndroid Build Coastguard Worker #include <stdlib.h>
11*59bfda1fSAndroid Build Coastguard Worker #include <fcntl.h>
12*59bfda1fSAndroid Build Coastguard Worker #include <string.h>
13*59bfda1fSAndroid Build Coastguard Worker #include <stdbool.h>
14*59bfda1fSAndroid Build Coastguard Worker #include <unistd.h>
15*59bfda1fSAndroid Build Coastguard Worker #include <sys/stat.h>
16*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_SYS_MOUNT_H
17*59bfda1fSAndroid Build Coastguard Worker #include <sys/mount.h>
18*59bfda1fSAndroid Build Coastguard Worker #endif
19*59bfda1fSAndroid Build Coastguard Worker #include <time.h>
20*59bfda1fSAndroid Build Coastguard Worker #include <errno.h>
21*59bfda1fSAndroid Build Coastguard Worker #include <getopt.h>
22*59bfda1fSAndroid Build Coastguard Worker
23*59bfda1fSAndroid Build Coastguard Worker #include <f2fs_fs.h>
24*59bfda1fSAndroid Build Coastguard Worker
25*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_LIBBLKID
26*59bfda1fSAndroid Build Coastguard Worker #include <blkid/blkid.h>
27*59bfda1fSAndroid Build Coastguard Worker #endif
28*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_UUID_UUID_H
29*59bfda1fSAndroid Build Coastguard Worker #include <uuid/uuid.h>
30*59bfda1fSAndroid Build Coastguard Worker #endif
31*59bfda1fSAndroid Build Coastguard Worker
32*59bfda1fSAndroid Build Coastguard Worker #include "quota.h"
33*59bfda1fSAndroid Build Coastguard Worker #include "f2fs_format_utils.h"
34*59bfda1fSAndroid Build Coastguard Worker
35*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_SYS_UTSNAME_H
36*59bfda1fSAndroid Build Coastguard Worker #include <sys/utsname.h>
37*59bfda1fSAndroid Build Coastguard Worker #endif
38*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_SPARSE_SPARSE_H
39*59bfda1fSAndroid Build Coastguard Worker #include <sparse/sparse.h>
40*59bfda1fSAndroid Build Coastguard Worker extern struct sparse_file *f2fs_sparse_file;
41*59bfda1fSAndroid Build Coastguard Worker #endif
42*59bfda1fSAndroid Build Coastguard Worker
43*59bfda1fSAndroid Build Coastguard Worker extern struct f2fs_configuration c;
44*59bfda1fSAndroid Build Coastguard Worker static int force_overwrite = 0;
45*59bfda1fSAndroid Build Coastguard Worker
46*59bfda1fSAndroid Build Coastguard Worker INIT_FEATURE_TABLE;
47*59bfda1fSAndroid Build Coastguard Worker
mkfs_usage()48*59bfda1fSAndroid Build Coastguard Worker static void mkfs_usage()
49*59bfda1fSAndroid Build Coastguard Worker {
50*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\nUsage: mkfs.f2fs [options] device [sectors]\n");
51*59bfda1fSAndroid Build Coastguard Worker MSG(0, "[options]:\n");
52*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -b filesystem block size [default:4096]\n");
53*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -c [device_name[@alias_filename]] up to 7 additional devices, except meta device\n");
54*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -d debug level [default:0]\n");
55*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -e [cold file ext list] e.g. \"mp3,gif,mov\"\n");
56*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -E [hot file ext list] e.g. \"db\"\n");
57*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -f force overwrite of the existing filesystem\n");
58*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -g add default options\n");
59*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -H support write hint\n");
60*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -i extended node bitmap, node ratio is 20%% by default\n");
61*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -l label\n");
62*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -U uuid\n");
63*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -m support zoned block device [default:0]\n");
64*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -o overprovision percentage [default:auto]\n");
65*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -O feature1[,feature2,...] e.g. \"encrypt\"\n");
66*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -C [encoding[:flag1,...]] Support casefolding with optional flags\n");
67*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -q quiet mode\n");
68*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -r set checkpointing seed (srand()) to 0\n");
69*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -R root_owner [default: 0:0]\n");
70*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -s # of segments per section [default:1]\n");
71*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -S sparse mode\n");
72*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -t 0: nodiscard, 1: discard [default:1]\n");
73*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -T timestamps\n");
74*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -w wanted sector size\n");
75*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -z # of sections per zone [default:1]\n");
76*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -V print the version number and exit\n");
77*59bfda1fSAndroid Build Coastguard Worker MSG(0, " -Z # of reserved sections [default:auto]\n");
78*59bfda1fSAndroid Build Coastguard Worker MSG(0, "sectors: number of sectors [default: determined by device size]\n");
79*59bfda1fSAndroid Build Coastguard Worker exit(1);
80*59bfda1fSAndroid Build Coastguard Worker }
81*59bfda1fSAndroid Build Coastguard Worker
f2fs_show_info()82*59bfda1fSAndroid Build Coastguard Worker static void f2fs_show_info()
83*59bfda1fSAndroid Build Coastguard Worker {
84*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\n F2FS-tools: mkfs.f2fs Ver: %s (%s)\n\n",
85*59bfda1fSAndroid Build Coastguard Worker F2FS_TOOLS_VERSION,
86*59bfda1fSAndroid Build Coastguard Worker F2FS_TOOLS_DATE);
87*59bfda1fSAndroid Build Coastguard Worker
88*59bfda1fSAndroid Build Coastguard Worker MSG(0, "Info: Debug level = %d\n", c.dbg_lv);
89*59bfda1fSAndroid Build Coastguard Worker if (c.extension_list[0])
90*59bfda1fSAndroid Build Coastguard Worker MSG(0, "Info: Add new cold file extension list\n");
91*59bfda1fSAndroid Build Coastguard Worker if (c.extension_list[1])
92*59bfda1fSAndroid Build Coastguard Worker MSG(0, "Info: Add new hot file extension list\n");
93*59bfda1fSAndroid Build Coastguard Worker
94*59bfda1fSAndroid Build Coastguard Worker if (strlen(c.vol_label))
95*59bfda1fSAndroid Build Coastguard Worker MSG(0, "Info: Label = %s\n", c.vol_label);
96*59bfda1fSAndroid Build Coastguard Worker MSG(0, "Info: Trim is %s\n", c.trim ? "enabled": "disabled");
97*59bfda1fSAndroid Build Coastguard Worker
98*59bfda1fSAndroid Build Coastguard Worker if (c.defset == CONF_ANDROID)
99*59bfda1fSAndroid Build Coastguard Worker MSG(0, "Info: Set conf for android\n");
100*59bfda1fSAndroid Build Coastguard Worker
101*59bfda1fSAndroid Build Coastguard Worker if (c.feature & F2FS_FEATURE_CASEFOLD)
102*59bfda1fSAndroid Build Coastguard Worker MSG(0, "Info: Enable %s with casefolding\n",
103*59bfda1fSAndroid Build Coastguard Worker f2fs_encoding2str(c.s_encoding));
104*59bfda1fSAndroid Build Coastguard Worker if (c.feature & F2FS_FEATURE_PRJQUOTA)
105*59bfda1fSAndroid Build Coastguard Worker MSG(0, "Info: Enable Project quota\n");
106*59bfda1fSAndroid Build Coastguard Worker
107*59bfda1fSAndroid Build Coastguard Worker if (c.feature & F2FS_FEATURE_COMPRESSION)
108*59bfda1fSAndroid Build Coastguard Worker MSG(0, "Info: Enable Compression\n");
109*59bfda1fSAndroid Build Coastguard Worker
110*59bfda1fSAndroid Build Coastguard Worker if (c.feature & F2FS_FEATURE_DEVICE_ALIAS)
111*59bfda1fSAndroid Build Coastguard Worker MSG(0, "Info: Enable device aliasing\n");
112*59bfda1fSAndroid Build Coastguard Worker }
113*59bfda1fSAndroid Build Coastguard Worker
114*59bfda1fSAndroid Build Coastguard Worker #if defined(ANDROID_TARGET) && defined(HAVE_SYS_UTSNAME_H)
kernel_version_over(unsigned int min_major,unsigned int min_minor)115*59bfda1fSAndroid Build Coastguard Worker static bool kernel_version_over(unsigned int min_major, unsigned int min_minor)
116*59bfda1fSAndroid Build Coastguard Worker {
117*59bfda1fSAndroid Build Coastguard Worker unsigned int major, minor;
118*59bfda1fSAndroid Build Coastguard Worker struct utsname uts;
119*59bfda1fSAndroid Build Coastguard Worker
120*59bfda1fSAndroid Build Coastguard Worker if ((uname(&uts) != 0) ||
121*59bfda1fSAndroid Build Coastguard Worker (sscanf(uts.release, "%u.%u", &major, &minor) != 2))
122*59bfda1fSAndroid Build Coastguard Worker return false;
123*59bfda1fSAndroid Build Coastguard Worker if (major > min_major)
124*59bfda1fSAndroid Build Coastguard Worker return true;
125*59bfda1fSAndroid Build Coastguard Worker if (major == min_major && minor >= min_minor)
126*59bfda1fSAndroid Build Coastguard Worker return true;
127*59bfda1fSAndroid Build Coastguard Worker return false;
128*59bfda1fSAndroid Build Coastguard Worker }
129*59bfda1fSAndroid Build Coastguard Worker #else
kernel_version_over(unsigned int UNUSED (min_major),unsigned int UNUSED (min_minor))130*59bfda1fSAndroid Build Coastguard Worker static bool kernel_version_over(unsigned int UNUSED(min_major),
131*59bfda1fSAndroid Build Coastguard Worker unsigned int UNUSED(min_minor))
132*59bfda1fSAndroid Build Coastguard Worker {
133*59bfda1fSAndroid Build Coastguard Worker return false;
134*59bfda1fSAndroid Build Coastguard Worker }
135*59bfda1fSAndroid Build Coastguard Worker #endif
136*59bfda1fSAndroid Build Coastguard Worker
add_default_options(void)137*59bfda1fSAndroid Build Coastguard Worker static void add_default_options(void)
138*59bfda1fSAndroid Build Coastguard Worker {
139*59bfda1fSAndroid Build Coastguard Worker switch (c.defset) {
140*59bfda1fSAndroid Build Coastguard Worker case CONF_ANDROID:
141*59bfda1fSAndroid Build Coastguard Worker /* -d1 -f -w 4096 -R 0:0 */
142*59bfda1fSAndroid Build Coastguard Worker c.dbg_lv = 1;
143*59bfda1fSAndroid Build Coastguard Worker force_overwrite = 1;
144*59bfda1fSAndroid Build Coastguard Worker c.wanted_sector_size = F2FS_BLKSIZE;
145*59bfda1fSAndroid Build Coastguard Worker c.root_uid = c.root_gid = 0;
146*59bfda1fSAndroid Build Coastguard Worker
147*59bfda1fSAndroid Build Coastguard Worker /* RO doesn't need any other features */
148*59bfda1fSAndroid Build Coastguard Worker if (c.feature & F2FS_FEATURE_RO)
149*59bfda1fSAndroid Build Coastguard Worker return;
150*59bfda1fSAndroid Build Coastguard Worker
151*59bfda1fSAndroid Build Coastguard Worker /* -O encrypt -O project_quota,extra_attr,{quota} -O verity */
152*59bfda1fSAndroid Build Coastguard Worker c.feature |= F2FS_FEATURE_ENCRYPT;
153*59bfda1fSAndroid Build Coastguard Worker if (!kernel_version_over(4, 14))
154*59bfda1fSAndroid Build Coastguard Worker c.feature |= F2FS_FEATURE_QUOTA_INO;
155*59bfda1fSAndroid Build Coastguard Worker c.feature |= F2FS_FEATURE_PRJQUOTA;
156*59bfda1fSAndroid Build Coastguard Worker c.feature |= F2FS_FEATURE_EXTRA_ATTR;
157*59bfda1fSAndroid Build Coastguard Worker c.feature |= F2FS_FEATURE_VERITY;
158*59bfda1fSAndroid Build Coastguard Worker break;
159*59bfda1fSAndroid Build Coastguard Worker }
160*59bfda1fSAndroid Build Coastguard Worker #ifdef CONF_CASEFOLD
161*59bfda1fSAndroid Build Coastguard Worker c.s_encoding = F2FS_ENC_UTF8_12_1;
162*59bfda1fSAndroid Build Coastguard Worker c.feature |= F2FS_FEATURE_CASEFOLD;
163*59bfda1fSAndroid Build Coastguard Worker #endif
164*59bfda1fSAndroid Build Coastguard Worker #ifdef CONF_PROJID
165*59bfda1fSAndroid Build Coastguard Worker c.feature |= F2FS_FEATURE_QUOTA_INO;
166*59bfda1fSAndroid Build Coastguard Worker c.feature |= F2FS_FEATURE_PRJQUOTA;
167*59bfda1fSAndroid Build Coastguard Worker c.feature |= F2FS_FEATURE_EXTRA_ATTR;
168*59bfda1fSAndroid Build Coastguard Worker #endif
169*59bfda1fSAndroid Build Coastguard Worker
170*59bfda1fSAndroid Build Coastguard Worker if (c.feature & F2FS_FEATURE_QUOTA_INO)
171*59bfda1fSAndroid Build Coastguard Worker c.quota_bits = QUOTA_USR_BIT | QUOTA_GRP_BIT;
172*59bfda1fSAndroid Build Coastguard Worker if (c.feature & F2FS_FEATURE_PRJQUOTA) {
173*59bfda1fSAndroid Build Coastguard Worker c.feature |= F2FS_FEATURE_QUOTA_INO;
174*59bfda1fSAndroid Build Coastguard Worker c.quota_bits |= QUOTA_PRJ_BIT;
175*59bfda1fSAndroid Build Coastguard Worker }
176*59bfda1fSAndroid Build Coastguard Worker }
177*59bfda1fSAndroid Build Coastguard Worker
f2fs_parse_options(int argc,char * argv[])178*59bfda1fSAndroid Build Coastguard Worker static void f2fs_parse_options(int argc, char *argv[])
179*59bfda1fSAndroid Build Coastguard Worker {
180*59bfda1fSAndroid Build Coastguard Worker static const char *option_string = "qa:b:c:C:d:e:E:g:hHil:mo:O:rR:s:S:z:t:T:U:Vfw:Z:";
181*59bfda1fSAndroid Build Coastguard Worker static const struct option long_opts[] = {
182*59bfda1fSAndroid Build Coastguard Worker { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' },
183*59bfda1fSAndroid Build Coastguard Worker { .name = NULL, .has_arg = 0, .flag = NULL, .val = 0 }
184*59bfda1fSAndroid Build Coastguard Worker };
185*59bfda1fSAndroid Build Coastguard Worker int32_t option=0;
186*59bfda1fSAndroid Build Coastguard Worker int val;
187*59bfda1fSAndroid Build Coastguard Worker char *token;
188*59bfda1fSAndroid Build Coastguard Worker int dev_num;
189*59bfda1fSAndroid Build Coastguard Worker
190*59bfda1fSAndroid Build Coastguard Worker while ((option = getopt_long(argc,argv,option_string,long_opts,NULL)) != EOF) {
191*59bfda1fSAndroid Build Coastguard Worker switch (option) {
192*59bfda1fSAndroid Build Coastguard Worker case 'q':
193*59bfda1fSAndroid Build Coastguard Worker c.dbg_lv = -1;
194*59bfda1fSAndroid Build Coastguard Worker break;
195*59bfda1fSAndroid Build Coastguard Worker case 'a':
196*59bfda1fSAndroid Build Coastguard Worker MSG(0, "Info: heap allocation is deprecated\n");
197*59bfda1fSAndroid Build Coastguard Worker break;
198*59bfda1fSAndroid Build Coastguard Worker case 'b':
199*59bfda1fSAndroid Build Coastguard Worker c.blksize = atoi(optarg);
200*59bfda1fSAndroid Build Coastguard Worker c.blksize_bits = log_base_2(c.blksize);
201*59bfda1fSAndroid Build Coastguard Worker c.sectors_per_blk = DEFAULT_SECTORS_PER_BLOCK;
202*59bfda1fSAndroid Build Coastguard Worker if ((1 << c.blksize_bits) != c.blksize) {
203*59bfda1fSAndroid Build Coastguard Worker MSG(0, "Error: Block size must be power of 2");
204*59bfda1fSAndroid Build Coastguard Worker mkfs_usage();
205*59bfda1fSAndroid Build Coastguard Worker }
206*59bfda1fSAndroid Build Coastguard Worker break;
207*59bfda1fSAndroid Build Coastguard Worker case 'c':
208*59bfda1fSAndroid Build Coastguard Worker dev_num = c.ndevs;
209*59bfda1fSAndroid Build Coastguard Worker
210*59bfda1fSAndroid Build Coastguard Worker if (dev_num >= MAX_DEVICES) {
211*59bfda1fSAndroid Build Coastguard Worker MSG(0, "Error: Too many devices\n");
212*59bfda1fSAndroid Build Coastguard Worker mkfs_usage();
213*59bfda1fSAndroid Build Coastguard Worker }
214*59bfda1fSAndroid Build Coastguard Worker
215*59bfda1fSAndroid Build Coastguard Worker token = strtok(optarg, "@");
216*59bfda1fSAndroid Build Coastguard Worker if (strlen(token) > MAX_PATH_LEN) {
217*59bfda1fSAndroid Build Coastguard Worker MSG(0, "Error: device path should be equal or "
218*59bfda1fSAndroid Build Coastguard Worker "less than %d characters\n",
219*59bfda1fSAndroid Build Coastguard Worker MAX_PATH_LEN);
220*59bfda1fSAndroid Build Coastguard Worker mkfs_usage();
221*59bfda1fSAndroid Build Coastguard Worker }
222*59bfda1fSAndroid Build Coastguard Worker c.devices[dev_num].path = strdup(token);
223*59bfda1fSAndroid Build Coastguard Worker token = strtok(NULL, "");
224*59bfda1fSAndroid Build Coastguard Worker if (token) {
225*59bfda1fSAndroid Build Coastguard Worker if (strlen(token) > MAX_PATH_LEN) {
226*59bfda1fSAndroid Build Coastguard Worker MSG(0, "Error: alias_filename should "
227*59bfda1fSAndroid Build Coastguard Worker "be equal or less than %d "
228*59bfda1fSAndroid Build Coastguard Worker "characters\n", MAX_PATH_LEN);
229*59bfda1fSAndroid Build Coastguard Worker mkfs_usage();
230*59bfda1fSAndroid Build Coastguard Worker }
231*59bfda1fSAndroid Build Coastguard Worker if (strchr(token, '/')) {
232*59bfda1fSAndroid Build Coastguard Worker MSG(0, "Error: alias_filename has "
233*59bfda1fSAndroid Build Coastguard Worker "invalid '/' character\n");
234*59bfda1fSAndroid Build Coastguard Worker mkfs_usage();
235*59bfda1fSAndroid Build Coastguard Worker }
236*59bfda1fSAndroid Build Coastguard Worker c.devices[dev_num].alias_filename =
237*59bfda1fSAndroid Build Coastguard Worker strdup(token);
238*59bfda1fSAndroid Build Coastguard Worker if (!c.aliased_devices)
239*59bfda1fSAndroid Build Coastguard Worker c.feature |= F2FS_FEATURE_DEVICE_ALIAS;
240*59bfda1fSAndroid Build Coastguard Worker c.aliased_devices++;
241*59bfda1fSAndroid Build Coastguard Worker }
242*59bfda1fSAndroid Build Coastguard Worker c.ndevs++;
243*59bfda1fSAndroid Build Coastguard Worker break;
244*59bfda1fSAndroid Build Coastguard Worker case 'd':
245*59bfda1fSAndroid Build Coastguard Worker c.dbg_lv = atoi(optarg);
246*59bfda1fSAndroid Build Coastguard Worker break;
247*59bfda1fSAndroid Build Coastguard Worker case 'e':
248*59bfda1fSAndroid Build Coastguard Worker c.extension_list[0] = strdup(optarg);
249*59bfda1fSAndroid Build Coastguard Worker break;
250*59bfda1fSAndroid Build Coastguard Worker case 'E':
251*59bfda1fSAndroid Build Coastguard Worker c.extension_list[1] = strdup(optarg);
252*59bfda1fSAndroid Build Coastguard Worker break;
253*59bfda1fSAndroid Build Coastguard Worker case 'g':
254*59bfda1fSAndroid Build Coastguard Worker if (!strcmp(optarg, "android"))
255*59bfda1fSAndroid Build Coastguard Worker c.defset = CONF_ANDROID;
256*59bfda1fSAndroid Build Coastguard Worker break;
257*59bfda1fSAndroid Build Coastguard Worker case 'h':
258*59bfda1fSAndroid Build Coastguard Worker mkfs_usage();
259*59bfda1fSAndroid Build Coastguard Worker break;
260*59bfda1fSAndroid Build Coastguard Worker case 'H':
261*59bfda1fSAndroid Build Coastguard Worker c.need_whint = true;
262*59bfda1fSAndroid Build Coastguard Worker c.whint = WRITE_LIFE_NOT_SET;
263*59bfda1fSAndroid Build Coastguard Worker break;
264*59bfda1fSAndroid Build Coastguard Worker case 'i':
265*59bfda1fSAndroid Build Coastguard Worker c.large_nat_bitmap = 1;
266*59bfda1fSAndroid Build Coastguard Worker break;
267*59bfda1fSAndroid Build Coastguard Worker case 'l': /*v: volume label */
268*59bfda1fSAndroid Build Coastguard Worker if (strlen(optarg) > 512) {
269*59bfda1fSAndroid Build Coastguard Worker MSG(0, "Error: Volume Label should be less than "
270*59bfda1fSAndroid Build Coastguard Worker "512 characters\n");
271*59bfda1fSAndroid Build Coastguard Worker mkfs_usage();
272*59bfda1fSAndroid Build Coastguard Worker }
273*59bfda1fSAndroid Build Coastguard Worker c.vol_label = optarg;
274*59bfda1fSAndroid Build Coastguard Worker break;
275*59bfda1fSAndroid Build Coastguard Worker case 'm':
276*59bfda1fSAndroid Build Coastguard Worker c.zoned_mode = 1;
277*59bfda1fSAndroid Build Coastguard Worker break;
278*59bfda1fSAndroid Build Coastguard Worker case 'o':
279*59bfda1fSAndroid Build Coastguard Worker c.overprovision = atof(optarg);
280*59bfda1fSAndroid Build Coastguard Worker break;
281*59bfda1fSAndroid Build Coastguard Worker case 'O':
282*59bfda1fSAndroid Build Coastguard Worker if (parse_feature(feature_table, optarg))
283*59bfda1fSAndroid Build Coastguard Worker mkfs_usage();
284*59bfda1fSAndroid Build Coastguard Worker break;
285*59bfda1fSAndroid Build Coastguard Worker case 'r':
286*59bfda1fSAndroid Build Coastguard Worker c.fake_seed = 1;
287*59bfda1fSAndroid Build Coastguard Worker break;
288*59bfda1fSAndroid Build Coastguard Worker case 'R':
289*59bfda1fSAndroid Build Coastguard Worker if (parse_root_owner(optarg, &c.root_uid, &c.root_gid))
290*59bfda1fSAndroid Build Coastguard Worker mkfs_usage();
291*59bfda1fSAndroid Build Coastguard Worker break;
292*59bfda1fSAndroid Build Coastguard Worker case 's':
293*59bfda1fSAndroid Build Coastguard Worker c.segs_per_sec = atoi(optarg);
294*59bfda1fSAndroid Build Coastguard Worker break;
295*59bfda1fSAndroid Build Coastguard Worker case 'S':
296*59bfda1fSAndroid Build Coastguard Worker c.device_size = atoll(optarg);
297*59bfda1fSAndroid Build Coastguard Worker c.device_size &= (~((uint64_t)(F2FS_BLKSIZE - 1)));
298*59bfda1fSAndroid Build Coastguard Worker c.sparse_mode = 1;
299*59bfda1fSAndroid Build Coastguard Worker break;
300*59bfda1fSAndroid Build Coastguard Worker case 'z':
301*59bfda1fSAndroid Build Coastguard Worker c.secs_per_zone = atoi(optarg);
302*59bfda1fSAndroid Build Coastguard Worker break;
303*59bfda1fSAndroid Build Coastguard Worker case 't':
304*59bfda1fSAndroid Build Coastguard Worker c.trim = atoi(optarg);
305*59bfda1fSAndroid Build Coastguard Worker break;
306*59bfda1fSAndroid Build Coastguard Worker case 'T':
307*59bfda1fSAndroid Build Coastguard Worker c.fixed_time = strtoul(optarg, NULL, 0);
308*59bfda1fSAndroid Build Coastguard Worker break;
309*59bfda1fSAndroid Build Coastguard Worker case 'U':
310*59bfda1fSAndroid Build Coastguard Worker c.vol_uuid = strdup(optarg);
311*59bfda1fSAndroid Build Coastguard Worker break;
312*59bfda1fSAndroid Build Coastguard Worker case 'f':
313*59bfda1fSAndroid Build Coastguard Worker force_overwrite = 1;
314*59bfda1fSAndroid Build Coastguard Worker break;
315*59bfda1fSAndroid Build Coastguard Worker case 'w':
316*59bfda1fSAndroid Build Coastguard Worker c.wanted_sector_size = atoi(optarg);
317*59bfda1fSAndroid Build Coastguard Worker break;
318*59bfda1fSAndroid Build Coastguard Worker case 'V':
319*59bfda1fSAndroid Build Coastguard Worker show_version("mkfs.f2fs");
320*59bfda1fSAndroid Build Coastguard Worker exit(0);
321*59bfda1fSAndroid Build Coastguard Worker case 'C':
322*59bfda1fSAndroid Build Coastguard Worker token = strtok(optarg, ":");
323*59bfda1fSAndroid Build Coastguard Worker val = f2fs_str2encoding(token);
324*59bfda1fSAndroid Build Coastguard Worker if (val < 0) {
325*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\tError: Unknown encoding %s\n", token);
326*59bfda1fSAndroid Build Coastguard Worker mkfs_usage();
327*59bfda1fSAndroid Build Coastguard Worker }
328*59bfda1fSAndroid Build Coastguard Worker c.s_encoding = val;
329*59bfda1fSAndroid Build Coastguard Worker token = strtok(NULL, "");
330*59bfda1fSAndroid Build Coastguard Worker val = f2fs_str2encoding_flags(&token, &c.s_encoding_flags);
331*59bfda1fSAndroid Build Coastguard Worker if (val) {
332*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\tError: Unknown flag %s\n",token);
333*59bfda1fSAndroid Build Coastguard Worker mkfs_usage();
334*59bfda1fSAndroid Build Coastguard Worker }
335*59bfda1fSAndroid Build Coastguard Worker c.feature |= F2FS_FEATURE_CASEFOLD;
336*59bfda1fSAndroid Build Coastguard Worker break;
337*59bfda1fSAndroid Build Coastguard Worker case 'Z':
338*59bfda1fSAndroid Build Coastguard Worker c.conf_reserved_sections = atoi(optarg);
339*59bfda1fSAndroid Build Coastguard Worker break;
340*59bfda1fSAndroid Build Coastguard Worker default:
341*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\tError: Unknown option %c\n",option);
342*59bfda1fSAndroid Build Coastguard Worker mkfs_usage();
343*59bfda1fSAndroid Build Coastguard Worker break;
344*59bfda1fSAndroid Build Coastguard Worker }
345*59bfda1fSAndroid Build Coastguard Worker }
346*59bfda1fSAndroid Build Coastguard Worker
347*59bfda1fSAndroid Build Coastguard Worker add_default_options();
348*59bfda1fSAndroid Build Coastguard Worker
349*59bfda1fSAndroid Build Coastguard Worker if (!(c.feature & F2FS_FEATURE_EXTRA_ATTR)) {
350*59bfda1fSAndroid Build Coastguard Worker if (c.feature & F2FS_FEATURE_PRJQUOTA) {
351*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\tInfo: project quota feature should always be "
352*59bfda1fSAndroid Build Coastguard Worker "enabled with extra attr feature\n");
353*59bfda1fSAndroid Build Coastguard Worker exit(1);
354*59bfda1fSAndroid Build Coastguard Worker }
355*59bfda1fSAndroid Build Coastguard Worker if (c.feature & F2FS_FEATURE_INODE_CHKSUM) {
356*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\tInfo: inode checksum feature should always be "
357*59bfda1fSAndroid Build Coastguard Worker "enabled with extra attr feature\n");
358*59bfda1fSAndroid Build Coastguard Worker exit(1);
359*59bfda1fSAndroid Build Coastguard Worker }
360*59bfda1fSAndroid Build Coastguard Worker if (c.feature & F2FS_FEATURE_FLEXIBLE_INLINE_XATTR) {
361*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\tInfo: flexible inline xattr feature should always be "
362*59bfda1fSAndroid Build Coastguard Worker "enabled with extra attr feature\n");
363*59bfda1fSAndroid Build Coastguard Worker exit(1);
364*59bfda1fSAndroid Build Coastguard Worker }
365*59bfda1fSAndroid Build Coastguard Worker if (c.feature & F2FS_FEATURE_INODE_CRTIME) {
366*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\tInfo: inode crtime feature should always be "
367*59bfda1fSAndroid Build Coastguard Worker "enabled with extra attr feature\n");
368*59bfda1fSAndroid Build Coastguard Worker exit(1);
369*59bfda1fSAndroid Build Coastguard Worker }
370*59bfda1fSAndroid Build Coastguard Worker if (c.feature & F2FS_FEATURE_COMPRESSION) {
371*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\tInfo: compression feature should always be "
372*59bfda1fSAndroid Build Coastguard Worker "enabled with extra attr feature\n");
373*59bfda1fSAndroid Build Coastguard Worker exit(1);
374*59bfda1fSAndroid Build Coastguard Worker }
375*59bfda1fSAndroid Build Coastguard Worker }
376*59bfda1fSAndroid Build Coastguard Worker
377*59bfda1fSAndroid Build Coastguard Worker if (optind >= argc) {
378*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\tError: Device not specified\n");
379*59bfda1fSAndroid Build Coastguard Worker mkfs_usage();
380*59bfda1fSAndroid Build Coastguard Worker }
381*59bfda1fSAndroid Build Coastguard Worker
382*59bfda1fSAndroid Build Coastguard Worker /* [0] : META, [1 to MAX_DEVICES - 1] : NODE/DATA */
383*59bfda1fSAndroid Build Coastguard Worker c.devices[0].path = strdup(argv[optind]);
384*59bfda1fSAndroid Build Coastguard Worker
385*59bfda1fSAndroid Build Coastguard Worker if ((optind + 1) < argc) {
386*59bfda1fSAndroid Build Coastguard Worker if (c.ndevs > 1) {
387*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\tError: Not support custom size on multi-devs.\n");
388*59bfda1fSAndroid Build Coastguard Worker mkfs_usage();
389*59bfda1fSAndroid Build Coastguard Worker }
390*59bfda1fSAndroid Build Coastguard Worker c.wanted_total_sectors = atoll(argv[optind+1]);
391*59bfda1fSAndroid Build Coastguard Worker }
392*59bfda1fSAndroid Build Coastguard Worker
393*59bfda1fSAndroid Build Coastguard Worker if (c.sparse_mode)
394*59bfda1fSAndroid Build Coastguard Worker c.trim = 0;
395*59bfda1fSAndroid Build Coastguard Worker
396*59bfda1fSAndroid Build Coastguard Worker if (c.zoned_mode)
397*59bfda1fSAndroid Build Coastguard Worker c.feature |= F2FS_FEATURE_BLKZONED;
398*59bfda1fSAndroid Build Coastguard Worker check_block_struct_sizes();
399*59bfda1fSAndroid Build Coastguard Worker }
400*59bfda1fSAndroid Build Coastguard Worker
401*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_LIBBLKID
f2fs_dev_is_overwrite(const char * device)402*59bfda1fSAndroid Build Coastguard Worker static int f2fs_dev_is_overwrite(const char *device)
403*59bfda1fSAndroid Build Coastguard Worker {
404*59bfda1fSAndroid Build Coastguard Worker const char *type;
405*59bfda1fSAndroid Build Coastguard Worker blkid_probe pr = NULL;
406*59bfda1fSAndroid Build Coastguard Worker int ret = -1;
407*59bfda1fSAndroid Build Coastguard Worker
408*59bfda1fSAndroid Build Coastguard Worker if (!device || !*device)
409*59bfda1fSAndroid Build Coastguard Worker return 0;
410*59bfda1fSAndroid Build Coastguard Worker
411*59bfda1fSAndroid Build Coastguard Worker pr = blkid_new_probe_from_filename(device);
412*59bfda1fSAndroid Build Coastguard Worker if (!pr)
413*59bfda1fSAndroid Build Coastguard Worker goto out;
414*59bfda1fSAndroid Build Coastguard Worker
415*59bfda1fSAndroid Build Coastguard Worker ret = blkid_probe_enable_partitions(pr, 1);
416*59bfda1fSAndroid Build Coastguard Worker if (ret < 0)
417*59bfda1fSAndroid Build Coastguard Worker goto out;
418*59bfda1fSAndroid Build Coastguard Worker
419*59bfda1fSAndroid Build Coastguard Worker ret = blkid_do_fullprobe(pr);
420*59bfda1fSAndroid Build Coastguard Worker if (ret < 0)
421*59bfda1fSAndroid Build Coastguard Worker goto out;
422*59bfda1fSAndroid Build Coastguard Worker
423*59bfda1fSAndroid Build Coastguard Worker /*
424*59bfda1fSAndroid Build Coastguard Worker * Blkid returns 1 for nothing found and 0 when it finds a signature,
425*59bfda1fSAndroid Build Coastguard Worker * but we want the exact opposite, so reverse the return value here.
426*59bfda1fSAndroid Build Coastguard Worker *
427*59bfda1fSAndroid Build Coastguard Worker * In addition print some useful diagnostics about what actually is
428*59bfda1fSAndroid Build Coastguard Worker * on the device.
429*59bfda1fSAndroid Build Coastguard Worker */
430*59bfda1fSAndroid Build Coastguard Worker if (ret) {
431*59bfda1fSAndroid Build Coastguard Worker ret = 0;
432*59bfda1fSAndroid Build Coastguard Worker goto out;
433*59bfda1fSAndroid Build Coastguard Worker }
434*59bfda1fSAndroid Build Coastguard Worker
435*59bfda1fSAndroid Build Coastguard Worker if (!blkid_probe_lookup_value(pr, "TYPE", &type, NULL)) {
436*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\t%s appears to contain an existing filesystem (%s).\n",
437*59bfda1fSAndroid Build Coastguard Worker device, type);
438*59bfda1fSAndroid Build Coastguard Worker } else if (!blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL)) {
439*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\t%s appears to contain a partition table (%s).\n",
440*59bfda1fSAndroid Build Coastguard Worker device, type);
441*59bfda1fSAndroid Build Coastguard Worker } else {
442*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\t%s appears to contain something weird according to blkid\n",
443*59bfda1fSAndroid Build Coastguard Worker device);
444*59bfda1fSAndroid Build Coastguard Worker }
445*59bfda1fSAndroid Build Coastguard Worker ret = 1;
446*59bfda1fSAndroid Build Coastguard Worker out:
447*59bfda1fSAndroid Build Coastguard Worker if (pr)
448*59bfda1fSAndroid Build Coastguard Worker blkid_free_probe(pr);
449*59bfda1fSAndroid Build Coastguard Worker if (ret == -1)
450*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\tprobe of %s failed, cannot detect existing filesystem.\n",
451*59bfda1fSAndroid Build Coastguard Worker device);
452*59bfda1fSAndroid Build Coastguard Worker return ret;
453*59bfda1fSAndroid Build Coastguard Worker }
454*59bfda1fSAndroid Build Coastguard Worker
f2fs_check_overwrite(void)455*59bfda1fSAndroid Build Coastguard Worker static int f2fs_check_overwrite(void)
456*59bfda1fSAndroid Build Coastguard Worker {
457*59bfda1fSAndroid Build Coastguard Worker int i;
458*59bfda1fSAndroid Build Coastguard Worker
459*59bfda1fSAndroid Build Coastguard Worker for (i = 0; i < c.ndevs; i++)
460*59bfda1fSAndroid Build Coastguard Worker if (f2fs_dev_is_overwrite((char *)c.devices[i].path))
461*59bfda1fSAndroid Build Coastguard Worker return -1;
462*59bfda1fSAndroid Build Coastguard Worker return 0;
463*59bfda1fSAndroid Build Coastguard Worker }
464*59bfda1fSAndroid Build Coastguard Worker
465*59bfda1fSAndroid Build Coastguard Worker #else
466*59bfda1fSAndroid Build Coastguard Worker
f2fs_check_overwrite(void)467*59bfda1fSAndroid Build Coastguard Worker static int f2fs_check_overwrite(void)
468*59bfda1fSAndroid Build Coastguard Worker {
469*59bfda1fSAndroid Build Coastguard Worker return 0;
470*59bfda1fSAndroid Build Coastguard Worker }
471*59bfda1fSAndroid Build Coastguard Worker
472*59bfda1fSAndroid Build Coastguard Worker #endif /* HAVE_LIBBLKID */
473*59bfda1fSAndroid Build Coastguard Worker
main(int argc,char * argv[])474*59bfda1fSAndroid Build Coastguard Worker int main(int argc, char *argv[])
475*59bfda1fSAndroid Build Coastguard Worker {
476*59bfda1fSAndroid Build Coastguard Worker int ret;
477*59bfda1fSAndroid Build Coastguard Worker
478*59bfda1fSAndroid Build Coastguard Worker f2fs_init_configuration();
479*59bfda1fSAndroid Build Coastguard Worker
480*59bfda1fSAndroid Build Coastguard Worker f2fs_parse_options(argc, argv);
481*59bfda1fSAndroid Build Coastguard Worker
482*59bfda1fSAndroid Build Coastguard Worker f2fs_show_info();
483*59bfda1fSAndroid Build Coastguard Worker
484*59bfda1fSAndroid Build Coastguard Worker c.func = MKFS;
485*59bfda1fSAndroid Build Coastguard Worker
486*59bfda1fSAndroid Build Coastguard Worker ret = f2fs_devs_are_umounted();
487*59bfda1fSAndroid Build Coastguard Worker if (ret) {
488*59bfda1fSAndroid Build Coastguard Worker if (ret != -EBUSY)
489*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\tError: Not available on mounted device!\n");
490*59bfda1fSAndroid Build Coastguard Worker goto err_format;
491*59bfda1fSAndroid Build Coastguard Worker }
492*59bfda1fSAndroid Build Coastguard Worker
493*59bfda1fSAndroid Build Coastguard Worker if (f2fs_get_device_info() < 0)
494*59bfda1fSAndroid Build Coastguard Worker return -1;
495*59bfda1fSAndroid Build Coastguard Worker
496*59bfda1fSAndroid Build Coastguard Worker if (f2fs_check_overwrite()) {
497*59bfda1fSAndroid Build Coastguard Worker char *zero_buf = NULL;
498*59bfda1fSAndroid Build Coastguard Worker int i;
499*59bfda1fSAndroid Build Coastguard Worker
500*59bfda1fSAndroid Build Coastguard Worker if (!force_overwrite) {
501*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\tUse the -f option to force overwrite.\n");
502*59bfda1fSAndroid Build Coastguard Worker goto err_format;
503*59bfda1fSAndroid Build Coastguard Worker }
504*59bfda1fSAndroid Build Coastguard Worker zero_buf = calloc(F2FS_BLKSIZE, 1);
505*59bfda1fSAndroid Build Coastguard Worker if (!zero_buf) {
506*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\tError: Fail to allocate zero buffer.\n");
507*59bfda1fSAndroid Build Coastguard Worker goto err_format;
508*59bfda1fSAndroid Build Coastguard Worker }
509*59bfda1fSAndroid Build Coastguard Worker /* wipe out other FS magics mostly first 4MB space */
510*59bfda1fSAndroid Build Coastguard Worker for (i = 0; i < 1024; i++)
511*59bfda1fSAndroid Build Coastguard Worker if (dev_fill_block(zero_buf, i, WRITE_LIFE_NONE))
512*59bfda1fSAndroid Build Coastguard Worker break;
513*59bfda1fSAndroid Build Coastguard Worker free(zero_buf);
514*59bfda1fSAndroid Build Coastguard Worker if (i != 1024) {
515*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\tError: Fail to fill zeros till %d.\n", i);
516*59bfda1fSAndroid Build Coastguard Worker goto err_format;
517*59bfda1fSAndroid Build Coastguard Worker }
518*59bfda1fSAndroid Build Coastguard Worker if (f2fs_fsync_device())
519*59bfda1fSAndroid Build Coastguard Worker goto err_format;
520*59bfda1fSAndroid Build Coastguard Worker }
521*59bfda1fSAndroid Build Coastguard Worker
522*59bfda1fSAndroid Build Coastguard Worker if (f2fs_get_f2fs_info() < 0)
523*59bfda1fSAndroid Build Coastguard Worker goto err_format;
524*59bfda1fSAndroid Build Coastguard Worker
525*59bfda1fSAndroid Build Coastguard Worker /*
526*59bfda1fSAndroid Build Coastguard Worker * Some options are mandatory for host-managed
527*59bfda1fSAndroid Build Coastguard Worker * zoned block devices.
528*59bfda1fSAndroid Build Coastguard Worker */
529*59bfda1fSAndroid Build Coastguard Worker if (c.zoned_model != F2FS_ZONED_NONE && !c.zoned_mode) {
530*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\tError: zoned block device feature is required\n");
531*59bfda1fSAndroid Build Coastguard Worker goto err_format;
532*59bfda1fSAndroid Build Coastguard Worker }
533*59bfda1fSAndroid Build Coastguard Worker
534*59bfda1fSAndroid Build Coastguard Worker if (c.zoned_mode && !c.trim) {
535*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\tError: Trim is required for zoned block devices\n");
536*59bfda1fSAndroid Build Coastguard Worker goto err_format;
537*59bfda1fSAndroid Build Coastguard Worker }
538*59bfda1fSAndroid Build Coastguard Worker
539*59bfda1fSAndroid Build Coastguard Worker if (c.conf_reserved_sections && !c.zoned_mode) {
540*59bfda1fSAndroid Build Coastguard Worker MSG(0, "\tError: Reserved area can't be specified on non zoned device\n");
541*59bfda1fSAndroid Build Coastguard Worker goto err_format;
542*59bfda1fSAndroid Build Coastguard Worker }
543*59bfda1fSAndroid Build Coastguard Worker
544*59bfda1fSAndroid Build Coastguard Worker if (f2fs_format_device() < 0)
545*59bfda1fSAndroid Build Coastguard Worker goto err_format;
546*59bfda1fSAndroid Build Coastguard Worker
547*59bfda1fSAndroid Build Coastguard Worker if (f2fs_finalize_device() < 0)
548*59bfda1fSAndroid Build Coastguard Worker goto err_format;
549*59bfda1fSAndroid Build Coastguard Worker
550*59bfda1fSAndroid Build Coastguard Worker MSG(0, "Info: format successful\n");
551*59bfda1fSAndroid Build Coastguard Worker
552*59bfda1fSAndroid Build Coastguard Worker return 0;
553*59bfda1fSAndroid Build Coastguard Worker
554*59bfda1fSAndroid Build Coastguard Worker err_format:
555*59bfda1fSAndroid Build Coastguard Worker f2fs_release_sparse_resource();
556*59bfda1fSAndroid Build Coastguard Worker return -1;
557*59bfda1fSAndroid Build Coastguard Worker }
558