static int parse_filters(char *filters, struct btrfs_balance_args *args) { char *this_char; char *value; char *save_ptr = NULL; /* Satisfy static checkers */ if (!filters) return 0; for (this_char = strtok_r(filters, ",", &save_ptr); this_char != NULL; this_char = strtok_r(NULL, ",", &save_ptr)) { if ((value = strchr(this_char, '=')) != NULL) *value++ = 0; if (!strcmp(this_char, "profiles")) { if (!value || !*value) { error("the profiles filter requires an argument"); return 1; } if (parse_profiles(value, &args->profiles)) { error("invalid profiles argument"); return 1; } args->flags |= BTRFS_BALANCE_ARGS_PROFILES; } else if (!strcmp(this_char, "usage")) { if (!value || !*value) { error("the usage filter requires an argument"); return 1; } if (parse_u64(value, &args->usage)) { if (parse_range_u32(value, &args->usage_min, &args->usage_max)) { error("invalid usage argument: %s", value); return 1; } if (args->usage_max > 100) { error("invalid usage argument: %s", value); } args->flags &= ~BTRFS_BALANCE_ARGS_USAGE; args->flags |= BTRFS_BALANCE_ARGS_USAGE_RANGE; } else { if (args->usage > 100) { error("invalid usage argument: %s", value); return 1; } args->flags &= ~BTRFS_BALANCE_ARGS_USAGE_RANGE; args->flags |= BTRFS_BALANCE_ARGS_USAGE; } args->flags |= BTRFS_BALANCE_ARGS_USAGE; } else if (!strcmp(this_char, "devid")) { if (!value || !*value) { error("the devid filter requires an argument"); return 1; } if (parse_u64(value, &args->devid) || args->devid == 0) { error("invalid devid argument: %s", value); return 1; } args->flags |= BTRFS_BALANCE_ARGS_DEVID; } else if (!strcmp(this_char, "drange")) { if (!value || !*value) { error("the drange filter requires an argument"); return 1; } if (parse_range_strict(value, &args->pstart, &args->pend)) { error("invalid drange argument"); return 1; } args->flags |= BTRFS_BALANCE_ARGS_DRANGE; } else if (!strcmp(this_char, "vrange")) { if (!value || !*value) { error("the vrange filter requires an argument"); return 1; } if (parse_range_strict(value, &args->vstart, &args->vend)) { error("invalid vrange argument"); return 1; } args->flags |= BTRFS_BALANCE_ARGS_VRANGE; } else if (!strcmp(this_char, "convert")) { if (!value || !*value) { error("the convert option requires an argument"); return 1; } if (parse_one_profile(value, &args->target)) { error("invalid convert argument"); return 1; } args->flags |= BTRFS_BALANCE_ARGS_CONVERT; } else if (!strcmp(this_char, "soft")) { args->flags |= BTRFS_BALANCE_ARGS_SOFT; } else if (!strcmp(this_char, "limit")) { if (!value || !*value) { error("the limit filter requires an argument"); return 1; } if (parse_u64(value, &args->limit)) { if (parse_range_u32(value, &args->limit_min, &args->limit_max)) { error("Invalid limit argument: %s", value); return 1; } args->flags &= ~BTRFS_BALANCE_ARGS_LIMIT; args->flags |= BTRFS_BALANCE_ARGS_LIMIT_RANGE; } else { args->flags &= ~BTRFS_BALANCE_ARGS_LIMIT_RANGE; args->flags |= BTRFS_BALANCE_ARGS_LIMIT; } } else if (!strcmp(this_char, "stripes")) { if (!value || !*value) { error("the stripes filter requires an argument"); return 1; } if (parse_range_u32(value, &args->stripes_min, &args->stripes_max)) { error("invalid stripes argument"); return 1; } args->flags |= BTRFS_BALANCE_ARGS_STRIPES_RANGE; } else { error("unrecognized balance option: %s", this_char); return 1; } } return 0; }
static int parse_filters(char *filters, struct btrfs_balance_args *args) { char *this_char; char *value; char *save_ptr = NULL; /* Satisfy static checkers */ if (!filters) return 0; for (this_char = strtok_r(filters, ",", &save_ptr); this_char != NULL; this_char = strtok_r(NULL, ",", &save_ptr)) { if ((value = strchr(this_char, '=')) != NULL) *value++ = 0; if (!strcmp(this_char, "profiles")) { if (!value || !*value) { fprintf(stderr, "the profiles filter requires " "an argument\n"); return 1; } if (parse_profiles(value, &args->profiles)) { fprintf(stderr, "Invalid profiles argument\n"); return 1; } args->flags |= BTRFS_BALANCE_ARGS_PROFILES; } else if (!strcmp(this_char, "usage")) { if (!value || !*value) { fprintf(stderr, "the usage filter requires " "an argument\n"); return 1; } if (parse_u64(value, &args->usage) || args->usage > 100) { fprintf(stderr, "Invalid usage argument: %s\n", value); return 1; } args->flags |= BTRFS_BALANCE_ARGS_USAGE; } else if (!strcmp(this_char, "devid")) { if (!value || !*value) { fprintf(stderr, "the devid filter requires " "an argument\n"); return 1; } if (parse_u64(value, &args->devid) || args->devid == 0) { fprintf(stderr, "Invalid devid argument: %s\n", value); return 1; } args->flags |= BTRFS_BALANCE_ARGS_DEVID; } else if (!strcmp(this_char, "drange")) { if (!value || !*value) { fprintf(stderr, "the drange filter requires " "an argument\n"); return 1; } if (parse_range(value, &args->pstart, &args->pend)) { fprintf(stderr, "Invalid drange argument\n"); return 1; } args->flags |= BTRFS_BALANCE_ARGS_DRANGE; } else if (!strcmp(this_char, "vrange")) { if (!value || !*value) { fprintf(stderr, "the vrange filter requires " "an argument\n"); return 1; } if (parse_range(value, &args->vstart, &args->vend)) { fprintf(stderr, "Invalid vrange argument\n"); return 1; } args->flags |= BTRFS_BALANCE_ARGS_VRANGE; } else if (!strcmp(this_char, "convert")) { if (!value || !*value) { fprintf(stderr, "the convert option requires " "an argument\n"); return 1; } if (parse_one_profile(value, &args->target)) { fprintf(stderr, "Invalid convert argument\n"); return 1; } args->flags |= BTRFS_BALANCE_ARGS_CONVERT; } else if (!strcmp(this_char, "soft")) { args->flags |= BTRFS_BALANCE_ARGS_SOFT; } else { fprintf(stderr, "Unrecognized balance option '%s'\n", this_char); return 1; } } return 0; }