mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-12-09 00:00:17 +03:00
bcachefs recovery-passes
New subcommand for scheduling or descheduling recovery passes on an unmounted filesystem. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
cdde2f1160
commit
60ec05df84
@ -46,6 +46,7 @@ void bcachefs_usage(void)
|
||||
"\n"
|
||||
"Repair:\n"
|
||||
" fsck Check an existing filesystem for errors\n"
|
||||
" recovery-pass Schedule or deschedule recovery passes\n"
|
||||
"\n"
|
||||
#if 0
|
||||
"Startup/shutdown, assembly of multi device filesystems:\n"
|
||||
@ -106,18 +107,3 @@ void bcachefs_usage(void)
|
||||
" completions Generate shell completions\n"
|
||||
" version Display the version of the invoked bcachefs tool\n");
|
||||
}
|
||||
|
||||
int fs_cmds(int argc, char *argv[])
|
||||
{
|
||||
char *cmd = pop_cmd(&argc, argv);
|
||||
|
||||
if (argc < 1)
|
||||
return fs_usage();
|
||||
if (!strcmp(cmd, "usage"))
|
||||
return cmd_fs_usage(argc, argv);
|
||||
if (!strcmp(cmd, "top"))
|
||||
return cmd_fs_top(argc, argv);
|
||||
|
||||
fs_usage();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -559,3 +559,18 @@ int cmd_fs_usage(int argc, char *argv[])
|
||||
printbuf_exit(&buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fs_cmds(int argc, char *argv[])
|
||||
{
|
||||
char *cmd = pop_cmd(&argc, argv);
|
||||
|
||||
if (argc < 1)
|
||||
return fs_usage();
|
||||
if (!strcmp(cmd, "usage"))
|
||||
return cmd_fs_usage(argc, argv);
|
||||
if (!strcmp(cmd, "top"))
|
||||
return cmd_fs_top(argc, argv);
|
||||
|
||||
fs_usage();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
126
c_src/cmd_fsck.c
126
c_src/cmd_fsck.c
@ -6,27 +6,11 @@
|
||||
#include "cmds.h"
|
||||
#include "libbcachefs/error.h"
|
||||
#include "libbcachefs.h"
|
||||
#include "libbcachefs/recovery_passes.h"
|
||||
#include "libbcachefs/super.h"
|
||||
#include "libbcachefs/super-io.h"
|
||||
#include "tools-util.h"
|
||||
|
||||
static void fsck_usage(void)
|
||||
{
|
||||
puts("bcachefs fsck - filesystem check and repair\n"
|
||||
"Usage: bcachefs fsck [OPTION]... <devices>\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
" -p Automatic repair (no questions)\n"
|
||||
" -n Don't repair, only check for errors\n"
|
||||
" -y Assume \"yes\" to all questions\n"
|
||||
" -f Force checking even if filesystem is marked clean\n"
|
||||
" -r, --ratelimit_errors Don't display more than 10 errors of a given type\n"
|
||||
" -k, --kernel Use the in-kernel fsck implementation\n"
|
||||
" -v Be verbose\n"
|
||||
" -h, --help Display this help and exit\n"
|
||||
"Report bugs to <linux-bcachefs@vger.kernel.org>");
|
||||
}
|
||||
|
||||
static void setnonblocking(int fd)
|
||||
{
|
||||
int flags = fcntl(fd, F_GETFL);
|
||||
@ -212,6 +196,23 @@ static char *loopdev_alloc(const char *path)
|
||||
return line;
|
||||
}
|
||||
|
||||
static void fsck_usage(void)
|
||||
{
|
||||
puts("bcachefs fsck - filesystem check and repair\n"
|
||||
"Usage: bcachefs fsck [OPTION]... <devices>\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
" -p Automatic repair (no questions)\n"
|
||||
" -n Don't repair, only check for errors\n"
|
||||
" -y Assume \"yes\" to all questions\n"
|
||||
" -f Force checking even if filesystem is marked clean\n"
|
||||
" -r, --ratelimit_errors Don't display more than 10 errors of a given type\n"
|
||||
" -k, --kernel Use the in-kernel fsck implementation\n"
|
||||
" -v Be verbose\n"
|
||||
" -h, --help Display this help and exit\n"
|
||||
"Report bugs to <linux-bcachefs@vger.kernel.org>");
|
||||
}
|
||||
|
||||
int cmd_fsck(int argc, char *argv[])
|
||||
{
|
||||
static const struct option longopts[] = {
|
||||
@ -370,3 +371,94 @@ userland_fsck:
|
||||
printbuf_exit(&opts_str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void recovery_pass_usage(void)
|
||||
{
|
||||
puts("bcachefs recovery-pass - list and manage scheduled recovery passes\n"
|
||||
"Usage: bcachefs recovery-pass [OPTION]... <devices>\n"
|
||||
"\n"
|
||||
"Currently only supports unmounted/offline filesystems\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
" -s, --set Schedule a recovery pass in the superblock\n"
|
||||
" -u, --unset Deschedule a recovery pass\n"
|
||||
" -h, --help Display this help and exit\n"
|
||||
"Report bugs to <linux-bcachefs@vger.kernel.org>");
|
||||
}
|
||||
|
||||
int cmd_recovery_pass(int argc, char *argv[])
|
||||
{
|
||||
static const struct option longopts[] = {
|
||||
{ "set", required_argument, NULL, 's' },
|
||||
{ "unset", required_argument, NULL, 'u' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ NULL }
|
||||
};
|
||||
u64 passes_to_set = 0, passes_to_unset = 0;
|
||||
int opt;
|
||||
|
||||
while ((opt = getopt_long(argc, argv, "s:u:h", longopts, NULL)) != -1)
|
||||
switch (opt) {
|
||||
case 's':
|
||||
passes_to_set |= read_flag_list_or_die(optarg,
|
||||
bch2_recovery_passes,
|
||||
"recovery pass");
|
||||
break;
|
||||
case 'u':
|
||||
passes_to_unset |= read_flag_list_or_die(optarg,
|
||||
bch2_recovery_passes,
|
||||
"recovery pass");
|
||||
break;
|
||||
case 'h':
|
||||
recovery_pass_usage();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
args_shift(optind);
|
||||
|
||||
passes_to_set = bch2_recovery_passes_to_stable(passes_to_set);
|
||||
passes_to_unset = bch2_recovery_passes_to_stable(passes_to_unset);
|
||||
|
||||
darray_const_str devs = get_or_split_cmdline_devs(argc, argv);
|
||||
|
||||
struct bch_opts opts = bch2_opts_empty();
|
||||
opt_set(opts, nostart, true);
|
||||
|
||||
struct bch_fs *c = bch2_fs_open(&devs, &opts);
|
||||
int ret = PTR_ERR_OR_ZERO(c);
|
||||
if (ret)
|
||||
die("Error opening filesystem: %s", bch2_err_str(ret));
|
||||
|
||||
scoped_guard(mutex, &c->sb_lock) {
|
||||
struct bch_sb_field_ext *ext =
|
||||
bch2_sb_field_get_minsize(&c->disk_sb, ext,
|
||||
sizeof(struct bch_sb_field_ext) / sizeof(u64));
|
||||
if (!ext) {
|
||||
fprintf(stderr, "Error getting sb_field_ext\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
u64 scheduled = le64_to_cpu(ext->recovery_passes_required[0]);
|
||||
|
||||
if (passes_to_set || passes_to_unset) {
|
||||
ext->recovery_passes_required[0] &= ~cpu_to_le64(passes_to_unset);
|
||||
ext->recovery_passes_required[0] |= cpu_to_le64(passes_to_set);
|
||||
|
||||
scheduled = le64_to_cpu(ext->recovery_passes_required[0]);
|
||||
|
||||
bch2_write_super(c);
|
||||
}
|
||||
|
||||
CLASS(printbuf, buf)();
|
||||
prt_str(&buf, "Scheduled recovery passes: ");
|
||||
if (scheduled)
|
||||
prt_bitflags(&buf, bch2_recovery_passes,
|
||||
bch2_recovery_passes_from_stable(scheduled));
|
||||
else
|
||||
prt_str(&buf, "(none)");
|
||||
printf("%s\n", buf.buf);
|
||||
}
|
||||
err:
|
||||
bch2_fs_stop(c);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -31,6 +31,7 @@ int cmd_set_passphrase(int argc, char *argv[]);
|
||||
int cmd_remove_passphrase(int argc, char *argv[]);
|
||||
|
||||
int cmd_fsck(int argc, char *argv[]);
|
||||
int cmd_recovery_pass(int argc, char *argv[]);
|
||||
|
||||
int cmd_dump(int argc, char *argv[]);
|
||||
int cmd_list_journal(int argc, char *argv[]);
|
||||
|
||||
@ -49,6 +49,7 @@ fn handle_c_command(mut argv: Vec<String>, symlink_cmd: Option<&str>) -> i32 {
|
||||
"format" => c::cmd_format(argc, argv),
|
||||
"fs" => c::fs_cmds(argc, argv),
|
||||
"fsck" => c::cmd_fsck(argc, argv),
|
||||
"recovery-pass" => c::cmd_recovery_pass(argc, argv),
|
||||
"image" => c::image_cmds(argc, argv),
|
||||
"list_journal" => c::cmd_list_journal(argc, argv),
|
||||
"kill_btree_node" => c::cmd_kill_btree_node(argc, argv),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user