blob: 9b508f0cda2043d6606c4ed88ac52a6276e086f5 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fs-management/mount.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <zircon/compiler.h>
#include <zircon/device/vfs.h>
#include <zircon/processargs.h>
#include <zircon/syscalls.h>
#include <fdio/limits.h>
#include <fdio/util.h>
#include <fdio/vfs.h>
static zx_status_t fsck_mxfs(const char* devicepath, const fsck_options_t* options,
LaunchCallback cb, const char* cmdpath) {
zx_handle_t hnd[FDIO_MAX_HANDLES * 2];
uint32_t ids[FDIO_MAX_HANDLES * 2];
size_t n = 0;
int device_fd;
if ((device_fd = open(devicepath, O_RDWR)) < 0) {
fprintf(stderr, "Failed to open device\n");
return ZX_ERR_BAD_STATE;
}
zx_status_t status;
if ((status = fdio_transfer_fd(device_fd, FS_FD_BLOCKDEVICE, hnd + n, ids + n)) <= 0) {
fprintf(stderr, "Failed to access device handle\n");
return status != 0 ? status : ZX_ERR_BAD_STATE;
}
n += status;
const char** argv = calloc(sizeof(char*), (2 + NUM_FSCK_OPTIONS));
size_t argc = 0;
argv[argc++] = cmdpath;
if (options->verbose) {
argv[argc++] = "-v";
}
// TODO(smklein): Add support for modify, force flags. Without them,
// we have "always_modify=true" and "force=true" effectively on by default.
argv[argc++] = "fsck";
status = cb(argc, argv, hnd, ids, n);
free(argv);
return status;
}
static zx_status_t fsck_fat(const char* devicepath, const fsck_options_t* options,
LaunchCallback cb) {
const char** argv = calloc(sizeof(char*), (2 + NUM_FSCK_OPTIONS));
size_t argc = 0;
argv[argc++] = "/boot/bin/fsck-msdosfs";
if (options->never_modify) {
argv[argc++] = "-n";
} else if (options->always_modify) {
argv[argc++] = "-y";
}
if (options->force) {
argv[argc++] = "-f";
}
argv[argc++] = devicepath;
zx_status_t status = cb(argc, argv, NULL, NULL, 0);
free(argv);
return status;
}
zx_status_t fsck(const char* devicepath, disk_format_t df,
const fsck_options_t* options, LaunchCallback cb) {
switch (df) {
case DISK_FORMAT_MINFS:
return fsck_mxfs(devicepath, options, cb, "/boot/bin/minfs");
case DISK_FORMAT_FAT:
return fsck_fat(devicepath, options, cb);
case DISK_FORMAT_BLOBFS:
return fsck_mxfs(devicepath, options, cb, "/boot/bin/blobstore");
default:
return ZX_ERR_NOT_SUPPORTED;
}
}