@@ -42,6 +42,7 @@
#include <syscall.h>
#include <time.h>
#include <uuid/uuid.h>
+#include <mntent.h>
#include "kernel-lib/sizes.h"
#include "kernel-shared/volumes.h"
#include "common/defs.h"
@@ -1224,6 +1225,34 @@ static u64 write_scrub_device_limit(int fd, u64 devid, u64 limit)
return ret;
}
+/*
+ * Check if given path is a mount read only.
+ *
+ * Return: 1 if yes,
+ * 0 if no,
+ * -1 for error
+ */
+static int path_is_mount_readonly(const char *path){
+ FILE *f;
+ struct mntent *mnt;
+ int ret = -1;
+
+ f = setmntent("/proc/self/mounts", "r");
+ if (f == NULL)
+ return -1;
+ while ((mnt = getmntent(f)) != NULL) {
+ if (strcmp(mnt->mnt_dir, path))
+ continue;
+ if (hasmntopt(mnt, MNTOPT_RO))
+ ret = 1;
+ else
+ ret = 0;
+ break;
+ }
+ endmntent(f);
+ return ret;
+}
+
static int scrub_start(const struct cmd_struct *cmd, int argc, char **argv,
bool resume)
{
@@ -1320,11 +1349,17 @@ static int scrub_start(const struct cmd_struct *cmd, int argc, char **argv,
}
path = argv[optind];
+ if (strlen(path) > 1 && '/' == path[strlen(path)-1])
+ path[strlen(path)-1] = 0;
fdmnt = btrfs_open_mnt(path);
if (fdmnt < 0)
return 1;
+ if (path_is_mount_readonly(path) && !readonly){
+ error("The file system is mounted read-only, but the scrub options do not have an r option.");
+ return 1;
+ }
ret = get_fs_info(path, &fi_args, &di_args);
if (ret) {
errno = -ret;
[enhancement] When scrubbing a filesystem mounted read-only and without r option, it aborts and there is no message associated with it. So we need to print an error message when scrubbing a read-only filesystem to tell the user what is going on here. [implementation] Move the error message from the main thread to each scrub thread, previously the message was printed after all scrub threads finished and without background mode. [test] Mount dev in read-only mode, then scrub it without r option $ sudo mount /dev/vdb -o ro /mnt/ $ sudo btrfs scrub start /mnt/ ERROR: this filesystem is mounted readonly, but scrub option without r option. issue: #666 V1: Output directly within the thread. V2: Use the getmntent() function to obtain a bitmask to check whether the file system is mounted read-only. Signed-off-by: Li Zhang <zhanglikernel@gmail.com> --- cmds/scrub.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+)