From a8e8efef967b6acf474e1d6f69ef11aeb211726f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sat, 1 Nov 2008 17:28:10 +0000 Subject: [PATCH] * Made repairing partitions work theoretically. * Implemented a small app "checkfs" to check partitions and put it on the image. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28435 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- build/jam/HaikuImage | 6 +- src/bin/Jamfile | 1 + src/bin/checkfs.cpp | 147 ++++++++++++++++++ .../storage/disk_device/PartitionDelegate.cpp | 6 +- 4 files changed, 155 insertions(+), 5 deletions(-) create mode 100644 src/bin/checkfs.cpp diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index 55eb881057..4d7db6393b 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -30,9 +30,9 @@ if $(INCLUDE_GPL_ADDONS) = 1 { GPL_ONLY = "" ; } -BEOS_BIN = "[" addattr alert arp base64 basename bc beep bootman bzip2 cal cat - catattr chgrp chmod chop chown chroot cksum clear clockconfig cmp comm - compress cp copyattr $(X86_ONLY)CortexAddOnHost +BEOS_BIN = "[" addattr alert arp base64 basename bc beep bootman bzip2 + cal cat catattr checkfs chgrp chmod chop chown chroot cksum clear + clockconfig cmp comm compress cp copyattr $(X86_ONLY)CortexAddOnHost csplit ctags cut date dc dd desklink df diff diff3 dircolors dirname draggers driveinfo dstcheck du echo eject env error expand expr expr factor false fdinfo ffm find finddir fmt fold fortune frcode ftp ftpd diff --git a/src/bin/Jamfile b/src/bin/Jamfile index 21f3bf8388..19129b6102 100644 --- a/src/bin/Jamfile +++ b/src/bin/Jamfile @@ -75,6 +75,7 @@ StdBinCommands StdBinCommands alert.cpp beep.cpp + checkfs.cpp clipboard.cpp df.cpp dpms.cpp diff --git a/src/bin/checkfs.cpp b/src/bin/checkfs.cpp new file mode 100644 index 0000000000..6240b0805e --- /dev/null +++ b/src/bin/checkfs.cpp @@ -0,0 +1,147 @@ +/* + * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ + + +#include +#include + +#include +#include +#include + + +extern "C" const char* __progname; +static const char* kProgramName = __progname; + + +void +usage(FILE* output) +{ + fprintf(output, + "Usage: %s \n" + "\n" + "Options:\n" + " -h, --help - print this help text\n" + " -c, --check-only - do not make any changes to the file system\n", + kProgramName); +} + + +int +main(int argc, char** argv) +{ + const struct option kLongOptions[] = { + { "help", 0, NULL, 'h' }, + { "check-only", 0, NULL, 'c' }, + { NULL, 0, NULL, 0 } + }; + const char* kShortOptions = "hc"; + + // parse argument list + bool checkOnly = false; + + while (true) { + int nextOption = getopt_long(argc, argv, kShortOptions, kLongOptions, + NULL); + if (nextOption == -1) + break; + + switch (nextOption) { + case 'h': // --help + usage(stdout); + return 0; + case 'c': // --check-only + checkOnly = true; + break; + case -1: // done with options + break; + default: // everything else + usage(stderr); + return 1; + } + } + + // the device name should be the only non-option element + if (optind != argc - 1) { + usage(stderr); + return 1; + } + + const char* path = argv[optind]; + //UnregisterFileDevice unregisterFileDevice; + + BDiskDeviceRoster roster; + BPartition* partition; + BDiskDevice device; + + status_t status = roster.GetPartitionForPath(path, &device, + &partition); + if (status != B_OK) { + if (strncmp(path, "/dev", 4)) { + // try mounted volume + status = roster.FindPartitionByMountPoint(path, &device, &partition) + ? B_OK : B_BAD_VALUE; + } + + // TODO: try to register file device + + if (status != B_OK) { + fprintf(stderr, "%s: Failed to get disk device for path \"%s\": " + "%s\n", kProgramName, path, strerror(status)); + return 1; + } + } + + // Prepare the device for modifications + + status = device.PrepareModifications(); + if (status != B_OK) { + fprintf(stderr, "%s: Could not prepare the device for modifications: " + "%s\n", kProgramName, strerror(status)); + return false; + } + + // Check if the partition supports repairing + + bool canRepairWhileMounted; + bool canRepair = partition->CanRepair(checkOnly, &canRepairWhileMounted); + if (!canRepair && !canRepairWhileMounted) { + fprintf(stderr, "%s: The disk system does not support repairing.\n", + kProgramName); + return 1; + } + + if (partition->IsMounted() && !canRepairWhileMounted) { + fprintf(stderr, "%s: The disk system does not support repairing a " + "mounted volume.\n", kProgramName); + return 1; + } + if (!partition->IsMounted() && !canRepair) { + fprintf(stderr, "%s: The disk system does not support repairing a " + "volume that is not mounted.\n", kProgramName); + return 1; + } + + BDiskSystem diskSystem; + status = partition->GetDiskSystem(&diskSystem); + if (status != B_OK) { + fprintf(stderr, "%s: Failed to get disk system for partition: %s\n", + kProgramName, strerror(status)); + return 1; + } + + // Repair the volume + + status = partition->Repair(checkOnly); + if (status != B_OK) { + fprintf(stderr, "%s: Repairing failed: %s\n", kProgramName, + strerror(status)); + return 1; + } + + status = device.CommitModifications(); + + return 0; +} diff --git a/src/kits/storage/disk_device/PartitionDelegate.cpp b/src/kits/storage/disk_device/PartitionDelegate.cpp index bb71d5e5aa..f5cacc5907 100644 --- a/src/kits/storage/disk_device/PartitionDelegate.cpp +++ b/src/kits/storage/disk_device/PartitionDelegate.cpp @@ -163,8 +163,10 @@ BPartition::Delegate::Defragment() status_t BPartition::Delegate::Repair(bool checkOnly) { -// TODO: Implement! - return B_BAD_VALUE; + if (fPartitionHandle == NULL) + return B_NO_INIT; + + return fPartitionHandle->Repair(checkOnly); }