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>
master
Qu Wenruo 2018-06-20 08:38:38 +08:00 committed by David Sterba
parent 8aee4b000d
commit 7fb70440cf
16 changed files with 32 additions and 0 deletions

View File

@ -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[] = {

View File

@ -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[] = {

View File

@ -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'},

View File

@ -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;

View File

@ -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)

View File

@ -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 };

View File

@ -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':

View File

@ -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 };

View File

@ -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)

View File

@ -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)

View File

@ -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 };

View File

@ -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 '?':

View File

@ -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)

View File

@ -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 };

View File

@ -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[] = {

View File

@ -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:");