1*59bfda1fSAndroid Build Coastguard Worker /**
2*59bfda1fSAndroid Build Coastguard Worker * sload.c
3*59bfda1fSAndroid Build Coastguard Worker *
4*59bfda1fSAndroid Build Coastguard Worker * Copyright (C) 2015 Huawei Ltd.
5*59bfda1fSAndroid Build Coastguard Worker * Witten by:
6*59bfda1fSAndroid Build Coastguard Worker * Hou Pengyang <[email protected]>
7*59bfda1fSAndroid Build Coastguard Worker * Liu Shuoran <[email protected]>
8*59bfda1fSAndroid Build Coastguard Worker * Jaegeuk Kim <[email protected]>
9*59bfda1fSAndroid Build Coastguard Worker *
10*59bfda1fSAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or modify
11*59bfda1fSAndroid Build Coastguard Worker * it under the terms of the GNU General Public License version 2 as
12*59bfda1fSAndroid Build Coastguard Worker * published by the Free Software Foundation.
13*59bfda1fSAndroid Build Coastguard Worker */
14*59bfda1fSAndroid Build Coastguard Worker #define _GNU_SOURCE
15*59bfda1fSAndroid Build Coastguard Worker #include "fsck.h"
16*59bfda1fSAndroid Build Coastguard Worker #include <libgen.h>
17*59bfda1fSAndroid Build Coastguard Worker #include <dirent.h>
18*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_MNTENT_H
19*59bfda1fSAndroid Build Coastguard Worker #include <mntent.h>
20*59bfda1fSAndroid Build Coastguard Worker #endif
21*59bfda1fSAndroid Build Coastguard Worker
22*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_LIBSELINUX
23*59bfda1fSAndroid Build Coastguard Worker static struct selabel_handle *sehnd = NULL;
24*59bfda1fSAndroid Build Coastguard Worker #endif
25*59bfda1fSAndroid Build Coastguard Worker
26*59bfda1fSAndroid Build Coastguard Worker typedef void (*fs_config_f)(const char *path, int dir,
27*59bfda1fSAndroid Build Coastguard Worker const char *target_out_path,
28*59bfda1fSAndroid Build Coastguard Worker unsigned *uid, unsigned *gid,
29*59bfda1fSAndroid Build Coastguard Worker unsigned *mode, uint64_t *capabilities);
30*59bfda1fSAndroid Build Coastguard Worker
31*59bfda1fSAndroid Build Coastguard Worker #ifndef _WIN32
32*59bfda1fSAndroid Build Coastguard Worker static fs_config_f fs_config_func = NULL;
33*59bfda1fSAndroid Build Coastguard Worker
34*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_SELINUX_ANDROID_H
35*59bfda1fSAndroid Build Coastguard Worker #include <selinux/android.h>
36*59bfda1fSAndroid Build Coastguard Worker #include <private/android_filesystem_config.h>
37*59bfda1fSAndroid Build Coastguard Worker #include <private/canned_fs_config.h>
38*59bfda1fSAndroid Build Coastguard Worker #include <private/fs_config.h>
39*59bfda1fSAndroid Build Coastguard Worker #endif
40*59bfda1fSAndroid Build Coastguard Worker
filter_dot(const struct dirent * d)41*59bfda1fSAndroid Build Coastguard Worker static int filter_dot(const struct dirent *d)
42*59bfda1fSAndroid Build Coastguard Worker {
43*59bfda1fSAndroid Build Coastguard Worker return (strcmp(d->d_name, "..") && strcmp(d->d_name, "."));
44*59bfda1fSAndroid Build Coastguard Worker }
45*59bfda1fSAndroid Build Coastguard Worker
f2fs_make_directory(struct f2fs_sb_info * sbi,int entries,struct dentry * de)46*59bfda1fSAndroid Build Coastguard Worker static int f2fs_make_directory(struct f2fs_sb_info *sbi,
47*59bfda1fSAndroid Build Coastguard Worker int entries, struct dentry *de)
48*59bfda1fSAndroid Build Coastguard Worker {
49*59bfda1fSAndroid Build Coastguard Worker int ret = 0;
50*59bfda1fSAndroid Build Coastguard Worker int i = 0;
51*59bfda1fSAndroid Build Coastguard Worker
52*59bfda1fSAndroid Build Coastguard Worker for (i = 0; i < entries; i++) {
53*59bfda1fSAndroid Build Coastguard Worker if (de[i].file_type == F2FS_FT_DIR)
54*59bfda1fSAndroid Build Coastguard Worker ret = f2fs_mkdir(sbi, de + i);
55*59bfda1fSAndroid Build Coastguard Worker else if (de[i].file_type == F2FS_FT_REG_FILE)
56*59bfda1fSAndroid Build Coastguard Worker ret = f2fs_create(sbi, de + i);
57*59bfda1fSAndroid Build Coastguard Worker else if (de[i].file_type == F2FS_FT_SYMLINK)
58*59bfda1fSAndroid Build Coastguard Worker ret = f2fs_symlink(sbi, de + i);
59*59bfda1fSAndroid Build Coastguard Worker
60*59bfda1fSAndroid Build Coastguard Worker if (ret)
61*59bfda1fSAndroid Build Coastguard Worker break;
62*59bfda1fSAndroid Build Coastguard Worker }
63*59bfda1fSAndroid Build Coastguard Worker
64*59bfda1fSAndroid Build Coastguard Worker return ret;
65*59bfda1fSAndroid Build Coastguard Worker }
66*59bfda1fSAndroid Build Coastguard Worker #endif
67*59bfda1fSAndroid Build Coastguard Worker
68*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_LIBSELINUX
set_selinux_xattr(struct f2fs_sb_info * sbi,const char * path,nid_t ino,int mode)69*59bfda1fSAndroid Build Coastguard Worker static int set_selinux_xattr(struct f2fs_sb_info *sbi, const char *path,
70*59bfda1fSAndroid Build Coastguard Worker nid_t ino, int mode)
71*59bfda1fSAndroid Build Coastguard Worker {
72*59bfda1fSAndroid Build Coastguard Worker char *secontext = NULL;
73*59bfda1fSAndroid Build Coastguard Worker char *mnt_path = NULL;
74*59bfda1fSAndroid Build Coastguard Worker
75*59bfda1fSAndroid Build Coastguard Worker if (!sehnd)
76*59bfda1fSAndroid Build Coastguard Worker return 0;
77*59bfda1fSAndroid Build Coastguard Worker
78*59bfda1fSAndroid Build Coastguard Worker if (asprintf(&mnt_path, "%s%s", c.mount_point, path) <= 0) {
79*59bfda1fSAndroid Build Coastguard Worker ERR_MSG("cannot allocate security path for %s%s\n",
80*59bfda1fSAndroid Build Coastguard Worker c.mount_point, path);
81*59bfda1fSAndroid Build Coastguard Worker return -ENOMEM;
82*59bfda1fSAndroid Build Coastguard Worker }
83*59bfda1fSAndroid Build Coastguard Worker
84*59bfda1fSAndroid Build Coastguard Worker /* set root inode selinux context */
85*59bfda1fSAndroid Build Coastguard Worker if (selabel_lookup(sehnd, &secontext, mnt_path, mode) < 0) {
86*59bfda1fSAndroid Build Coastguard Worker ERR_MSG("cannot lookup security context for %s\n", mnt_path);
87*59bfda1fSAndroid Build Coastguard Worker free(mnt_path);
88*59bfda1fSAndroid Build Coastguard Worker return -EINVAL;
89*59bfda1fSAndroid Build Coastguard Worker }
90*59bfda1fSAndroid Build Coastguard Worker
91*59bfda1fSAndroid Build Coastguard Worker if (secontext) {
92*59bfda1fSAndroid Build Coastguard Worker MSG(2, "%s (%d) -> SELinux context = %s\n",
93*59bfda1fSAndroid Build Coastguard Worker mnt_path, ino, secontext);
94*59bfda1fSAndroid Build Coastguard Worker inode_set_selinux(sbi, ino, secontext);
95*59bfda1fSAndroid Build Coastguard Worker }
96*59bfda1fSAndroid Build Coastguard Worker freecon(secontext);
97*59bfda1fSAndroid Build Coastguard Worker free(mnt_path);
98*59bfda1fSAndroid Build Coastguard Worker return 0;
99*59bfda1fSAndroid Build Coastguard Worker }
100*59bfda1fSAndroid Build Coastguard Worker #else
101*59bfda1fSAndroid Build Coastguard Worker #define set_selinux_xattr(...) 0
102*59bfda1fSAndroid Build Coastguard Worker #endif
103*59bfda1fSAndroid Build Coastguard Worker
104*59bfda1fSAndroid Build Coastguard Worker #ifndef _WIN32
set_perms_and_caps(struct dentry * de)105*59bfda1fSAndroid Build Coastguard Worker static int set_perms_and_caps(struct dentry *de)
106*59bfda1fSAndroid Build Coastguard Worker {
107*59bfda1fSAndroid Build Coastguard Worker uint64_t capabilities = 0;
108*59bfda1fSAndroid Build Coastguard Worker unsigned int uid = 0, gid = 0, imode = 0;
109*59bfda1fSAndroid Build Coastguard Worker char *mnt_path = NULL;
110*59bfda1fSAndroid Build Coastguard Worker char *mount_path = c.mount_point;
111*59bfda1fSAndroid Build Coastguard Worker
112*59bfda1fSAndroid Build Coastguard Worker /*
113*59bfda1fSAndroid Build Coastguard Worker * de->path already has "/" in the beginning of it.
114*59bfda1fSAndroid Build Coastguard Worker * Need to remove "/" when c.mount_point is "/", not to add it twice.
115*59bfda1fSAndroid Build Coastguard Worker */
116*59bfda1fSAndroid Build Coastguard Worker if (strlen(c.mount_point) == 1 && c.mount_point[0] == '/')
117*59bfda1fSAndroid Build Coastguard Worker mount_path = "";
118*59bfda1fSAndroid Build Coastguard Worker
119*59bfda1fSAndroid Build Coastguard Worker if (asprintf(&mnt_path, "%s%s", mount_path, de->path) <= 0) {
120*59bfda1fSAndroid Build Coastguard Worker ERR_MSG("cannot allocate mount path for %s%s\n",
121*59bfda1fSAndroid Build Coastguard Worker mount_path, de->path);
122*59bfda1fSAndroid Build Coastguard Worker return -ENOMEM;
123*59bfda1fSAndroid Build Coastguard Worker }
124*59bfda1fSAndroid Build Coastguard Worker
125*59bfda1fSAndroid Build Coastguard Worker /* Permissions */
126*59bfda1fSAndroid Build Coastguard Worker if (fs_config_func != NULL) {
127*59bfda1fSAndroid Build Coastguard Worker fs_config_func(mnt_path, de->file_type == F2FS_FT_DIR,
128*59bfda1fSAndroid Build Coastguard Worker c.target_out_dir, &uid, &gid, &imode,
129*59bfda1fSAndroid Build Coastguard Worker &capabilities);
130*59bfda1fSAndroid Build Coastguard Worker de->uid = uid & 0xffff;
131*59bfda1fSAndroid Build Coastguard Worker de->gid = gid & 0xffff;
132*59bfda1fSAndroid Build Coastguard Worker de->mode = (de->mode & S_IFMT) | (imode & 0xffff);
133*59bfda1fSAndroid Build Coastguard Worker de->capabilities = capabilities;
134*59bfda1fSAndroid Build Coastguard Worker }
135*59bfda1fSAndroid Build Coastguard Worker MSG(2, "%s -> mode = 0x%x, uid = 0x%x, gid = 0x%x, "
136*59bfda1fSAndroid Build Coastguard Worker "capabilities = 0x%"PRIx64"\n",
137*59bfda1fSAndroid Build Coastguard Worker mnt_path, de->mode, de->uid, de->gid, de->capabilities);
138*59bfda1fSAndroid Build Coastguard Worker free(mnt_path);
139*59bfda1fSAndroid Build Coastguard Worker return 0;
140*59bfda1fSAndroid Build Coastguard Worker }
141*59bfda1fSAndroid Build Coastguard Worker
set_inode_metadata(struct dentry * de)142*59bfda1fSAndroid Build Coastguard Worker static void set_inode_metadata(struct dentry *de)
143*59bfda1fSAndroid Build Coastguard Worker {
144*59bfda1fSAndroid Build Coastguard Worker struct stat stat;
145*59bfda1fSAndroid Build Coastguard Worker int ret;
146*59bfda1fSAndroid Build Coastguard Worker
147*59bfda1fSAndroid Build Coastguard Worker ret = lstat(de->full_path, &stat);
148*59bfda1fSAndroid Build Coastguard Worker if (ret < 0) {
149*59bfda1fSAndroid Build Coastguard Worker ERR_MSG("lstat failure\n");
150*59bfda1fSAndroid Build Coastguard Worker ASSERT(0);
151*59bfda1fSAndroid Build Coastguard Worker }
152*59bfda1fSAndroid Build Coastguard Worker
153*59bfda1fSAndroid Build Coastguard Worker if (S_ISREG(stat.st_mode)) {
154*59bfda1fSAndroid Build Coastguard Worker if (stat.st_nlink > 1) {
155*59bfda1fSAndroid Build Coastguard Worker /*
156*59bfda1fSAndroid Build Coastguard Worker * This file might have multiple links to it, so remember
157*59bfda1fSAndroid Build Coastguard Worker * device and inode.
158*59bfda1fSAndroid Build Coastguard Worker */
159*59bfda1fSAndroid Build Coastguard Worker de->from_devino = stat.st_dev;
160*59bfda1fSAndroid Build Coastguard Worker de->from_devino <<= 32;
161*59bfda1fSAndroid Build Coastguard Worker de->from_devino |= stat.st_ino;
162*59bfda1fSAndroid Build Coastguard Worker }
163*59bfda1fSAndroid Build Coastguard Worker de->file_type = F2FS_FT_REG_FILE;
164*59bfda1fSAndroid Build Coastguard Worker } else if (S_ISDIR(stat.st_mode)) {
165*59bfda1fSAndroid Build Coastguard Worker de->file_type = F2FS_FT_DIR;
166*59bfda1fSAndroid Build Coastguard Worker } else if (S_ISCHR(stat.st_mode)) {
167*59bfda1fSAndroid Build Coastguard Worker de->file_type = F2FS_FT_CHRDEV;
168*59bfda1fSAndroid Build Coastguard Worker } else if (S_ISBLK(stat.st_mode)) {
169*59bfda1fSAndroid Build Coastguard Worker de->file_type = F2FS_FT_BLKDEV;
170*59bfda1fSAndroid Build Coastguard Worker } else if (S_ISFIFO(stat.st_mode)) {
171*59bfda1fSAndroid Build Coastguard Worker de->file_type = F2FS_FT_FIFO;
172*59bfda1fSAndroid Build Coastguard Worker } else if (S_ISSOCK(stat.st_mode)) {
173*59bfda1fSAndroid Build Coastguard Worker de->file_type = F2FS_FT_SOCK;
174*59bfda1fSAndroid Build Coastguard Worker } else if (S_ISLNK(stat.st_mode)) {
175*59bfda1fSAndroid Build Coastguard Worker de->file_type = F2FS_FT_SYMLINK;
176*59bfda1fSAndroid Build Coastguard Worker de->link = calloc(F2FS_BLKSIZE, 1);
177*59bfda1fSAndroid Build Coastguard Worker ASSERT(de->link);
178*59bfda1fSAndroid Build Coastguard Worker ret = readlink(de->full_path, de->link, F2FS_BLKSIZE - 1);
179*59bfda1fSAndroid Build Coastguard Worker ASSERT(ret >= 0);
180*59bfda1fSAndroid Build Coastguard Worker } else {
181*59bfda1fSAndroid Build Coastguard Worker ERR_MSG("unknown file type on %s", de->path);
182*59bfda1fSAndroid Build Coastguard Worker ASSERT(0);
183*59bfda1fSAndroid Build Coastguard Worker }
184*59bfda1fSAndroid Build Coastguard Worker
185*59bfda1fSAndroid Build Coastguard Worker de->size = stat.st_size;
186*59bfda1fSAndroid Build Coastguard Worker de->mode = stat.st_mode &
187*59bfda1fSAndroid Build Coastguard Worker (S_IFMT|S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO);
188*59bfda1fSAndroid Build Coastguard Worker if (c.fixed_time == -1 && c.from_dir)
189*59bfda1fSAndroid Build Coastguard Worker de->mtime = stat.st_mtime;
190*59bfda1fSAndroid Build Coastguard Worker else
191*59bfda1fSAndroid Build Coastguard Worker de->mtime = c.fixed_time;
192*59bfda1fSAndroid Build Coastguard Worker
193*59bfda1fSAndroid Build Coastguard Worker if (c.preserve_perms) {
194*59bfda1fSAndroid Build Coastguard Worker de->uid = stat.st_uid;
195*59bfda1fSAndroid Build Coastguard Worker de->gid = stat.st_gid;
196*59bfda1fSAndroid Build Coastguard Worker }
197*59bfda1fSAndroid Build Coastguard Worker
198*59bfda1fSAndroid Build Coastguard Worker set_perms_and_caps(de);
199*59bfda1fSAndroid Build Coastguard Worker }
200*59bfda1fSAndroid Build Coastguard Worker
build_directory(struct f2fs_sb_info * sbi,const char * full_path,const char * dir_path,const char * target_out_dir,nid_t dir_ino)201*59bfda1fSAndroid Build Coastguard Worker static int build_directory(struct f2fs_sb_info *sbi, const char *full_path,
202*59bfda1fSAndroid Build Coastguard Worker const char *dir_path, const char *target_out_dir,
203*59bfda1fSAndroid Build Coastguard Worker nid_t dir_ino)
204*59bfda1fSAndroid Build Coastguard Worker {
205*59bfda1fSAndroid Build Coastguard Worker int entries = 0;
206*59bfda1fSAndroid Build Coastguard Worker struct dentry *dentries;
207*59bfda1fSAndroid Build Coastguard Worker struct dirent **namelist = NULL;
208*59bfda1fSAndroid Build Coastguard Worker int i = 0, ret = 0;
209*59bfda1fSAndroid Build Coastguard Worker
210*59bfda1fSAndroid Build Coastguard Worker entries = scandir(full_path, &namelist, filter_dot, (void *)alphasort);
211*59bfda1fSAndroid Build Coastguard Worker if (entries < 0) {
212*59bfda1fSAndroid Build Coastguard Worker ERR_MSG("No entries in %s\n", full_path);
213*59bfda1fSAndroid Build Coastguard Worker return -ENOENT;
214*59bfda1fSAndroid Build Coastguard Worker }
215*59bfda1fSAndroid Build Coastguard Worker
216*59bfda1fSAndroid Build Coastguard Worker dentries = calloc(entries, sizeof(struct dentry));
217*59bfda1fSAndroid Build Coastguard Worker ASSERT(dentries);
218*59bfda1fSAndroid Build Coastguard Worker
219*59bfda1fSAndroid Build Coastguard Worker for (i = 0; i < entries; i++) {
220*59bfda1fSAndroid Build Coastguard Worker dentries[i].name = (unsigned char *)strdup(namelist[i]->d_name);
221*59bfda1fSAndroid Build Coastguard Worker if (dentries[i].name == NULL) {
222*59bfda1fSAndroid Build Coastguard Worker ERR_MSG("Skip: ENOMEM\n");
223*59bfda1fSAndroid Build Coastguard Worker continue;
224*59bfda1fSAndroid Build Coastguard Worker }
225*59bfda1fSAndroid Build Coastguard Worker dentries[i].len = strlen((char *)dentries[i].name);
226*59bfda1fSAndroid Build Coastguard Worker
227*59bfda1fSAndroid Build Coastguard Worker ret = asprintf(&dentries[i].path, "%s%s",
228*59bfda1fSAndroid Build Coastguard Worker dir_path, namelist[i]->d_name);
229*59bfda1fSAndroid Build Coastguard Worker ASSERT(ret > 0);
230*59bfda1fSAndroid Build Coastguard Worker ret = asprintf(&dentries[i].full_path, "%s/%s",
231*59bfda1fSAndroid Build Coastguard Worker full_path, namelist[i]->d_name);
232*59bfda1fSAndroid Build Coastguard Worker ASSERT(ret > 0);
233*59bfda1fSAndroid Build Coastguard Worker free(namelist[i]);
234*59bfda1fSAndroid Build Coastguard Worker
235*59bfda1fSAndroid Build Coastguard Worker set_inode_metadata(dentries + i);
236*59bfda1fSAndroid Build Coastguard Worker
237*59bfda1fSAndroid Build Coastguard Worker dentries[i].pino = dir_ino;
238*59bfda1fSAndroid Build Coastguard Worker }
239*59bfda1fSAndroid Build Coastguard Worker
240*59bfda1fSAndroid Build Coastguard Worker free(namelist);
241*59bfda1fSAndroid Build Coastguard Worker
242*59bfda1fSAndroid Build Coastguard Worker ret = f2fs_make_directory(sbi, entries, dentries);
243*59bfda1fSAndroid Build Coastguard Worker if (ret)
244*59bfda1fSAndroid Build Coastguard Worker goto out_free;
245*59bfda1fSAndroid Build Coastguard Worker
246*59bfda1fSAndroid Build Coastguard Worker for (i = 0; i < entries; i++) {
247*59bfda1fSAndroid Build Coastguard Worker if (dentries[i].file_type == F2FS_FT_REG_FILE) {
248*59bfda1fSAndroid Build Coastguard Worker f2fs_build_file(sbi, dentries + i);
249*59bfda1fSAndroid Build Coastguard Worker } else if (dentries[i].file_type == F2FS_FT_DIR) {
250*59bfda1fSAndroid Build Coastguard Worker char *subdir_full_path = NULL;
251*59bfda1fSAndroid Build Coastguard Worker char *subdir_dir_path = NULL;
252*59bfda1fSAndroid Build Coastguard Worker
253*59bfda1fSAndroid Build Coastguard Worker ret = asprintf(&subdir_full_path, "%s",
254*59bfda1fSAndroid Build Coastguard Worker dentries[i].full_path);
255*59bfda1fSAndroid Build Coastguard Worker ASSERT(ret > 0);
256*59bfda1fSAndroid Build Coastguard Worker ret = asprintf(&subdir_dir_path, "%s/",
257*59bfda1fSAndroid Build Coastguard Worker dentries[i].path);
258*59bfda1fSAndroid Build Coastguard Worker ASSERT(ret > 0);
259*59bfda1fSAndroid Build Coastguard Worker
260*59bfda1fSAndroid Build Coastguard Worker ret = build_directory(sbi, subdir_full_path,
261*59bfda1fSAndroid Build Coastguard Worker subdir_dir_path,
262*59bfda1fSAndroid Build Coastguard Worker target_out_dir,
263*59bfda1fSAndroid Build Coastguard Worker dentries[i].ino);
264*59bfda1fSAndroid Build Coastguard Worker free(subdir_full_path);
265*59bfda1fSAndroid Build Coastguard Worker free(subdir_dir_path);
266*59bfda1fSAndroid Build Coastguard Worker
267*59bfda1fSAndroid Build Coastguard Worker if (ret)
268*59bfda1fSAndroid Build Coastguard Worker goto out_free;
269*59bfda1fSAndroid Build Coastguard Worker } else if (dentries[i].file_type == F2FS_FT_SYMLINK) {
270*59bfda1fSAndroid Build Coastguard Worker /*
271*59bfda1fSAndroid Build Coastguard Worker * It is already done in f2fs_make_directory
272*59bfda1fSAndroid Build Coastguard Worker * f2fs_make_symlink(sbi, dir_ino, &dentries[i]);
273*59bfda1fSAndroid Build Coastguard Worker */
274*59bfda1fSAndroid Build Coastguard Worker } else {
275*59bfda1fSAndroid Build Coastguard Worker MSG(1, "Error unknown file type\n");
276*59bfda1fSAndroid Build Coastguard Worker }
277*59bfda1fSAndroid Build Coastguard Worker
278*59bfda1fSAndroid Build Coastguard Worker ret = set_selinux_xattr(sbi, dentries[i].path,
279*59bfda1fSAndroid Build Coastguard Worker dentries[i].ino, dentries[i].mode);
280*59bfda1fSAndroid Build Coastguard Worker if (ret)
281*59bfda1fSAndroid Build Coastguard Worker goto out_free;
282*59bfda1fSAndroid Build Coastguard Worker
283*59bfda1fSAndroid Build Coastguard Worker free(dentries[i].path);
284*59bfda1fSAndroid Build Coastguard Worker free(dentries[i].full_path);
285*59bfda1fSAndroid Build Coastguard Worker free((void *)dentries[i].name);
286*59bfda1fSAndroid Build Coastguard Worker }
287*59bfda1fSAndroid Build Coastguard Worker out_free:
288*59bfda1fSAndroid Build Coastguard Worker for (; i < entries; i++) {
289*59bfda1fSAndroid Build Coastguard Worker free(dentries[i].path);
290*59bfda1fSAndroid Build Coastguard Worker free(dentries[i].full_path);
291*59bfda1fSAndroid Build Coastguard Worker free((void *)dentries[i].name);
292*59bfda1fSAndroid Build Coastguard Worker }
293*59bfda1fSAndroid Build Coastguard Worker
294*59bfda1fSAndroid Build Coastguard Worker free(dentries);
295*59bfda1fSAndroid Build Coastguard Worker return 0;
296*59bfda1fSAndroid Build Coastguard Worker }
297*59bfda1fSAndroid Build Coastguard Worker #else
build_directory(struct f2fs_sb_info * sbi,const char * full_path,const char * dir_path,const char * target_out_dir,nid_t dir_ino)298*59bfda1fSAndroid Build Coastguard Worker static int build_directory(struct f2fs_sb_info *sbi, const char *full_path,
299*59bfda1fSAndroid Build Coastguard Worker const char *dir_path, const char *target_out_dir,
300*59bfda1fSAndroid Build Coastguard Worker nid_t dir_ino)
301*59bfda1fSAndroid Build Coastguard Worker {
302*59bfda1fSAndroid Build Coastguard Worker return -1;
303*59bfda1fSAndroid Build Coastguard Worker }
304*59bfda1fSAndroid Build Coastguard Worker #endif
305*59bfda1fSAndroid Build Coastguard Worker
configure_files(void)306*59bfda1fSAndroid Build Coastguard Worker static int configure_files(void)
307*59bfda1fSAndroid Build Coastguard Worker {
308*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_LIBSELINUX
309*59bfda1fSAndroid Build Coastguard Worker if (!c.nr_opt)
310*59bfda1fSAndroid Build Coastguard Worker goto skip;
311*59bfda1fSAndroid Build Coastguard Worker #if !defined(__ANDROID__)
312*59bfda1fSAndroid Build Coastguard Worker sehnd = selabel_open(SELABEL_CTX_FILE, c.seopt_file, c.nr_opt);
313*59bfda1fSAndroid Build Coastguard Worker if (!sehnd) {
314*59bfda1fSAndroid Build Coastguard Worker ERR_MSG("Failed to open file contexts \"%s\"",
315*59bfda1fSAndroid Build Coastguard Worker c.seopt_file[0].value);
316*59bfda1fSAndroid Build Coastguard Worker return -EINVAL;
317*59bfda1fSAndroid Build Coastguard Worker }
318*59bfda1fSAndroid Build Coastguard Worker #else
319*59bfda1fSAndroid Build Coastguard Worker sehnd = selinux_android_file_context_handle();
320*59bfda1fSAndroid Build Coastguard Worker if (!sehnd) {
321*59bfda1fSAndroid Build Coastguard Worker ERR_MSG("Failed to get android file_contexts\n");
322*59bfda1fSAndroid Build Coastguard Worker return -EINVAL;
323*59bfda1fSAndroid Build Coastguard Worker }
324*59bfda1fSAndroid Build Coastguard Worker #endif
325*59bfda1fSAndroid Build Coastguard Worker skip:
326*59bfda1fSAndroid Build Coastguard Worker #endif
327*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_SELINUX_ANDROID_H
328*59bfda1fSAndroid Build Coastguard Worker /* Load the FS config */
329*59bfda1fSAndroid Build Coastguard Worker if (c.fs_config_file) {
330*59bfda1fSAndroid Build Coastguard Worker int ret = load_canned_fs_config(c.fs_config_file);
331*59bfda1fSAndroid Build Coastguard Worker
332*59bfda1fSAndroid Build Coastguard Worker if (ret < 0) {
333*59bfda1fSAndroid Build Coastguard Worker ERR_MSG("Failed to load fs_config \"%s\"",
334*59bfda1fSAndroid Build Coastguard Worker c.fs_config_file);
335*59bfda1fSAndroid Build Coastguard Worker return ret;
336*59bfda1fSAndroid Build Coastguard Worker }
337*59bfda1fSAndroid Build Coastguard Worker fs_config_func = canned_fs_config;
338*59bfda1fSAndroid Build Coastguard Worker } else {
339*59bfda1fSAndroid Build Coastguard Worker fs_config_func = fs_config;
340*59bfda1fSAndroid Build Coastguard Worker }
341*59bfda1fSAndroid Build Coastguard Worker #endif
342*59bfda1fSAndroid Build Coastguard Worker return 0;
343*59bfda1fSAndroid Build Coastguard Worker }
344*59bfda1fSAndroid Build Coastguard Worker
f2fs_sload(struct f2fs_sb_info * sbi)345*59bfda1fSAndroid Build Coastguard Worker int f2fs_sload(struct f2fs_sb_info *sbi)
346*59bfda1fSAndroid Build Coastguard Worker {
347*59bfda1fSAndroid Build Coastguard Worker int ret = 0;
348*59bfda1fSAndroid Build Coastguard Worker
349*59bfda1fSAndroid Build Coastguard Worker /* this requires for the below sanity checks */
350*59bfda1fSAndroid Build Coastguard Worker fsck_init(sbi);
351*59bfda1fSAndroid Build Coastguard Worker
352*59bfda1fSAndroid Build Coastguard Worker ret = configure_files();
353*59bfda1fSAndroid Build Coastguard Worker if (ret) {
354*59bfda1fSAndroid Build Coastguard Worker ERR_MSG("Failed to configure files\n");
355*59bfda1fSAndroid Build Coastguard Worker return ret;
356*59bfda1fSAndroid Build Coastguard Worker }
357*59bfda1fSAndroid Build Coastguard Worker
358*59bfda1fSAndroid Build Coastguard Worker /* flush NAT/SIT journal entries */
359*59bfda1fSAndroid Build Coastguard Worker flush_journal_entries(sbi);
360*59bfda1fSAndroid Build Coastguard Worker
361*59bfda1fSAndroid Build Coastguard Worker /* initialize empty hardlink cache */
362*59bfda1fSAndroid Build Coastguard Worker sbi->hardlink_cache = 0;
363*59bfda1fSAndroid Build Coastguard Worker
364*59bfda1fSAndroid Build Coastguard Worker ret = build_directory(sbi, c.from_dir, "/",
365*59bfda1fSAndroid Build Coastguard Worker c.target_out_dir, F2FS_ROOT_INO(sbi));
366*59bfda1fSAndroid Build Coastguard Worker if (ret) {
367*59bfda1fSAndroid Build Coastguard Worker ERR_MSG("Failed to build due to %d\n", ret);
368*59bfda1fSAndroid Build Coastguard Worker return ret;
369*59bfda1fSAndroid Build Coastguard Worker }
370*59bfda1fSAndroid Build Coastguard Worker
371*59bfda1fSAndroid Build Coastguard Worker ret = set_selinux_xattr(sbi, c.mount_point,
372*59bfda1fSAndroid Build Coastguard Worker F2FS_ROOT_INO(sbi), S_IFDIR);
373*59bfda1fSAndroid Build Coastguard Worker if (ret) {
374*59bfda1fSAndroid Build Coastguard Worker ERR_MSG("Failed to set selinux for root: %d\n", ret);
375*59bfda1fSAndroid Build Coastguard Worker return ret;
376*59bfda1fSAndroid Build Coastguard Worker }
377*59bfda1fSAndroid Build Coastguard Worker
378*59bfda1fSAndroid Build Coastguard Worker /* update curseg info; can update sit->types */
379*59bfda1fSAndroid Build Coastguard Worker move_curseg_info(sbi, SM_I(sbi)->main_blkaddr, 0);
380*59bfda1fSAndroid Build Coastguard Worker zero_journal_entries(sbi);
381*59bfda1fSAndroid Build Coastguard Worker write_curseg_info(sbi);
382*59bfda1fSAndroid Build Coastguard Worker
383*59bfda1fSAndroid Build Coastguard Worker /* flush dirty sit entries */
384*59bfda1fSAndroid Build Coastguard Worker flush_sit_entries(sbi);
385*59bfda1fSAndroid Build Coastguard Worker
386*59bfda1fSAndroid Build Coastguard Worker write_checkpoint(sbi);
387*59bfda1fSAndroid Build Coastguard Worker return 0;
388*59bfda1fSAndroid Build Coastguard Worker }
389