Ext4.cpp revision 9c48498f4529f623650c56d03e63324c8d813032
1344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root/*
2344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root * Copyright (C) 2012 The Android Open Source Project
3344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root *
4344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root * Licensed under the Apache License, Version 2.0 (the "License");
5344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root * you may not use this file except in compliance with the License.
6344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root * You may obtain a copy of the License at
7344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root *
8344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root *      http://www.apache.org/licenses/LICENSE-2.0
9344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root *
10344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root * Unless required by applicable law or agreed to in writing, software
11344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root * distributed under the License is distributed on an "AS IS" BASIS,
12344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root * See the License for the specific language governing permissions and
14344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root * limitations under the License.
15344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root */
16344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
17344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root#include <stdio.h>
18344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root#include <stdlib.h>
19344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root#include <fcntl.h>
20344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root#include <unistd.h>
21344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root#include <errno.h>
22344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root#include <string.h>
23344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root#include <dirent.h>
24344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root#include <errno.h>
25344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root#include <fcntl.h>
269c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey#include <vector>
279c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey#include <string>
28344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
29344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root#include <sys/types.h>
30344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root#include <sys/stat.h>
31344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root#include <sys/types.h>
32344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root#include <sys/mman.h>
33344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root#include <sys/mount.h>
342ba45aafc22ff2fed91f8cd191beb85578b7b9bcRom Lemarchand#include <sys/wait.h>
35344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
36344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root#include <linux/kdev_t.h>
37344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
38344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root#define LOG_TAG "Vold"
39344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
409c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey#include <base/stringprintf.h>
41344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root#include <cutils/log.h>
42344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root#include <cutils/properties.h>
432ba45aafc22ff2fed91f8cd191beb85578b7b9bcRom Lemarchand#include <logwrap/logwrap.h>
442ba45aafc22ff2fed91f8cd191beb85578b7b9bcRom Lemarchand
45344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root#include "Ext4.h"
469c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey#include "Utils.h"
475593c856f49684f149116a6f2f28ddf9338b8557Rom Lemarchand#include "VoldUtil.h"
48344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
49fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg#define RESIZE2FS_PATH "/system/bin/resize2fs"
50344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
519c48498f4529f623650c56d03e63324c8d813032Jeff Sharkeyusing android::base::StringPrintf;
529c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey
539c48498f4529f623650c56d03e63324c8d813032Jeff Sharkeystatic const char* kMkfsPath = "/system/bin/make_ext4fs";
549c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey
559c48498f4529f623650c56d03e63324c8d813032Jeff Sharkeystatic const char* kFsckPath = "/system/bin/e2fsck";
569c48498f4529f623650c56d03e63324c8d813032Jeff Sharkeystatic const char* kFsckLogFile = "/dev/fscklogs/log";
579c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey
589c48498f4529f623650c56d03e63324c8d813032Jeff Sharkeyint Ext4::check(const char *fsPath, const char *mountPoint) {
599c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    // The following is shamelessly borrowed from fs_mgr.c, so it should be
609c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    // kept in sync with any changes over there.
619c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey
629c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    char* blk_device = (char*) fsPath;
639c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    char* target = (char*) mountPoint;
649c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey
659c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    int status;
669c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    int ret;
679c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID;
689c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    char *tmpmnt_opts = (char*) "nomblk_io_submit,errors=remount-ro";
699c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    char *e2fsck_argv[] = {
709c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey        (char*) kFsckPath,
719c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey        (char*) "-y",
729c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey        blk_device
739c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    };
749c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey
759c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    /*
769c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey     * First try to mount and unmount the filesystem.  We do this because
779c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey     * the kernel is more efficient than e2fsck in running the journal and
789c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey     * processing orphaned inodes, and on at least one device with a
799c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey     * performance issue in the emmc firmware, it can take e2fsck 2.5 minutes
809c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey     * to do what the kernel does in about a second.
819c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey     *
829c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey     * After mounting and unmounting the filesystem, run e2fsck, and if an
839c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey     * error is recorded in the filesystem superblock, e2fsck will do a full
849c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey     * check.  Otherwise, it does nothing.  If the kernel cannot mount the
859c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey     * filesytsem due to an error, e2fsck is still run to do a full check
869c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey     * fix the filesystem.
879c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey     */
889c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    ret = mount(blk_device, target, "ext4", tmpmnt_flags, tmpmnt_opts);
899c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    if (!ret) {
909c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey        int i;
919c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey        for (i = 0; i < 5; i++) {
929c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey            // Try to umount 5 times before continuing on.
939c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey            // Should we try rebooting if all attempts fail?
949c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey            int result = umount(target);
959c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey            if (result == 0) {
969c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey                break;
979c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey            }
989c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey            ALOGW("%s(): umount(%s)=%d: %s\n", __func__, target, result, strerror(errno));
999c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey            sleep(1);
1009c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey        }
1019c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    }
1029c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey
1039c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    /*
1049c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey     * Some system images do not have e2fsck for licensing reasons
1059c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey     * (e.g. recent SDK system images). Detect these and skip the check.
1069c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey     */
1079c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    if (access(kFsckPath, X_OK)) {
1089c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey        ALOGD("Not running %s on %s (executable not in system image)\n",
1099c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey                kFsckPath, blk_device);
1109c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    } else {
1119c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey        ALOGD("Running %s on %s\n", kFsckPath, blk_device);
1129c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey
1139c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey        ret = android_fork_execvp(ARRAY_SIZE(e2fsck_argv), e2fsck_argv,
1149c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey                                    &status, false, true);
1159c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey
1169c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey        if (ret < 0) {
1179c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey            /* No need to check for error in fork, we can't really handle it now */
1189c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey            ALOGW("Failed trying to run %s\n", kFsckPath);
1199c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey            return -1;
1209c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey        }
1219c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    }
1229c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey
1239c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    return 0;
1249c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey}
1259c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey
126344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Rootint Ext4::doMount(const char *fsPath, const char *mountPoint, bool ro, bool remount,
127344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        bool executable) {
128344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    int rc;
129344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    unsigned long flags;
130344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
131344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    flags = MS_NOATIME | MS_NODEV | MS_NOSUID | MS_DIRSYNC;
132344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
133344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    flags |= (executable ? 0 : MS_NOEXEC);
134344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    flags |= (ro ? MS_RDONLY : 0);
135344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    flags |= (remount ? MS_REMOUNT : 0);
136344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
137344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    rc = mount(fsPath, mountPoint, "ext4", flags, NULL);
138344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
139344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    if (rc && errno == EROFS) {
140344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        SLOGE("%s appears to be a read only filesystem - retrying mount RO", fsPath);
141344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        flags |= MS_RDONLY;
142344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        rc = mount(fsPath, mountPoint, "ext4", flags, NULL);
143344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    }
144344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
145344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    return rc;
146344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root}
147344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
148fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenbergint Ext4::resize(const char *fspath, unsigned int numSectors) {
149fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    const char *args[4];
150fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    char* size_str;
151fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    int rc;
152fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    int status;
153fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg
154fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    args[0] = RESIZE2FS_PATH;
155fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    args[1] = "-f";
156fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    args[2] = fspath;
157fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    if (asprintf(&size_str, "%ds", numSectors) < 0)
158fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    {
159fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg      SLOGE("Filesystem (ext4) resize failed to set size");
160fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg      return -1;
161fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    }
162fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    args[3] = size_str;
163fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status, false,
164fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg            true);
165fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    free(size_str);
166fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    if (rc != 0) {
167fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg        SLOGE("Filesystem (ext4) resize failed due to logwrap error");
168fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg        errno = EIO;
169fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg        return -1;
170fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    }
171fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg
172fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    if (!WIFEXITED(status)) {
173fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg        SLOGE("Filesystem (ext4) resize did not exit properly");
174fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg        errno = EIO;
175fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg        return -1;
176fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    }
177fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg
178fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    status = WEXITSTATUS(status);
179fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg
180fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    if (status == 0) {
181fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg        SLOGI("Filesystem (ext4) resized OK");
182fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg        return 0;
183fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    } else {
184fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg        SLOGE("Resize (ext4) failed (unknown exit code %d)", status);
185fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg        errno = EIO;
186fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg        return -1;
187fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    }
188fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    return 0;
189fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg}
190fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg
1916a74dcaa6e646fea8e00b7c04332fc60fe7e017cDaniel Rosenbergint Ext4::format(const char *fsPath, unsigned int numSectors, const char *mountpoint) {
1922ba45aafc22ff2fed91f8cd191beb85578b7b9bcRom Lemarchand    int status;
193344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
1949c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    std::vector<std::string> cmd;
1959c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    cmd.push_back(kMkfsPath);
1969c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    cmd.push_back("-J");
1979c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey
1989c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    cmd.push_back("-a");
1999c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    cmd.push_back(mountpoint);
2009c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey
2016a74dcaa6e646fea8e00b7c04332fc60fe7e017cDaniel Rosenberg    if (numSectors) {
2029c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey        cmd.push_back("-l");
2039c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey        cmd.push_back(StringPrintf("%u", numSectors * 512));
2046a74dcaa6e646fea8e00b7c04332fc60fe7e017cDaniel Rosenberg    }
2059c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey
2069c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    cmd.push_back(fsPath);
2079c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey
2089c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey    int rc = android::vold::ForkExecvp(cmd, &status, false, true);
2092ba45aafc22ff2fed91f8cd191beb85578b7b9bcRom Lemarchand    if (rc != 0) {
2102ba45aafc22ff2fed91f8cd191beb85578b7b9bcRom Lemarchand        SLOGE("Filesystem (ext4) format failed due to logwrap error");
2112ba45aafc22ff2fed91f8cd191beb85578b7b9bcRom Lemarchand        errno = EIO;
2122ba45aafc22ff2fed91f8cd191beb85578b7b9bcRom Lemarchand        return -1;
2132ba45aafc22ff2fed91f8cd191beb85578b7b9bcRom Lemarchand    }
2142ba45aafc22ff2fed91f8cd191beb85578b7b9bcRom Lemarchand
2152ba45aafc22ff2fed91f8cd191beb85578b7b9bcRom Lemarchand    if (!WIFEXITED(status)) {
2162ba45aafc22ff2fed91f8cd191beb85578b7b9bcRom Lemarchand        SLOGE("Filesystem (ext4) format did not exit properly");
2172ba45aafc22ff2fed91f8cd191beb85578b7b9bcRom Lemarchand        errno = EIO;
2182ba45aafc22ff2fed91f8cd191beb85578b7b9bcRom Lemarchand        return -1;
2192ba45aafc22ff2fed91f8cd191beb85578b7b9bcRom Lemarchand    }
2202ba45aafc22ff2fed91f8cd191beb85578b7b9bcRom Lemarchand
2212ba45aafc22ff2fed91f8cd191beb85578b7b9bcRom Lemarchand    status = WEXITSTATUS(status);
222344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
2232ba45aafc22ff2fed91f8cd191beb85578b7b9bcRom Lemarchand    if (status == 0) {
224344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        SLOGI("Filesystem (ext4) formatted OK");
225344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        return 0;
226344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    } else {
2272ba45aafc22ff2fed91f8cd191beb85578b7b9bcRom Lemarchand        SLOGE("Format (ext4) failed (unknown exit code %d)", status);
228344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        errno = EIO;
229344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        return -1;
230344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    }
231344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    return 0;
232344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root}
233