btrfs-progs: Fix wrong optind re-initialization to allow mixed option and non-option
In function handle_global_options(), we reset @optind to 1.
However according to man page of getopt(3) NOTES section, if we need to
rescan options later, @optind should be reset to 0 to initialize the
internal variables correctly.
This explains the reason why in cmd_check(), getopt_long() doesn't
handle the following command correctly:
"btrfs check /dev/data/btrfs --check-data-csum"
While mkfs.btrfs handles mixed non-option and option correctly:
"mkfs.btrfs -f /dev/data/disk1 --data raid1 /dev/data/disk2"
Cc: Paul Jones <paul@pauljones.id.au>
Cc: Hugo Mills <hugo@carfax.org.uk>
Fixes: 010ceab56e
("btrfs-progs: rework option parser to use getopt for global options")
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
8aee4b000d
commit
7fb70440cf
|
@ -528,6 +528,7 @@ static int cmd_balance_start(int argc, char **argv)
|
|||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
enum { GETOPT_VAL_FULL_BALANCE = 256,
|
||||
GETOPT_VAL_BACKGROUND = 257 };
|
||||
|
@ -831,6 +832,7 @@ static int cmd_balance_status(int argc, char **argv)
|
|||
int verbose = 0;
|
||||
int ret;
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int opt;
|
||||
static const struct option longopts[] = {
|
||||
|
|
|
@ -57,6 +57,7 @@ static int cmd_device_add(int argc, char **argv)
|
|||
int force = 0;
|
||||
int last_dev;
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int c;
|
||||
static const struct option long_options[] = {
|
||||
|
@ -267,6 +268,7 @@ static int cmd_device_scan(int argc, char **argv)
|
|||
int all = 0;
|
||||
int ret = 0;
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int c;
|
||||
static const struct option long_options[] = {
|
||||
|
@ -403,6 +405,7 @@ static int cmd_device_stats(int argc, char **argv)
|
|||
__u64 flags = 0;
|
||||
DIR *dirstream = NULL;
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int c;
|
||||
static const struct option long_options[] = {
|
||||
|
|
|
@ -565,6 +565,7 @@ int cmd_filesystem_du(int argc, char **argv)
|
|||
|
||||
unit_mode = get_unit_mode_from_arg(&argc, argv, 1);
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
static const struct option long_options[] = {
|
||||
{ "summarize", no_argument, NULL, 's'},
|
||||
|
|
|
@ -974,6 +974,7 @@ int cmd_filesystem_usage(int argc, char **argv)
|
|||
|
||||
unit_mode = get_unit_mode_from_arg(&argc, argv, 1);
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int c;
|
||||
|
||||
|
|
|
@ -685,6 +685,7 @@ static int cmd_filesystem_show(int argc, char **argv)
|
|||
|
||||
unit_mode = get_unit_mode_from_arg(&argc, argv, 0);
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int c;
|
||||
static const struct option long_options[] = {
|
||||
|
@ -924,6 +925,7 @@ static int cmd_filesystem_defrag(int argc, char **argv)
|
|||
defrag_global_errors = 0;
|
||||
defrag_global_verbose = 0;
|
||||
defrag_global_errors = 0;
|
||||
optind = 0;
|
||||
while(1) {
|
||||
int c = getopt(argc, argv, "vrc::fs:l:t:");
|
||||
if (c < 0)
|
||||
|
|
|
@ -235,6 +235,7 @@ int cmd_inspect_dump_tree(int argc, char **argv)
|
|||
* tree blocks as possible.
|
||||
*/
|
||||
open_ctree_flags = OPEN_CTREE_PARTIAL | OPEN_CTREE_NO_BLOCK_GROUPS;
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int c;
|
||||
enum { GETOPT_VAL_FOLLOW = 256 };
|
||||
|
|
|
@ -434,6 +434,7 @@ int cmd_inspect_tree_stats(int argc, char **argv)
|
|||
int opt;
|
||||
int ret = 0;
|
||||
|
||||
optind = 0;
|
||||
while ((opt = getopt(argc, argv, "vb")) != -1) {
|
||||
switch (opt) {
|
||||
case 'v':
|
||||
|
|
|
@ -94,6 +94,7 @@ static int cmd_inspect_inode_resolve(int argc, char **argv)
|
|||
int ret;
|
||||
DIR *dirstream = NULL;
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int c = getopt(argc, argv, "v");
|
||||
if (c < 0)
|
||||
|
@ -148,6 +149,7 @@ static int cmd_inspect_logical_resolve(int argc, char **argv)
|
|||
char *path_ptr;
|
||||
DIR *dirstream = NULL;
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int c = getopt(argc, argv, "Pvs:");
|
||||
if (c < 0)
|
||||
|
@ -591,6 +593,7 @@ static int cmd_inspect_min_dev_size(int argc, char **argv)
|
|||
DIR *dirstream = NULL;
|
||||
u64 devid = 1;
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int c;
|
||||
enum { GETOPT_VAL_DEVID = 256 };
|
||||
|
|
|
@ -46,6 +46,7 @@ static int _cmd_qgroup_assign(int assign, int argc, char **argv,
|
|||
DIR *dirstream = NULL;
|
||||
|
||||
if (assign) {
|
||||
optind = 0;
|
||||
while (1) {
|
||||
enum { GETOPT_VAL_RESCAN = 256, GETOPT_VAL_NO_RESCAN };
|
||||
static const struct option long_options[] = {
|
||||
|
@ -310,6 +311,7 @@ static int cmd_qgroup_show(int argc, char **argv)
|
|||
|
||||
unit_mode = get_unit_mode_from_arg(&argc, argv, 0);
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int c;
|
||||
enum {
|
||||
|
@ -429,6 +431,7 @@ static int cmd_qgroup_limit(int argc, char **argv)
|
|||
DIR *dirstream = NULL;
|
||||
enum btrfs_util_error err;
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int c = getopt(argc, argv, "ce");
|
||||
if (c < 0)
|
||||
|
|
|
@ -119,6 +119,7 @@ static int cmd_quota_rescan(int argc, char **argv)
|
|||
DIR *dirstream = NULL;
|
||||
int wait_for_completion = 0;
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int c = getopt(argc, argv, "sw");
|
||||
if (c < 0)
|
||||
|
|
|
@ -1267,6 +1267,7 @@ int cmd_receive(int argc, char **argv)
|
|||
realmnt[0] = 0;
|
||||
fromfile[0] = 0;
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int c;
|
||||
enum { GETOPT_VAL_DUMP = 257 };
|
||||
|
|
|
@ -134,6 +134,7 @@ static int cmd_replace_start(int argc, char **argv)
|
|||
u64 srcdev_size;
|
||||
u64 dstdev_size;
|
||||
|
||||
optind = 0;
|
||||
while ((c = getopt(argc, argv, "Brf")) != -1) {
|
||||
switch (c) {
|
||||
case 'B':
|
||||
|
@ -333,6 +334,7 @@ static int cmd_replace_status(int argc, char **argv)
|
|||
int ret;
|
||||
DIR *dirstream = NULL;
|
||||
|
||||
optind = 0;
|
||||
while ((c = getopt(argc, argv, "1")) != -1) {
|
||||
switch (c) {
|
||||
case '1':
|
||||
|
@ -501,6 +503,7 @@ static int cmd_replace_cancel(int argc, char **argv)
|
|||
char *path;
|
||||
DIR *dirstream = NULL;
|
||||
|
||||
optind = 0;
|
||||
while ((c = getopt(argc, argv, "")) != -1) {
|
||||
switch (c) {
|
||||
case '?':
|
||||
|
|
|
@ -52,6 +52,7 @@ static int cmd_rescue_chunk_recover(int argc, char *argv[])
|
|||
int yes = 0;
|
||||
int verbose = 0;
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int c = getopt(argc, argv, "yvh");
|
||||
if (c < 0)
|
||||
|
@ -119,6 +120,7 @@ static int cmd_rescue_super_recover(int argc, char **argv)
|
|||
int yes = 0;
|
||||
char *dname;
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int c = getopt(argc, argv, "vy");
|
||||
if (c < 0)
|
||||
|
|
|
@ -1440,6 +1440,7 @@ int cmd_restore(int argc, char **argv)
|
|||
regex_t match_reg, *mreg = NULL;
|
||||
char reg_err[256];
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int opt;
|
||||
enum { GETOPT_VAL_PATH_REGEX = 256 };
|
||||
|
|
|
@ -508,6 +508,7 @@ int cmd_send(int argc, char **argv)
|
|||
send.dump_fd = fileno(stdout);
|
||||
outname[0] = 0;
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
enum { GETOPT_VAL_SEND_NO_DATA = 256 };
|
||||
static const struct option long_options[] = {
|
||||
|
|
|
@ -102,6 +102,7 @@ static int cmd_subvol_create(int argc, char **argv)
|
|||
struct btrfs_qgroup_inherit *inherit = NULL;
|
||||
DIR *dirstream = NULL;
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int c = getopt(argc, argv, "c:i:");
|
||||
if (c < 0)
|
||||
|
@ -248,6 +249,7 @@ static int cmd_subvol_delete(int argc, char **argv)
|
|||
enum { COMMIT_AFTER = 1, COMMIT_EACH = 2 };
|
||||
enum btrfs_util_error err;
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int c;
|
||||
static const struct option long_options[] = {
|
||||
|
@ -466,6 +468,7 @@ static int cmd_subvol_list(int argc, char **argv)
|
|||
filter_set = btrfs_list_alloc_filter_set();
|
||||
comparer_set = btrfs_list_alloc_comparer_set();
|
||||
|
||||
optind = 0;
|
||||
while(1) {
|
||||
int c;
|
||||
static const struct option long_options[] = {
|
||||
|
@ -636,6 +639,7 @@ static int cmd_subvol_snapshot(int argc, char **argv)
|
|||
DIR *dirstream1 = NULL, *dirstream2 = NULL;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int c = getopt(argc, argv, "c:i:r");
|
||||
if (c < 0)
|
||||
|
@ -933,6 +937,7 @@ static int cmd_subvol_show(int argc, char **argv)
|
|||
char *subvol_path = NULL;
|
||||
enum btrfs_util_error err;
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int c;
|
||||
static const struct option long_options[] = {
|
||||
|
@ -1132,6 +1137,7 @@ static int cmd_subvol_sync(int argc, char **argv)
|
|||
int sleep_interval = 1;
|
||||
enum btrfs_util_error err;
|
||||
|
||||
optind = 0;
|
||||
while (1) {
|
||||
int c = getopt(argc, argv, "s:");
|
||||
|
||||
|
|
Loading…
Reference in a new issue