summaryrefslogtreecommitdiff
path: root/cmds-check.c
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.cz>2017-08-31 18:34:37 +0200
committerDavid Sterba <dsterba@suse.com>2017-09-08 16:15:05 +0200
commit162fdf95383bd6685cce17f9c52cc858fef2c09c (patch)
tree8c767bcce1ce252a6740438a3c3bb0c3dd4f9768 /cmds-check.c
parent8609c8bad68528f668d9ce564b868aa4828107a0 (diff)
btrfs-progs: check: add option to skip mount checks
Sometimes it's needed to do a check on a mounted filesystem. This should work fine on a quiescent filesystem or a read-only mount. Changes on the block device done by kernel might confuse the userspace checker and it might crash when it reads some stale data. Repair without mount checks is not supported right now. Signed-off-by: David Sterba <dsterba@suse.cz>
Diffstat (limited to 'cmds-check.c')
-rw-r--r--cmds-check.c50
1 files changed, 39 insertions, 11 deletions
diff --git a/cmds-check.c b/cmds-check.c
index a633d044..006edbde 100644
--- a/cmds-check.c
+++ b/cmds-check.c
@@ -12730,6 +12730,7 @@ const char * const cmd_check_usage[] = {
"",
"-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",
@@ -12761,7 +12762,7 @@ int cmd_check(int argc, char **argv)
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;
@@ -12770,13 +12771,15 @@ int cmd_check(int argc, char **argv)
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 },
@@ -12798,6 +12801,7 @@ int cmd_check(int argc, char **argv)
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}
};
@@ -12882,6 +12886,9 @@ int cmd_check(int argc, char **argv)
}
ctree_flags |= OPEN_CTREE_WRITES;
break;
+ case GETOPT_VAL_FORCE:
+ force = 1;
+ break;
}
}
@@ -12910,15 +12917,36 @@ int cmd_check(int argc, char **argv)
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 */