struct btrfs_key key;
struct walk_control wc;
struct extent_buffer *leaf, *tree_node;
- struct btrfs_root *root = fs_info->fs_root;
struct btrfs_root *tmp_root;
- struct btrfs_root *tree_root = root->fs_info->tree_root;
+ struct btrfs_root *tree_root = fs_info->tree_root;
int ret;
int err = 0;
* reflected into the free space cache yet.
*/
if (repair)
- reset_cached_block_groups(root->fs_info);
+ reset_cached_block_groups(fs_info);
memset(&wc, 0, sizeof(wc));
cache_tree_init(&wc.shared);
btrfs_init_path(&path);
fs_root_objectid(key.objectid)) {
if (key.objectid == BTRFS_TREE_RELOC_OBJECTID) {
tmp_root = btrfs_read_fs_root_no_cache(
- root->fs_info, &key);
+ fs_info, &key);
} else {
key.offset = (u64)-1;
tmp_root = btrfs_read_fs_root(
- root->fs_info, &key);
+ fs_info, &key);
}
if (IS_ERR(tmp_root)) {
err = 1;
return err;
}
+static int do_check_fs_roots(struct btrfs_fs_info *fs_info,
+ struct cache_tree *root_cache)
+{
+ int ret;
+
+ if (!ctx.progress_enabled)
+ fprintf(stderr, "checking fs roots\n");
+ if (check_mode == CHECK_MODE_LOWMEM)
+ ret = check_fs_roots_v2(fs_info);
+ else
+ ret = check_fs_roots(fs_info, root_cache);
+
+ return ret;
+}
+
static int all_backpointers_checked(struct extent_record *rec, int print_errs)
{
struct list_head *cur = rec->backrefs.next;
"",
"-s|--super <superblock> use this superblock copy",
"-b|--backup use the first valid backup root copy",
+ "--force skip mount checks, repair is not possible",
"--repair try to repair the filesystem",
"--readonly run in read-only mode (default)",
"--init-csum-tree create a new CRC tree",
u64 tree_root_bytenr = 0;
u64 chunk_root_bytenr = 0;
char uuidbuf[BTRFS_UUID_UNPARSED_SIZE];
- int ret;
+ int ret = 0;
int err = 0;
u64 num;
int init_csum_tree = 0;
int qgroup_report = 0;
int qgroups_repaired = 0;
unsigned ctree_flags = OPEN_CTREE_EXCLUSIVE;
+ int force = 0;
while(1) {
int c;
enum { GETOPT_VAL_REPAIR = 257, GETOPT_VAL_INIT_CSUM,
GETOPT_VAL_INIT_EXTENT, GETOPT_VAL_CHECK_CSUM,
GETOPT_VAL_READONLY, GETOPT_VAL_CHUNK_TREE,
- GETOPT_VAL_MODE, GETOPT_VAL_CLEAR_SPACE_CACHE };
+ GETOPT_VAL_MODE, GETOPT_VAL_CLEAR_SPACE_CACHE,
+ GETOPT_VAL_FORCE };
static const struct option long_options[] = {
{ "super", required_argument, NULL, 's' },
{ "repair", no_argument, NULL, GETOPT_VAL_REPAIR },
GETOPT_VAL_MODE },
{ "clear-space-cache", required_argument, NULL,
GETOPT_VAL_CLEAR_SPACE_CACHE},
+ { "force", no_argument, NULL, GETOPT_VAL_FORCE },
{ NULL, 0, NULL, 0}
};
}
ctree_flags |= OPEN_CTREE_WRITES;
break;
+ case GETOPT_VAL_FORCE:
+ force = 1;
+ break;
}
}
radix_tree_init();
cache_tree_init(&root_cache);
- if((ret = check_mounted(argv[optind])) < 0) {
- error("could not check mount status: %s", strerror(-ret));
- err |= !!ret;
- goto err_out;
- } else if(ret) {
- error("%s is currently mounted, aborting", argv[optind]);
- ret = -EBUSY;
- err |= !!ret;
- goto err_out;
+ ret = check_mounted(argv[optind]);
+ if (!force) {
+ if (ret < 0) {
+ error("could not check mount status: %s",
+ strerror(-ret));
+ err |= !!ret;
+ goto err_out;
+ } else if (ret) {
+ error(
+"%s is currently mounted, use --force if you really intend to check the filesystem",
+ argv[optind]);
+ ret = -EBUSY;
+ err |= !!ret;
+ goto err_out;
+ }
+ } else {
+ if (repair) {
+ error("repair and --force is not yet supported");
+ ret = 1;
+ err |= !!ret;
+ goto err_out;
+ }
+ if (ret < 0) {
+ warning(
+"cannot check mount status of %s, the filesystem could be mounted, continuing because of --force",
+ argv[optind]);
+ } else if (ret) {
+ warning(
+ "filesystem mounted, continuing because of --force");
+ }
}
/* only allow partial opening under repair mode */
* ignore it when this happens.
*/
no_holes = btrfs_fs_incompat(root->fs_info, NO_HOLES);
- if (!ctx.progress_enabled)
- fprintf(stderr, "checking fs roots\n");
- if (check_mode == CHECK_MODE_LOWMEM)
- ret = check_fs_roots_v2(root->fs_info);
- else
- ret = check_fs_roots(info, &root_cache);
+ ret = do_check_fs_roots(info, &root_cache);
err |= !!ret;
if (ret) {
error("errors found in fs roots");