[PATCH] erofs-utils: fsck: fix issues related to --extract=X
Igor Ostapenko
igoreisberg at gmail.com
Fri Jan 28 15:05:11 AEDT 2022
From: Igor Eisberg <igoreisberg at gmail.com>
* Added tar-like default behaviors for --[no-]preserve options:
normal user - uses user's owner ID + umask on perms by default;
root user - preserve original owner IDs + perms by default;
and add appropriate error message when used without --extract=X.
* "--[no-]same-owner" and "--[no-]same-permissions" were renamed
to "--[no-]preserve-owner" and "--[no-]preserve-perms" to
better represent what these options do, the word "same" is
ambiguous and tells nothing to the user ("same" to what?).
* Added "--[no-]preserve" as shortcuts for both options in one.
* Fixed option descriptions as they had typos and were too ambiguous
("extract information" to where? separate file?).
* Added --force option to allow extracting directly to root path.
Signed-off-by: Igor Ostapenko <igoreisberg at gmail.com>
---
fsck/main.c | 104 ++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 77 insertions(+), 27 deletions(-)
diff --git a/fsck/main.c b/fsck/main.c
index 92e0c76..9080a66 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -18,15 +18,21 @@
static int erofsfsck_check_inode(erofs_nid_t pnid, erofs_nid_t nid);
struct erofsfsck_cfg {
+ bool superuser;
+ mode_t umask;
bool corrupted;
+ u64 physical_blocks;
+ u64 logical_blocks;
bool print_comp_ratio;
bool check_decomp;
char *extract_path;
size_t extract_pos;
- bool overwrite, preserve_owner, preserve_perms;
- mode_t umask;
- u64 physical_blocks;
- u64 logical_blocks;
+ bool force;
+ bool overwrite;
+ bool preserve_owner;
+ bool preserve_perms;
+ bool no_preserve_owner;
+ bool no_preserve_perms;
};
static struct erofsfsck_cfg fsckcfg;
@@ -34,11 +40,14 @@ static struct option long_options[] = {
{"help", no_argument, 0, 1},
{"extract", optional_argument, 0, 2},
{"device", required_argument, 0, 3},
- {"no-same-owner", no_argument, 0, 4},
- {"no-same-permissions", no_argument, 0, 5},
- {"same-owner", no_argument, 0, 6},
- {"same-permissions", no_argument, 0, 7},
- {"overwrite", no_argument, 0, 8},
+ {"force", no_argument, 0, 4},
+ {"overwrite", no_argument, 0, 5},
+ {"preserve", no_argument, 0, 6},
+ {"preserve-owner", no_argument, 0, 7},
+ {"preserve-perms", no_argument, 0, 8},
+ {"no-preserve", no_argument, 0, 9},
+ {"no-preserve-owner", no_argument, 0, 10},
+ {"no-preserve-perms", no_argument, 0, 11},
{0, 0, 0, 0},
};
@@ -66,11 +75,16 @@ static void usage(void)
" --extract[=X] check if all files are well encoded, optionally extract to X\n"
" --help display this help and exit\n"
"\nExtraction options (--extract=X is required):\n"
- " --no-same-owner extract files as yourself\n"
- " --no-same-permissions apply the user's umask when extracting permission\n"
- " --same-permissions extract information about file permissions\n"
- " --same-owner extract files about the file ownerships\n"
- " --overwrite if file already exists then overwrite\n"
+ " --force allow extracting to root\n"
+ " --overwrite overwrite files that already exist\n"
+ " --preserve extract with the same ownership and permissions as on the filesystem\n"
+ " (default for superuser)\n"
+ " --preserve-owner extract with the same ownership as on the filesystem\n"
+ " --preserve-perms extract with the same permissions as on the filesystem\n"
+ " --no-preserve extract as yourself and apply user's umask on permissions\n"
+ " (default for ordinary users)\n"
+ " --no-preserve-owner extract as yourself\n"
+ " --no-preserve-perms apply user's umask when extracting permissions\n"
"\nSupported algorithms are: ", stderr);
print_available_decompressors(stderr, ", ");
}
@@ -121,6 +135,9 @@ static int erofsfsck_parse_options_cfg(int argc, char **argv)
return -ENOMEM;
strncpy(fsckcfg.extract_path, optarg, len);
fsckcfg.extract_path[len] = '\0';
+ /* if path is root, start writing from position 0 */
+ if (len == 1 && fsckcfg.extract_path[0] == '/')
+ len = 0;
fsckcfg.extract_pos = len;
}
break;
@@ -131,33 +148,62 @@ static int erofsfsck_parse_options_cfg(int argc, char **argv)
++sbi.extra_devices;
break;
case 4:
- fsckcfg.preserve_owner = false;
+ fsckcfg.force = true;
break;
case 5:
- fsckcfg.preserve_perms = false;
+ fsckcfg.overwrite = true;
break;
case 6:
fsckcfg.preserve_owner = true;
+ fsckcfg.preserve_perms = true;
+ fsckcfg.no_preserve_owner = false;
+ fsckcfg.no_preserve_perms = false;
break;
case 7:
- fsckcfg.preserve_perms = true;
+ fsckcfg.preserve_owner = true;
+ fsckcfg.no_preserve_owner = false;
break;
case 8:
- fsckcfg.overwrite = true;
+ fsckcfg.preserve_perms = true;
+ fsckcfg.no_preserve_perms = false;
+ break;
+ case 9:
+ fsckcfg.no_preserve_owner = true;
+ fsckcfg.no_preserve_perms = true;
+ fsckcfg.preserve_owner = false;
+ fsckcfg.preserve_perms = false;
+ break;
+ case 10:
+ fsckcfg.no_preserve_owner = true;
+ fsckcfg.preserve_owner = false;
+ break;
+ case 11:
+ fsckcfg.no_preserve_perms = true;
+ fsckcfg.preserve_perms = false;
break;
default:
return -EINVAL;
}
}
+ if (fsckcfg.extract_path) {
+ if (!fsckcfg.extract_pos && !fsckcfg.force) {
+ erofs_err("--extract=/ must be used together with --force");
+ return -EINVAL;
+ }
+ } else {
+ if (fsckcfg.force)
+ erofs_err("--force must be used together with --extract=X");
+ if (fsckcfg.overwrite)
+ erofs_err("--overwrite must be used together with --extract=X");
+ if (fsckcfg.preserve_owner || fsckcfg.preserve_perms ||
+ fsckcfg.no_preserve_owner || fsckcfg.no_preserve_perms)
+ erofs_err("--[no-]preserve[-owner/-perms] must be used together with --extract=X");
+ }
+
if (optind >= argc)
return -EINVAL;
- if (!fsckcfg.extract_path)
- if (fsckcfg.overwrite || fsckcfg.preserve_owner ||
- fsckcfg.preserve_perms)
- return -EINVAL;
-
cfg.c_img_path = strdup(argv[optind++]);
if (!cfg.c_img_path)
return -ENOMEM;
@@ -680,13 +726,19 @@ int main(int argc, char **argv)
erofs_init_configure();
+ fsckcfg.superuser = geteuid() == 0;
+ fsckcfg.umask = umask(0);
fsckcfg.corrupted = false;
+ fsckcfg.logical_blocks = 0;
+ fsckcfg.physical_blocks = 0;
fsckcfg.print_comp_ratio = false;
fsckcfg.check_decomp = false;
fsckcfg.extract_path = NULL;
fsckcfg.extract_pos = 0;
- fsckcfg.logical_blocks = 0;
- fsckcfg.physical_blocks = 0;
+ fsckcfg.force = false;
+ fsckcfg.overwrite = false;
+ fsckcfg.preserve_owner = fsckcfg.superuser;
+ fsckcfg.preserve_perms = fsckcfg.superuser;
err = erofsfsck_parse_options_cfg(argc, argv);
if (err) {
@@ -695,8 +747,6 @@ int main(int argc, char **argv)
goto exit;
}
- fsckcfg.umask = umask(0);
-
err = dev_open_ro(cfg.c_img_path);
if (err) {
erofs_err("failed to open image file");
--
2.30.2
More information about the Linux-erofs
mailing list