X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Futils%2Flfs.c;h=dc07fb97d1750f4681555d98631bdf2c9ea4066b;hp=0eaaf7e39e1ad147e94cff8d13fb359a9b1c5fa0;hb=a8dcf372f430c308d3e96fb506563068d0a80c2d;hpb=8e6c461eba6cb4210bb399180ce831788d78e003 diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 0eaaf7e..dc07fb9 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -65,8 +65,8 @@ #include #include #include -#include -#include +#include +#include #ifndef ARRAY_SIZE # define ARRAY_SIZE(a) ((sizeof(a)) / (sizeof((a)[0]))) @@ -187,6 +187,7 @@ command_t cmdlist[] = { " \n" "\tcomp_id: Unique component ID\n" "\tcomp_flags: 'init' indicating all instantiated components\n" + "\t '^init' indicating all uninstantiated components\n" "\t-I and -F can't be specified at the same time\n" " or\n" "To add component(s) to an existing composite file:\n" @@ -200,13 +201,13 @@ command_t cmdlist[] = { "usage: getstripe [--ost|-O ] [--quiet|-q] [--verbose|-v]\n" " [--stripe-count|-c] [--stripe-index|-i]\n" " [--pool|-p] [--stripe-size|-S] [--directory|-d]\n" - " [--mdt|-m] [--recursive|-r] [--raw|-R]\n" + " [--mdt|-m] [--recursive|-r] [--raw|-R] [--yaml|-y]\n" " [--layout|-L] [--fid|-F] [--generation|-g]\n" - " [--component-id|-I [comp_id]]\n" - " [--component-flags [comp_flags]]\n" - " [--component-count [comp_count]]\n" - " [--component-start [comp_start]]\n" - " [--component-end|-E [comp_end]]\n" + " [--component-id[=comp_id]|-I[comp_id]]\n" + " [--component-flags[=comp_flags]]\n" + " [--component-count]\n" + " [--component-start[=[+-]comp_start]]\n" + " [--component-end[=[+-]comp_end]|-E[[+-]comp_end]]\n" " ..."}, {"setdirstripe", lfs_setdirstripe, 0, "To create a striped directory on a specified MDT. This can only\n" @@ -217,8 +218,9 @@ command_t cmdlist[] = { "To list the striping info for a given directory\n" "or recursively for all directories in a directory tree.\n" "usage: getdirstripe [--obd|-O ] [--mdt-count|-c]\n" - " [--mdt-index|-i] [--mdt-hash|-H]\n" - " [--recursive|-r] [--default|-D] ..."}, + " [--mdt-index|-i] [--mdt-hash|-t]\n" + " [--recursive|-r] [--yaml|-y]\n" + " [--default|-D] ..."}, {"mkdir", lfs_setdirstripe, 0, "To create a striped directory on a specified MDT. This can only\n" "be done on MDT0 with the right of administrator.\n" @@ -246,6 +248,7 @@ command_t cmdlist[] = { " [[!] --stripe-size|-S [+-]N[kMGT]] [[!] --type|-t ]\n" " [[!] --gid|-g|--group|-G |]\n" " [[!] --uid|-u|--user|-U |] [[!] --pool ]\n" + " [[!] --projid ]\n" " [[!] --layout|-L released,raid0]\n" " [[!] --component-count [+-]]\n" " [[!] --component-start [+-]N[kMGTPE]]\n" @@ -254,8 +257,8 @@ command_t cmdlist[] = { " [[!] --mdt-count|-T [+-]]\n" " [[!] --mdt-hash|-H \n" "\t !: used before an option indicates 'NOT' requested attribute\n" - "\t -: used before a value indicates 'AT MOST' requested value\n" - "\t +: used before a value indicates 'AT LEAST' requested value\n" + "\t -: used before a value indicates less than requested value\n" + "\t +: used before a value indicates more than requested value\n" "\tmdt-hash: hash type of the striped directory.\n" "\t fnv_1a_64 FNV-1a hash algorithm\n" "\t all_char sum of characters % MDT_COUNT\n"}, @@ -279,12 +282,12 @@ command_t cmdlist[] = { "usage: setquota <-u|-g|-p> ||||\n" " -b -B \n" " -i -I \n" - " setquota <-u|--user|-g|--group|-p|--project> ||||\n" + " setquota <-u|--user|-g|--group|-p|--projid> ||||\n" " [--block-softlimit ]\n" " [--block-hardlimit ]\n" " [--inode-softlimit ]\n" " [--inode-hardlimit ] \n" - " setquota [-t] <-u|--user|-g|--group|-p|--project>\n" + " setquota [-t] <-u|--user|-g|--group|-p|--projid>\n" " [--block-grace ]\n" " [--inode-grace ] \n" " -b can be used instead of --block-softlimit/--block-grace\n" @@ -397,9 +400,10 @@ command_t cmdlist[] = { {"ladvise", lfs_ladvise, 0, "Provide servers with advice about access patterns for a file.\n" "usage: ladvise [--advice|-a ADVICE] [--start|-s START[kMGT]]\n" - " [--background|-b]\n" + " [--background|-b] [--unset|-u]\n\n" " {[--end|-e END[kMGT]] | [--length|-l LENGTH[kMGT]]}\n" - " ..."}, + " {[--mode|-m [READ,WRITE]}\n" + " ...\n"}, {"help", Parser_help, 0, "help"}, {"exit", Parser_quit, 0, "quit"}, {"quit", Parser_quit, 0, "quit"}, @@ -682,13 +686,12 @@ static int lfs_component_del(char *fname, __u32 comp_id, __u32 flags) fprintf(stderr, "Invalid component flags %#x\n", flags); return -EINVAL; } - comp_id = LCME_ID_NONE | flags; } else if (comp_id > LCME_ID_MAX) { fprintf(stderr, "Invalid component id %u\n", comp_id); return -EINVAL; } - rc = llapi_layout_file_comp_del(fname, comp_id); + rc = llapi_layout_file_comp_del(fname, comp_id, flags); if (rc) fprintf(stderr, "Delete component %#x from %s failed. %s\n", comp_id, fname, strerror(errno)); @@ -1007,48 +1010,8 @@ static int parse_targets(__u32 *osts, int size, int offset, char *arg) return rc < 0 ? rc : nr; } -static int verify_pool_name(char *prog_name, char *pool_name) -{ - char *ptr; - int rc; - - if (pool_name == NULL) - return 0; - - ptr = strchr(pool_name, '.'); - if (ptr == NULL) { - ptr = pool_name; - } else { - if (ptr == pool_name) { - fprintf(stderr, "error: %s: fsname is empty " - "in pool name '%s'\n", - prog_name, pool_name); - return -EINVAL; - } - ++ptr; - } - - rc = lustre_is_poolname_valid(ptr, 1, LOV_MAXPOOLNAME); - if (rc == -1) { - fprintf(stderr, "error: %s: poolname '%s' is empty\n", - prog_name, pool_name); - return -EINVAL; - } else if (rc == -2) { - fprintf(stderr, "error: %s: pool name '%s' is too long " - "(max is %d characters)\n", - prog_name, pool_name, LOV_MAXPOOLNAME); - return -EINVAL; - } else if (rc > 0) { - fprintf(stderr, "error: %s: char '%c' not allowed in " - "pool name '%s'\n", - prog_name, rc, pool_name); - return -EINVAL; - } - return rc; -} - struct lfs_setstripe_args { - __u64 lsa_comp_end; + unsigned long long lsa_comp_end; unsigned long long lsa_stripe_size; int lsa_stripe_count; int lsa_stripe_off; @@ -1181,14 +1144,24 @@ static int adjust_first_extent(char *fname, struct llapi_layout *layout) if (layout == NULL) return -EINVAL; + errno = 0; head = llapi_layout_get_by_path(fname, 0); if (head == NULL) { fprintf(stderr, "Read layout from %s failed. %s\n", fname, strerror(errno)); return -EINVAL; + } else if (errno == ENODATA) { + /* file without LOVEA, this component-add will be turned + * into a component-create. */ + llapi_layout_free(head); + return -ENODATA; + } else if (!llapi_layout_is_composite(head)) { + fprintf(stderr, "'%s' isn't a composite file.\n", + fname); + llapi_layout_free(head); + return -EINVAL; } - /* Current component of 'head' should be tail of component list. */ rc = llapi_layout_comp_extent_get(head, &start, &prev_end); if (rc) { fprintf(stderr, "Get prev extent failed. %s\n", @@ -1200,7 +1173,7 @@ static int adjust_first_extent(char *fname, struct llapi_layout *layout) llapi_layout_free(head); /* Make sure we use the first component of the layout to be added. */ - rc = llapi_layout_comp_move(layout, LLAPI_LAYOUT_COMP_POS_FIRST); + rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST); if (rc < 0) { fprintf(stderr, "Move component cursor failed. %s\n", strerror(errno)); @@ -1244,24 +1217,73 @@ static int adjust_first_extent(char *fname, struct llapi_layout *layout) return 0; } -static int comp_name2flags(__u32 *flags, char *name) +static inline bool comp_flags_is_neg(__u32 flags) { - char *ptr; + return flags & LCME_FL_NEG; +} - if (name == NULL) +static inline void comp_flags_set_neg(__u32 *flags) +{ + *flags |= LCME_FL_NEG; +} + +static inline void comp_flags_clear_neg(__u32 *flags) +{ + *flags &= ~LCME_FL_NEG; +} + +static int comp_str2flags(__u32 *flags, char *string) +{ + char *name; + __u32 neg_flags = 0; + + if (string == NULL) return -EINVAL; *flags = 0; - for (ptr = name; ; ptr = NULL) { - char *flg = strtok(ptr, ","); - if (flg == NULL) - break; - if (strcmp(flg, "init") == 0) - *flags |= LCME_FL_INIT; - else + for (name = strtok(string, ","); name; name = strtok(NULL, ",")) { + bool found = false; + int i; + + for (i = 0; i < ARRAY_SIZE(comp_flags_table); i++) { + __u32 comp_flag = comp_flags_table[i].cfn_flag; + const char *comp_name = comp_flags_table[i].cfn_name; + + if (strcmp(name, comp_name) == 0) { + *flags |= comp_flag; + found = true; + } else if (strncmp(name, "^", 1) == 0 && + strcmp(name + 1, comp_name) == 0) { + neg_flags |= comp_flag; + found = true; + } + } + if (!found) { + llapi_printf(LLAPI_MSG_ERROR, "Component flag " + "'%s' is not supported.\n", name); return -EINVAL; + } } - return (*flags == 0) ? -EINVAL : 0; + + if (*flags == 0 && neg_flags == 0) + return -EINVAL; + /* don't support mixed flags for now */ + if (*flags && neg_flags) + return -EINVAL; + + if (neg_flags) { + *flags = neg_flags; + comp_flags_set_neg(flags); + } + + return 0; +} + +static inline bool arg_is_eof(char *arg) +{ + return !strncmp(arg, "-1", strlen("-1")) || + !strncmp(arg, "EOF", strlen("EOF")) || + !strncmp(arg, "eof", strlen("eof")); } enum { @@ -1271,7 +1293,8 @@ enum { LFS_COMP_FLAGS_OPT, LFS_COMP_DEL_OPT, LFS_COMP_SET_OPT, - LFS_COMP_ADD_OPT + LFS_COMP_ADD_OPT, + LFS_PROJID_OPT, }; /* functions */ @@ -1300,57 +1323,87 @@ static int lfs_setstripe(int argc, char **argv) __u32 comp_id = 0; struct llapi_layout *layout = NULL; - struct option long_opts[] = { + struct option long_opts[] = { /* --block is only valid in migrate mode */ - {"block", no_argument, 0, 'b'}, - {"component-add", no_argument, 0, LFS_COMP_ADD_OPT}, - {"component-del", no_argument, 0, LFS_COMP_DEL_OPT}, - {"component-flags", required_argument, 0, LFS_COMP_FLAGS_OPT}, - {"component-set", no_argument, 0, LFS_COMP_SET_OPT}, + { .val = 'b', .name = "block", .has_arg = no_argument}, + { .val = LFS_COMP_ADD_OPT, + .name = "comp-add", .has_arg = no_argument}, + { .val = LFS_COMP_ADD_OPT, + .name = "component-add", + .has_arg = no_argument}, + { .val = LFS_COMP_DEL_OPT, + .name = "comp-del", .has_arg = no_argument}, + { .val = LFS_COMP_DEL_OPT, + .name = "component-del", + .has_arg = no_argument}, + { .val = LFS_COMP_FLAGS_OPT, + .name = "comp-flags", .has_arg = required_argument}, + { .val = LFS_COMP_FLAGS_OPT, + .name = "component-flags", + .has_arg = required_argument}, + { .val = LFS_COMP_SET_OPT, + .name = "comp-set", .has_arg = no_argument}, + { .val = LFS_COMP_SET_OPT, + .name = "component-set", + .has_arg = no_argument}, #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 59, 0) - /* This formerly implied "stripe-count", but was explicitly - * made "stripe-count" for consistency with other options, - * and to separate it from "mdt-count" when DNE arrives. */ - {"count", required_argument, 0, 'c'}, + /* This formerly implied "stripe-count", but was explicitly + * made "stripe-count" for consistency with other options, + * and to separate it from "mdt-count" when DNE arrives. */ + { .val = 'c', .name = "count", .has_arg = required_argument }, #endif - {"stripe-count", required_argument, 0, 'c'}, - {"stripe_count", required_argument, 0, 'c'}, - {"delete", no_argument, 0, 'd'}, - {"component-end", required_argument, 0, 'E'}, - /* dirstripe {"mdt-hash", required_argument, 0, 'H'}, */ + { .val = 'c', .name = "stripe-count", .has_arg = required_argument}, + { .val = 'c', .name = "stripe_count", .has_arg = required_argument}, + { .val = 'd', .name = "delete", .has_arg = no_argument}, + { .val = 'E', .name = "comp-end", .has_arg = required_argument}, + { .val = 'E', .name = "component-end", + .has_arg = required_argument}, + /* dirstripe {"mdt-hash", required_argument, 0, 'H'}, */ #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 59, 0) - /* This formerly implied "stripe-index", but was explicitly - * made "stripe-index" for consistency with other options, - * and to separate it from "mdt-index" when DNE arrives. */ - {"index", required_argument, 0, 'i'}, + /* This formerly implied "stripe-index", but was explicitly + * made "stripe-index" for consistency with other options, + * and to separate it from "mdt-index" when DNE arrives. */ + { .val = 'i', .name = "index", .has_arg = required_argument }, #endif - {"stripe-index", required_argument, 0, 'i'}, - {"stripe_index", required_argument, 0, 'i'}, - {"component-id", required_argument, 0, 'I'}, - {"mdt", required_argument, 0, 'm'}, - {"mdt-index", required_argument, 0, 'm'}, - {"mdt_index", required_argument, 0, 'm'}, - /* --non-block is only valid in migrate mode */ - {"non-block", no_argument, 0, 'n'}, - {"ost", required_argument, 0, 'o'}, + { .val = 'i', .name = "stripe-index", .has_arg = required_argument}, + { .val = 'i', .name = "stripe_index", .has_arg = required_argument}, + { .val = 'I', .name = "comp-id", .has_arg = required_argument}, + { .val = 'I', .name = "component-id", .has_arg = required_argument}, + { .val = 'm', .name = "mdt", .has_arg = required_argument}, + { .val = 'm', .name = "mdt-index", .has_arg = required_argument}, + { .val = 'm', .name = "mdt_index", .has_arg = required_argument}, + /* --non-block is only valid in migrate mode */ + { .val = 'n', .name = "non-block", .has_arg = no_argument}, + { .val = 'o', .name = "ost", .has_arg = required_argument}, #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0) - {"ost-list", required_argument, 0, 'o'}, - {"ost_list", required_argument, 0, 'o'}, + { .val = 'o', .name = "ost-list", .has_arg = required_argument }, + { .val = 'o', .name = "ost_list", .has_arg = required_argument }, #endif - {"pool", required_argument, 0, 'p'}, + { .val = 'p', .name = "pool", .has_arg = required_argument }, #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 59, 0) - /* This formerly implied "--stripe-size", but was confusing - * with "lfs find --size|-s", which means "file size", so use - * the consistent "--stripe-size|-S" for all commands. */ - {"size", required_argument, 0, 's'}, + /* This formerly implied "--stripe-size", but was confusing + * with "lfs find --size|-s", which means "file size", so use + * the consistent "--stripe-size|-S" for all commands. */ + { .val = 's', .name = "size", .has_arg = required_argument }, #endif - {"stripe-size", required_argument, 0, 'S'}, - {"stripe_size", required_argument, 0, 'S'}, - /* dirstripe {"mdt-count", required_argument, 0, 'T'}, */ - /* --verbose is only valid in migrate mode */ - {"verbose", no_argument, 0, 'v'}, - {0, 0, 0, 0} - }; + { .val = 'S', .name = "stripe-size", .has_arg = required_argument }, + { .val = 'S', .name = "stripe_size", .has_arg = required_argument }, + /* dirstripe {"mdt-count", required_argument, 0, 'T'}, */ + /* --verbose is only valid in migrate mode */ + { .val = 'v', .name = "verbose", .has_arg = no_argument }, + { .val = LFS_COMP_ADD_OPT, + .name = "component-add", + .has_arg = no_argument }, + { .val = LFS_COMP_DEL_OPT, + .name = "component-del", + .has_arg = no_argument }, + { .val = LFS_COMP_FLAGS_OPT, + .name = "component-flags", + .has_arg = required_argument }, + { .val = LFS_COMP_SET_OPT, + .name = "component-set", + .has_arg = no_argument }, + { .name = NULL } }; setstripe_args_init(&lsa); @@ -1370,7 +1423,7 @@ static int lfs_setstripe(int argc, char **argv) comp_del = 1; break; case LFS_COMP_FLAGS_OPT: - result = comp_name2flags(&lsa.lsa_comp_flags, optarg); + result = comp_str2flags(&lsa.lsa_comp_flags, optarg); if (result != 0) { fprintf(stderr, "error: %s: bad comp flags " "'%s'\n", argv[0], optarg); @@ -1414,9 +1467,7 @@ static int lfs_setstripe(int argc, char **argv) setstripe_args_init(&lsa); } - if (!strncmp(optarg, "-1", strlen("-1")) || - !strncmp(optarg, "EOF", strlen("EOF")) || - !strncmp(optarg, "eof", strlen("eof"))) { + if (arg_is_eof(optarg)) { lsa.lsa_comp_end = LUSTRE_EOF; } else { result = llapi_parse_size(optarg, @@ -1443,7 +1494,8 @@ static int lfs_setstripe(int argc, char **argv) break; case 'I': comp_id = strtoul(optarg, &end, 0); - if (*end != '\0' || comp_id == 0) { + if (*end != '\0' || comp_id == 0 || + comp_id > LCME_ID_MAX) { fprintf(stderr, "error: %s: bad comp ID " "'%s'\n", argv[0], optarg); goto error; @@ -1481,8 +1533,7 @@ static int lfs_setstripe(int argc, char **argv) lsa.lsa_stripe_off = osts[0]; break; case 'p': - result = verify_pool_name(argv[0], optarg); - if (result) + if (optarg == NULL) goto error; lsa.lsa_pool_name = optarg; break; @@ -1567,6 +1618,18 @@ static int lfs_setstripe(int argc, char **argv) goto error; } + if (comp_add || comp_del) { + struct stat st; + + result = lstat(fname, &st); + if (result == 0 && S_ISDIR(st.st_mode)) { + fprintf(stderr, "error: %s: can't use --component-add " + "or --component-del for directory.\n", + argv[0]); + goto error; + } + } + if (comp_add) { if (layout == NULL) { fprintf(stderr, "error: %s: -E option must be present" @@ -1574,7 +1637,9 @@ static int lfs_setstripe(int argc, char **argv) goto error; } result = adjust_first_extent(fname, layout); - if (result != 0) + if (result == -ENODATA) + comp_add = 0; + else if (result != 0) goto error; } @@ -1591,10 +1656,9 @@ static int lfs_setstripe(int argc, char **argv) goto error; } - /* support --component-id option for migrate later. */ - if (migrate_mode && comp_id != 0) { - fprintf(stderr, "error: %s: -I isn't supported yet.\n", - argv[0]); + if (!comp_del && !comp_set && comp_id != 0) { + fprintf(stderr, "error: %s: -I can only be used with " + "--component-del.\n", argv[0]); goto error; } @@ -1807,49 +1871,65 @@ static int lfs_find(int argc, char **argv) { int c, rc; int ret = 0; - time_t t; + time_t t; struct find_param param = { .fp_max_depth = -1, .fp_quiet = 1, }; struct option long_opts[] = { - {"atime", required_argument, 0, 'A'}, - {"component-count", required_argument, 0, LFS_COMP_COUNT_OPT}, - {"component-flags", required_argument, 0, LFS_COMP_FLAGS_OPT}, - {"component-start", required_argument, 0, LFS_COMP_START_OPT}, - {"stripe-count", required_argument, 0, 'c'}, - {"stripe_count", required_argument, 0, 'c'}, - {"ctime", required_argument, 0, 'C'}, - {"maxdepth", required_argument, 0, 'D'}, - {"component-end", required_argument, 0, 'E'}, - {"gid", required_argument, 0, 'g'}, - {"group", required_argument, 0, 'G'}, - {"mdt-hash", required_argument, 0, 'H'}, - {"stripe-index", required_argument, 0, 'i'}, - {"stripe_index", required_argument, 0, 'i'}, - /*{"component-id", required_argument, 0, 'I'},*/ - {"layout", required_argument, 0, 'L'}, - {"mdt", required_argument, 0, 'm'}, - {"mdt-index", required_argument, 0, 'm'}, - {"mdt_index", required_argument, 0, 'm'}, - {"mtime", required_argument, 0, 'M'}, - {"name", required_argument, 0, 'n'}, + { .val = 'A', .name = "atime", .has_arg = required_argument }, + { .val = LFS_COMP_COUNT_OPT, + .name = "comp-count", .has_arg = required_argument }, + { .val = LFS_COMP_COUNT_OPT, + .name = "component-count", + .has_arg = required_argument }, + { .val = LFS_COMP_FLAGS_OPT, + .name = "comp-flags", .has_arg = required_argument }, + { .val = LFS_COMP_FLAGS_OPT, + .name = "component-flags", + .has_arg = required_argument }, + { .val = LFS_COMP_START_OPT, + .name = "comp-start", .has_arg = required_argument }, + { .val = LFS_COMP_START_OPT, + .name = "component-start", + .has_arg = required_argument }, + { .val = 'c', .name = "stripe-count", .has_arg = required_argument }, + { .val = 'c', .name = "stripe_count", .has_arg = required_argument }, + { .val = 'C', .name = "ctime", .has_arg = required_argument }, + { .val = 'D', .name = "maxdepth", .has_arg = required_argument }, + { .val = 'E', .name = "comp-end", .has_arg = required_argument }, + { .val = 'E', .name = "component-end", + .has_arg = required_argument }, + { .val = 'g', .name = "gid", .has_arg = required_argument }, + { .val = 'G', .name = "group", .has_arg = required_argument }, + { .val = 'H', .name = "mdt-hash", .has_arg = required_argument }, + { .val = 'i', .name = "stripe-index", .has_arg = required_argument }, + { .val = 'i', .name = "stripe_index", .has_arg = required_argument }, + /*{"component-id", required_argument, 0, 'I'},*/ + { .val = 'L', .name = "layout", .has_arg = required_argument }, + { .val = 'm', .name = "mdt", .has_arg = required_argument }, + { .val = 'm', .name = "mdt-index", .has_arg = required_argument }, + { .val = 'm', .name = "mdt_index", .has_arg = required_argument }, + { .val = 'M', .name = "mtime", .has_arg = required_argument }, + { .val = 'n', .name = "name", .has_arg = required_argument }, /* reserve {"or", no_argument, , 0, 'o'}, to match find(1) */ - {"obd", required_argument, 0, 'O'}, - {"ost", required_argument, 0, 'O'}, - /* no short option for pool, p/P already used */ - {"pool", required_argument, 0, LFS_POOL_OPT}, - {"print0", no_argument, 0, 'p'}, - {"print", no_argument, 0, 'P'}, - {"size", required_argument, 0, 's'}, - {"stripe-size", required_argument, 0, 'S'}, - {"stripe_size", required_argument, 0, 'S'}, - {"type", required_argument, 0, 't'}, - {"mdt-count", required_argument, 0, 'T'}, - {"uid", required_argument, 0, 'u'}, - {"user", required_argument, 0, 'U'}, - {0, 0, 0, 0} - }; + { .val = 'O', .name = "obd", .has_arg = required_argument }, + { .val = 'O', .name = "ost", .has_arg = required_argument }, + /* no short option for pool, p/P already used */ + { .val = LFS_POOL_OPT, + .name = "pool", .has_arg = required_argument }, + { .val = 'p', .name = "print0", .has_arg = no_argument }, + { .val = 'P', .name = "print", .has_arg = no_argument }, + { .val = LFS_PROJID_OPT, + .name = "projid", .has_arg = required_argument }, + { .val = 's', .name = "size", .has_arg = required_argument }, + { .val = 'S', .name = "stripe-size", .has_arg = required_argument }, + { .val = 'S', .name = "stripe_size", .has_arg = required_argument }, + { .val = 't', .name = "type", .has_arg = required_argument }, + { .val = 'T', .name = "mdt-count", .has_arg = required_argument }, + { .val = 'u', .name = "uid", .has_arg = required_argument }, + { .val = 'U', .name = "user", .has_arg = required_argument }, + { .name = NULL } }; int pathstart = -1; int pathend = -1; int neg_opt = 0; @@ -1943,8 +2023,8 @@ static int lfs_find(int argc, char **argv) param.fp_exclude_comp_count = !!neg_opt; break; case LFS_COMP_FLAGS_OPT: - rc = comp_name2flags(¶m.fp_comp_flags, optarg); - if (rc) { + rc = comp_str2flags(¶m.fp_comp_flags, optarg); + if (rc || comp_flags_is_neg(param.fp_comp_flags)) { fprintf(stderr, "error: bad component flags " "'%s'\n", optarg); goto err; @@ -2002,8 +2082,15 @@ static int lfs_find(int argc, char **argv) optarg++; } - rc = llapi_parse_size(optarg, ¶m.fp_comp_end, - ¶m.fp_comp_end_units, 0); + if (arg_is_eof(optarg)) { + param.fp_comp_end = LUSTRE_EOF; + param.fp_comp_end_units = 1; + rc = 0; + } else { + rc = llapi_parse_size(optarg, + ¶m.fp_comp_end, + ¶m.fp_comp_end_units, 0); + } if (rc) { fprintf(stderr, "error: bad component end " "'%s'\n", optarg); @@ -2151,17 +2238,32 @@ static int lfs_find(int argc, char **argv) strncpy(puuid->uuid, token, sizeof(puuid->uuid)); - } + } err_free: - if (buf) - free(buf); - break; - } - case 'p': + if (buf) + free(buf); + break; + } + case 'p': param.fp_zero_end = 1; - break; - case 'P': - break; + break; + case 'P': + break; + case LFS_PROJID_OPT: + rc = name2projid(¶m.fp_projid, optarg); + if (rc) { + param.fp_projid = strtoul(optarg, &endptr, 10); + if (*endptr != '\0') { + fprintf(stderr, + "Invalid project ID: %s", + optarg); + ret = -1; + goto err; + } + } + param.fp_exclude_projid = !!neg_opt; + param.fp_check_projid = 1; + break; case 's': if (optarg[0] == '+') { param.fp_size_sign = -1; @@ -2289,68 +2391,82 @@ static int lfs_getstripe_internal(int argc, char **argv, struct find_param *param) { struct option long_opts[] = { - {"component-count", no_argument, 0, LFS_COMP_COUNT_OPT}, - {"component-flags", required_argument, 0, LFS_COMP_FLAGS_OPT}, - {"component-start", required_argument, 0, LFS_COMP_START_OPT}, + { .val = LFS_COMP_COUNT_OPT, + .name = "comp-count", .has_arg = no_argument }, + { .val = LFS_COMP_COUNT_OPT, + .name = "component-count", .has_arg = no_argument }, + { .val = LFS_COMP_FLAGS_OPT, + .name = "comp-flags", .has_arg = optional_argument }, + { .val = LFS_COMP_FLAGS_OPT, + .name = "component-flags", .has_arg = optional_argument }, + { .val = LFS_COMP_START_OPT, + .name = "comp-start", .has_arg = optional_argument }, + { .val = LFS_COMP_START_OPT, + .name = "component-start", .has_arg = optional_argument }, #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 59, 0) - /* This formerly implied "stripe-count", but was explicitly - * made "stripe-count" for consistency with other options, - * and to separate it from "mdt-count" when DNE arrives. */ - {"count", no_argument, 0, 'c'}, + /* This formerly implied "stripe-count", but was explicitly + * made "stripe-count" for consistency with other options, + * and to separate it from "mdt-count" when DNE arrives. */ + { .val = 'c', .name = "count", .has_arg = no_argument }, #endif - {"stripe-count", no_argument, 0, 'c'}, - {"stripe_count", no_argument, 0, 'c'}, - {"directory", no_argument, 0, 'd'}, - {"default", no_argument, 0, 'D'}, - {"component-end", required_argument, 0, 'E'}, - {"fid", no_argument, 0, 'F'}, - {"generation", no_argument, 0, 'g'}, - /* dirstripe {"mdt-hash", required_argument, 0, 'H'}, */ + { .val = 'c', .name = "stripe-count", .has_arg = no_argument }, + { .val = 'c', .name = "stripe_count", .has_arg = no_argument }, + { .val = 'd', .name = "directory", .has_arg = no_argument }, + { .val = 'D', .name = "default", .has_arg = no_argument }, + { .val = 'E', .name = "comp-end", .has_arg = optional_argument }, + { .val = 'E', .name = "component-end", + .has_arg = optional_argument }, + { .val = 'F', .name = "fid", .has_arg = no_argument }, + { .val = 'g', .name = "generation", .has_arg = no_argument }, + /* dirstripe { .val = 'H', .name = "mdt-hash", + * .has_arg = required_argument }, */ #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 59, 0) - /* This formerly implied "stripe-index", but was explicitly - * made "stripe-index" for consistency with other options, - * and to separate it from "mdt-index" when DNE arrives. */ - {"index", no_argument, 0, 'i'}, + /* This formerly implied "stripe-index", but was explicitly + * made "stripe-index" for consistency with other options, + * and to separate it from "mdt-index" when DNE arrives. */ + { .val = 'i', .name = "index", .has_arg = no_argument }, #endif - {"stripe-index", no_argument, 0, 'i'}, - {"stripe_index", no_argument, 0, 'i'}, - {"component-id", required_argument, 0, 'I'}, - {"layout", no_argument, 0, 'L'}, - {"mdt", no_argument, 0, 'm'}, - {"mdt-index", no_argument, 0, 'm'}, - {"mdt_index", no_argument, 0, 'm'}, + { .val = 'i', .name = "stripe-index", .has_arg = no_argument }, + { .val = 'i', .name = "stripe_index", .has_arg = no_argument }, + { .val = 'I', .name = "comp-id", .has_arg = optional_argument }, + { .val = 'I', .name = "component-id", .has_arg = optional_argument }, + { .val = 'L', .name = "layout", .has_arg = no_argument }, + { .val = 'm', .name = "mdt", .has_arg = no_argument }, + { .val = 'm', .name = "mdt-index", .has_arg = no_argument }, + { .val = 'm', .name = "mdt_index", .has_arg = no_argument }, #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0) - {"mdt-index", no_argument, 0, 'M'}, - {"mdt_index", no_argument, 0, 'M'}, + { .val = 'M', .name = "mdt-index", .has_arg = no_argument }, + { .val = 'M', .name = "mdt_index", .has_arg = no_argument }, #endif #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 59, 0) - /* This formerly implied "stripe-index", but was confusing - * with "file offset" (which will eventually be needed for - * with different layouts by offset), so deprecate it. */ - {"offset", no_argument, 0, 'o'}, + /* This formerly implied "stripe-index", but was confusing + * with "file offset" (which will eventually be needed for + * with different layouts by offset), so deprecate it. */ + { .val = 'o', .name = "offset", .has_arg = no_argument }, #endif - {"obd", required_argument, 0, 'O'}, - {"ost", required_argument, 0, 'O'}, - {"pool", no_argument, 0, 'p'}, - {"quiet", no_argument, 0, 'q'}, - {"recursive", no_argument, 0, 'r'}, - {"raw", no_argument, 0, 'R'}, + { .val = 'O', .name = "obd", .has_arg = required_argument }, + { .val = 'O', .name = "ost", .has_arg = required_argument }, + { .val = 'p', .name = "pool", .has_arg = no_argument }, + { .val = 'q', .name = "quiet", .has_arg = no_argument }, + { .val = 'r', .name = "recursive", .has_arg = no_argument }, + { .val = 'R', .name = "raw", .has_arg = no_argument }, #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 59, 0) - /* This formerly implied "--stripe-size", but was confusing - * with "lfs find --size|-s", which means "file size", so use - * the consistent "--stripe-size|-S" for all commands. */ - {"size", no_argument, 0, 's'}, + /* This formerly implied "--stripe-size", but was confusing + * with "lfs find --size|-s", which means "file size", so use + * the consistent "--stripe-size|-S" for all commands. */ + { .val = 's', .name = "size", .has_arg = no_argument }, #endif - {"stripe-size", no_argument, 0, 'S'}, - {"stripe_size", no_argument, 0, 'S'}, - /* dirstripe {"mdt-count", required_argument, 0, 'T'}, */ - {"verbose", no_argument, 0, 'v'}, - {0, 0, 0, 0} - }; + { .val = 'S', .name = "stripe-size", .has_arg = no_argument }, + { .val = 'S', .name = "stripe_size", .has_arg = no_argument }, + /* dirstripe { .val = 'T', .name = "mdt-count", + * .has_arg = required_argument }, */ + { .val = 'v', .name = "verbose", .has_arg = no_argument }, + { .val = 'y', .name = "yaml", .has_arg = no_argument }, + { .name = NULL } }; int c, rc; char *end, *tmp; - while ((c = getopt_long(argc, argv, "cdDE:FghiI:LmMoO:pqrRsSv", + while ((c = getopt_long(argc, argv, "cdDE::FghiI::LmMoO:pqrRsSvy", long_opts, NULL)) != -1) { switch (c) { case 'c': @@ -2368,15 +2484,18 @@ static int lfs_getstripe_internal(int argc, char **argv, break; case LFS_COMP_FLAGS_OPT: if (optarg != NULL) { - rc = comp_name2flags(¶m->fp_comp_flags, - optarg); + __u32 *flags = ¶m->fp_comp_flags; + rc = comp_str2flags(flags, optarg); if (rc != 0) { - param->fp_verbose |= - VERBOSE_COMP_FLAGS; - param->fp_max_depth = 0; - optind--; + fprintf(stderr, "error: %s bad " + "component flags '%s'.\n", + argv[0], optarg); + return CMD_HELP; } else { param->fp_check_comp_flags = 1; + param->fp_exclude_comp_flags = + comp_flags_is_neg(*flags); + comp_flags_clear_neg(flags); } } else { param->fp_verbose |= VERBOSE_COMP_FLAGS; @@ -2387,19 +2506,20 @@ static int lfs_getstripe_internal(int argc, char **argv, if (optarg != NULL) { tmp = optarg; if (tmp[0] == '+') { - param->fp_comp_start_sign = 1; + param->fp_comp_start_sign = -1; tmp++; } else if (tmp[0] == '-') { - param->fp_comp_start_sign = -1; + param->fp_comp_start_sign = 1; tmp++; } rc = llapi_parse_size(tmp, ¶m->fp_comp_start, ¶m->fp_comp_start_units, 0); if (rc != 0) { - param->fp_verbose |= VERBOSE_COMP_START; - param->fp_max_depth = 0; - optind--; + fprintf(stderr, "error: %s bad " + "component start '%s'.\n", + argv[0], tmp); + return CMD_HELP; } else { param->fp_check_comp_start = 1; } @@ -2418,22 +2538,29 @@ static int lfs_getstripe_internal(int argc, char **argv, if (optarg != NULL) { tmp = optarg; if (tmp[0] == '+') { - param->fp_comp_end_sign = 1; + param->fp_comp_end_sign = -1; tmp++; } else if (tmp[0] == '-') { - param->fp_comp_end_sign = -1; + param->fp_comp_end_sign = 1; tmp++; } - rc = llapi_parse_size(tmp, + + if (arg_is_eof(tmp)) { + param->fp_comp_end = LUSTRE_EOF; + param->fp_comp_end_units = 1; + rc = 0; + } else { + rc = llapi_parse_size(tmp, ¶m->fp_comp_end, ¶m->fp_comp_end_units, 0); + } if (rc != 0) { - param->fp_verbose |= VERBOSE_COMP_END; - param->fp_max_depth = 0; - optind--; - } else { - param->fp_check_comp_end = 1; + fprintf(stderr, "error: %s bad " + "component end '%s'.\n", + argv[0], tmp); + return CMD_HELP; } + param->fp_check_comp_end = 1; } else { param->fp_verbose |= VERBOSE_COMP_END; param->fp_max_depth = 0; @@ -2470,10 +2597,12 @@ static int lfs_getstripe_internal(int argc, char **argv, case 'I': if (optarg != NULL) { param->fp_comp_id = strtoul(optarg, &end, 0); - if (*end != '\0') { - param->fp_verbose |= VERBOSE_COMP_ID; - param->fp_max_depth = 0; - optind--; + if (*end != '\0' || param->fp_comp_id == 0 || + param->fp_comp_id > LCME_ID_MAX) { + fprintf(stderr, "error: %s bad " + "component id '%s'\n", + argv[0], optarg); + return CMD_HELP; } else { param->fp_check_comp_id = 1; } @@ -2538,6 +2667,9 @@ static int lfs_getstripe_internal(int argc, char **argv, case 'v': param->fp_verbose = VERBOSE_DEFAULT | VERBOSE_DETAIL; break; + case 'y': + param->fp_yaml = 1; + break; default: return CMD_HELP; } @@ -2618,25 +2750,25 @@ static int lfs_getdirstripe(int argc, char **argv) struct find_param param = { 0 }; struct option long_opts[] = { #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0) - {"mdt-count", no_argument, 0, 'c'}, + { .val = 'c', .name = "mdt-count", .has_arg = no_argument }, #endif - {"mdt-hash", no_argument, 0, 'H'}, - {"mdt-index", no_argument, 0, 'i'}, - {"recursive", no_argument, 0, 'r'}, + { .val = 'D', .name = "default", .has_arg = no_argument }, + { .val = 'H', .name = "mdt-hash", .has_arg = no_argument }, + { .val = 'i', .name = "mdt-index", .has_arg = no_argument }, + { .val = 'O', .name = "obd", .has_arg = required_argument }, + { .val = 'r', .name = "recursive", .has_arg = no_argument }, #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0) - {"mdt-hash", no_argument, 0, 't'}, + { .val = 't', .name = "mdt-hash", .has_arg = no_argument }, #endif - {"default", no_argument, 0, 'D'}, - {"obd", required_argument, 0, 'O'}, - {"mdt-count", no_argument, 0, 'T'}, - {0, 0, 0, 0} - }; + { .val = 'T', .name = "mdt-count", .has_arg = no_argument }, + { .val = 'y', .name = "yaml", .has_arg = no_argument }, + { .name = NULL } }; int c, rc; param.fp_get_lmv = 1; while ((c = getopt_long(argc, argv, - "cDHiO:rtT", long_opts, NULL)) != -1) + "cDHiO:rtTy", long_opts, NULL)) != -1) { switch (c) { case 'O': @@ -2673,6 +2805,9 @@ static int lfs_getdirstripe(int argc, char **argv) case 'r': param.fp_recursive = 1; break; + case 'y': + param.fp_yaml = 1; + break; default: return CMD_HELP; } @@ -2718,26 +2853,26 @@ static int lfs_setdirstripe(int argc, char **argv) struct option long_opts[] = { #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0) - {"count", required_argument, 0, 'c'}, + { .val = 'c', .name = "count", .has_arg = required_argument }, #endif - {"mdt-count", required_argument, 0, 'c'}, - {"delete", no_argument, 0, 'd'}, + { .val = 'c', .name = "mdt-count", .has_arg = required_argument }, + { .val = 'd', .name = "delete", .has_arg = no_argument }, #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0) - {"index", required_argument, 0, 'i'}, + { .val = 'i', .name = "index", .has_arg = required_argument }, #endif - {"mdt-index", required_argument, 0, 'i'}, - {"mode", required_argument, 0, 'm'}, + { .val = 'i', .name = "mdt-index", .has_arg = required_argument }, + { .val = 'm', .name = "mode", .has_arg = required_argument }, #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0) - {"hash-type", required_argument, 0, 't'}, - {"mdt-hash", required_argument, 0, 't'}, + { .val = 't', .name = "hash-type", .has_arg = required_argument }, + { .val = 't', .name = "mdt-hash", .has_arg = required_argument }, #endif {"mdt-hash", required_argument, 0, 'H'}, #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0) - {"default_stripe", no_argument, 0, 'D'}, + { .val = 'D', .name = "default_stripe", + .has_arg = no_argument }, #endif - {"default", no_argument, 0, 'D'}, - {0, 0, 0, 0} - }; + { .val = 'D', .name = "default", .has_arg = no_argument }, + { .name = NULL } }; while ((c = getopt_long(argc, argv, "c:dDi:H:m:t:", long_opts, NULL)) >= 0) { @@ -2748,8 +2883,9 @@ static int lfs_setdirstripe(int argc, char **argv) case 'c': #if LUSTRE_VERSION_CODE >= OBD_OCD_VERSION(2, 11, 53, 0) if (strcmp(argv[optind - 1], "--count") == 0) - fprintf(stderr, "warning: '--count' deprecated" - ", use '--mdt-count' instead\n"); + fprintf(stderr, + "%s %s: warning: '--count' deprecated, use '--mdt-count' instead\n", + progname, argv[0]); #endif stripe_count_opt = optarg; break; @@ -2763,8 +2899,9 @@ static int lfs_setdirstripe(int argc, char **argv) case 'i': #if LUSTRE_VERSION_CODE >= OBD_OCD_VERSION(2, 11, 53, 0) if (strcmp(argv[optind - 1], "--index") == 0) - fprintf(stderr, "warning: '--index' deprecated" - ", use '--mdt-index' instead\n"); + fprintf(stderr, + "%s %s: warning: '--index' deprecated, use '--mdt-index' instead\n", + progname, argv[0]); #endif stripe_offset_opt = optarg; break; @@ -2777,29 +2914,29 @@ static int lfs_setdirstripe(int argc, char **argv) case 'H': #if LUSTRE_VERSION_CODE >= OBD_OCD_VERSION(2, 11, 53, 0) if (strcmp(argv[optind - 1], "--hash-type") == 0) - fprintf(stderr, "warning: '--hash-type' " - "deprecated, use '--mdt-hash' " - "instead\n"); + fprintf(stderr, + "%s %s: warning: '--hash-type' deprecated, use '--mdt-hash' instead\n", + progname, argv[0]); #endif stripe_hash_opt = optarg; break; default: - fprintf(stderr, "error: %s: option '%s' " - "unrecognized\n", - argv[0], argv[optind - 1]); + fprintf(stderr, "%s %s: unrecognized option '%s'\n", + progname, argv[0], argv[optind - 1]); return CMD_HELP; } } if (optind == argc) { - fprintf(stderr, "error: %s: missing dirname\n", - argv[0]); + fprintf(stderr, "%s %s: DIR must be specified\n", + progname, argv[0]); return CMD_HELP; } if (!delete && stripe_offset_opt == NULL && stripe_count_opt == NULL) { - fprintf(stderr, "error: %s: missing stripe offset and count.\n", - argv[0]); + fprintf(stderr, + "%s %s: stripe offset and count must be specified\n", + progname, argv[0]); return CMD_HELP; } @@ -2807,16 +2944,18 @@ static int lfs_setdirstripe(int argc, char **argv) /* get the stripe offset */ stripe_offset = strtoul(stripe_offset_opt, &end, 0); if (*end != '\0') { - fprintf(stderr, "error: %s: bad stripe offset '%s'\n", - argv[0], stripe_offset_opt); + fprintf(stderr, + "%s %s: bad stripe offset '%s'\n", + progname, argv[0], stripe_offset_opt); return CMD_HELP; } } if (delete) { if (stripe_offset_opt != NULL || stripe_count_opt != NULL) { - fprintf(stderr, "error: %s: cannot specify -d with -s," - " or -i options.\n", argv[0]); + fprintf(stderr, + "%s %s: cannot specify -d with -c or -i options\n", + progname, argv[0]); return CMD_HELP; } else { stripe_count = 0; @@ -2827,8 +2966,9 @@ static int lfs_setdirstripe(int argc, char **argv) if (mode_opt != NULL) { mode = strtoul(mode_opt, &end, 8); if (*end != '\0') { - fprintf(stderr, "error: %s: bad mode '%s'\n", - argv[0], mode_opt); + fprintf(stderr, + "%s %s: bad MODE '%s'\n", + progname, argv[0], mode_opt); return CMD_HELP; } previous_mode = umask(0); @@ -2839,9 +2979,8 @@ static int lfs_setdirstripe(int argc, char **argv) } else { hash_type = check_hashtype(stripe_hash_opt); if (hash_type == 0) { - fprintf(stderr, - "error: %s: bad stripe hash type '%s'\n", - argv[0], stripe_hash_opt); + fprintf(stderr, "%s %s: bad stripe hash type '%s'\n", + progname, argv[0], stripe_hash_opt); return CMD_HELP; } } @@ -2850,8 +2989,9 @@ static int lfs_setdirstripe(int argc, char **argv) if (stripe_count_opt != NULL) { stripe_count = strtoul(stripe_count_opt, &end, 0); if (*end != '\0') { - fprintf(stderr, "error: %s: bad stripe count '%s'\n", - argv[0], stripe_count_opt); + fprintf(stderr, + "%s %s: bad stripe count '%s'\n", + progname, argv[0], stripe_count_opt); return CMD_HELP; } } @@ -2870,8 +3010,9 @@ static int lfs_setdirstripe(int argc, char **argv) } if (result) { - fprintf(stderr, "error: %s: create stripe dir '%s' " - "failed\n", argv[0], dname); + fprintf(stderr, + "%s setdirstripe: cannot create stripe dir '%s': %s\n", + progname, dname, strerror(-result)); break; } dname = argv[++optind]; @@ -2920,10 +3061,9 @@ static int lfs_mv(int argc, char **argv) int c; int rc = 0; struct option long_opts[] = { - {"mdt-index", required_argument, 0, 'M'}, - {"verbose", no_argument, 0, 'v'}, - {0, 0, 0, 0} - }; + { .val = 'M', .name = "mdt-index", .has_arg = required_argument }, + { .val = 'v', .name = "verbose", .has_arg = no_argument }, + { .name = NULL } }; while ((c = getopt_long(argc, argv, "M:v", long_opts, NULL)) != -1) { switch (c) { @@ -3114,9 +3254,10 @@ static int mntdf(char *mntdir, char *fsname, char *pool, enum mntdf_flags flags) struct obd_statfs stat_buf, sum = { .os_bsize = 1 }; struct obd_uuid uuid_buf; char *poolname = NULL; - struct ll_stat_type types[] = { { LL_STATFS_LMV, "MDT" }, - { LL_STATFS_LOV, "OST" }, - { 0, NULL } }; + struct ll_stat_type types[] = { + { .st_op = LL_STATFS_LMV, .st_name = "MDT" }, + { .st_op = LL_STATFS_LOV, .st_name = "OST" }, + { .st_name = NULL } }; struct ll_stat_type *tp; __u64 ost_ffree = 0; __u32 index; @@ -3230,13 +3371,13 @@ static int lfs_df(int argc, char **argv) int c, rc = 0, index = 0; char fsname[PATH_MAX] = "", *pool_name = NULL; struct option long_opts[] = { - {"human-readable", 0, 0, 'h'}, - {"inodes", 0, 0, 'i'}, - {"lazy", 0, 0, 'l'}, - {"pool", required_argument, 0, 'p'}, - {"verbose", 0, 0, 'v'}, - {0, 0, 0, 0} - }; + { .val = 'h', .name = "human-readable", + .has_arg = no_argument }, + { .val = 'i', .name = "inodes", .has_arg = no_argument }, + { .val = 'l', .name = "lazy", .has_arg = no_argument }, + { .val = 'p', .name = "pool", .has_arg = required_argument }, + { .val = 'v', .name = "verbose", .has_arg = no_argument }, + { .name = NULL} }; while ((c = getopt_long(argc, argv, "hilp:v", long_opts, NULL)) != -1) { switch (c) { @@ -3466,14 +3607,13 @@ int lfs_setquota_times(int argc, char **argv) struct obd_dqblk *dqb = &qctl.qc_dqblk; struct obd_dqinfo *dqi = &qctl.qc_dqinfo; struct option long_opts[] = { - {"block-grace", required_argument, 0, 'b'}, - {"group", no_argument, 0, 'g'}, - {"inode-grace", required_argument, 0, 'i'}, - {"project", no_argument, 0, 'p'}, - {"times", no_argument, 0, 't'}, - {"user", no_argument, 0, 'u'}, - {0, 0, 0, 0} - }; + { .val = 'b', .name = "block-grace", .has_arg = required_argument }, + { .val = 'g', .name = "group", .has_arg = no_argument }, + { .val = 'i', .name = "inode-grace", .has_arg = required_argument }, + { .val = 'p', .name = "projid", .has_arg = no_argument }, + { .val = 't', .name = "times", .has_arg = no_argument }, + { .val = 'u', .name = "user", .has_arg = no_argument }, + { .name = NULL } }; int qtype; memset(&qctl, 0, sizeof(qctl)); @@ -3557,15 +3697,18 @@ int lfs_setquota(int argc, char **argv) char *mnt, *obd_type = (char *)qctl.obd_type; struct obd_dqblk *dqb = &qctl.qc_dqblk; struct option long_opts[] = { - {"block-softlimit", required_argument, 0, 'b'}, - {"block-hardlimit", required_argument, 0, 'B'}, - {"group", required_argument, 0, 'g'}, - {"inode-softlimit", required_argument, 0, 'i'}, - {"inode-hardlimit", required_argument, 0, 'I'}, - {"user", required_argument, 0, 'u'}, - {"project", required_argument, 0, 'p'}, - {0, 0, 0, 0} - }; + { .val = 'b', .name = "block-softlimit", + .has_arg = required_argument }, + { .val = 'B', .name = "block-hardlimit", + .has_arg = required_argument }, + { .val = 'g', .name = "group", .has_arg = required_argument }, + { .val = 'i', .name = "inode-softlimit", + .has_arg = required_argument }, + { .val = 'I', .name = "inode-hardlimit", + .has_arg = required_argument }, + { .val = 'p', .name = "projid", .has_arg = required_argument }, + { .val = 'u', .name = "user", .has_arg = required_argument }, + { .name = NULL } }; unsigned limit_mask = 0; char *endptr; int qtype; @@ -3576,13 +3719,13 @@ int lfs_setquota(int argc, char **argv) memset(&qctl, 0, sizeof(qctl)); qctl.qc_cmd = LUSTRE_Q_SETQUOTA; qctl.qc_type = ALLQUOTA; /* ALLQUOTA makes no sense for setquota, - * so it can be used as a marker that qc_type - * isn't reinitialized from command line */ + * so it can be used as a marker that qc_type + * isn't reinitialized from command line */ while ((c = getopt_long(argc, argv, "b:B:g:i:I:p:u:", long_opts, NULL)) != -1) { - switch (c) { - case 'u': + switch (c) { + case 'u': qtype = USRQUOTA; rc = name2uid(&qctl.qc_id, optarg); goto quota_type; @@ -4073,8 +4216,8 @@ all_output: if (rc) { qctl.qc_id = strtoul(name, &endptr, 10); if (*endptr != '\0') { - fprintf(stderr, "error: can't find id for name " - "%s\n", name); + fprintf(stderr, "error: can't find id for name: %s\n", + name); return CMD_HELP; } } @@ -4083,9 +4226,8 @@ all_output: return CMD_HELP; } - mnt = argv[optind]; - - rc1 = llapi_quotactl(mnt, &qctl); + mnt = argv[optind]; + rc1 = llapi_quotactl(mnt, &qctl); if (rc1 < 0) { switch (rc1) { case -ESRCH: @@ -4231,19 +4373,18 @@ static int lfs_ls(int argc, char **argv) static int lfs_changelog(int argc, char **argv) { - void *changelog_priv; + void *changelog_priv; struct changelog_rec *rec; - long long startrec = 0, endrec = 0; - char *mdd; - struct option long_opts[] = { - {"follow", no_argument, 0, 'f'}, - {0, 0, 0, 0} - }; - char short_opts[] = "f"; - int rc, follow = 0; - - while ((rc = getopt_long(argc, argv, short_opts, - long_opts, NULL)) != -1) { + long long startrec = 0, endrec = 0; + char *mdd; + struct option long_opts[] = { + { .val = 'f', .name = "follow", .has_arg = no_argument }, + { .name = NULL } }; + char short_opts[] = "f"; + int rc, follow = 0; + + while ((rc = getopt_long(argc, argv, short_opts, + long_opts, NULL)) != -1) { switch (rc) { case 'f': follow++; @@ -4276,26 +4417,26 @@ static int lfs_changelog(int argc, char **argv) return rc; } - while ((rc = llapi_changelog_recv(changelog_priv, &rec)) == 0) { - time_t secs; - struct tm ts; + while ((rc = llapi_changelog_recv(changelog_priv, &rec)) == 0) { + time_t secs; + struct tm ts; - if (endrec && rec->cr_index > endrec) { - llapi_changelog_free(&rec); - break; - } - if (rec->cr_index < startrec) { - llapi_changelog_free(&rec); - continue; - } + if (endrec && rec->cr_index > endrec) { + llapi_changelog_free(&rec); + break; + } + if (rec->cr_index < startrec) { + llapi_changelog_free(&rec); + continue; + } secs = rec->cr_time >> 30; gmtime_r(&secs, &ts); - printf("%ju %02d%-5s %02d:%02d:%02d.%06d %04d.%02d.%02d " - "0x%x t="DFID, (uintmax_t) rec->cr_index, rec->cr_type, + printf("%ju %02d%-5s %02d:%02d:%02d.%09d %04d.%02d.%02d " + "0x%x t="DFID, (uintmax_t)rec->cr_index, rec->cr_type, changelog_type2str(rec->cr_type), ts.tm_hour, ts.tm_min, ts.tm_sec, - (int)(rec->cr_time & ((1<<30) - 1)), + (int)(rec->cr_time & ((1 << 30) - 1)), ts.tm_year + 1900, ts.tm_mon + 1, ts.tm_mday, rec->cr_flags & CLF_FLAGMASK, PFID(&rec->cr_tfid)); @@ -4365,22 +4506,21 @@ static int lfs_changelog_clear(int argc, char **argv) static int lfs_fid2path(int argc, char **argv) { - struct option long_opts[] = { - {"cur", no_argument, 0, 'c'}, - {"link", required_argument, 0, 'l'}, - {"rec", required_argument, 0, 'r'}, - {0, 0, 0, 0} - }; - char short_opts[] = "cl:r:"; - char *device, *fid, *path; - long long recno = -1; - int linkno = -1; - int lnktmp; - int printcur = 0; + struct option long_opts[] = { + { .val = 'c', .name = "cur", .has_arg = no_argument }, + { .val = 'l', .name = "link", .has_arg = required_argument }, + { .val = 'r', .name = "rec", .has_arg = required_argument }, + { .name = NULL } }; + char short_opts[] = "cl:r:"; + char *device, *fid, *path; + long long recno = -1; + int linkno = -1; + int lnktmp; + int printcur = 0; int rc = 0; - while ((rc = getopt_long(argc, argv, short_opts, - long_opts, NULL)) != -1) { + while ((rc = getopt_long(argc, argv, short_opts, + long_opts, NULL)) != -1) { switch (rc) { case 'c': printcur++; @@ -4455,10 +4595,9 @@ static int lfs_fid2path(int argc, char **argv) static int lfs_path2fid(int argc, char **argv) { - struct option long_opts[] = { - {"parents", no_argument, 0, 'p'}, - {0, 0, 0, 0} - }; + struct option long_opts[] = { + { .val = 'p', .name = "parents", .has_arg = no_argument }, + { .name = NULL } }; char **path; const char short_opts[] = "p"; const char *sep = ""; @@ -4633,14 +4772,13 @@ static int lfs_hsm_state(int argc, char **argv) static int lfs_hsm_change_flags(int argc, char **argv, int mode) { struct option long_opts[] = { - {"lost", 0, 0, 'l'}, - {"norelease", 0, 0, 'r'}, - {"noarchive", 0, 0, 'a'}, - {"archived", 0, 0, 'A'}, - {"dirty", 0, 0, 'd'}, - {"exists", 0, 0, 'e'}, - {0, 0, 0, 0} - }; + { .val = 'A', .name = "archived", .has_arg = no_argument }, + { .val = 'a', .name = "noarchive", .has_arg = no_argument }, + { .val = 'd', .name = "dirty", .has_arg = no_argument }, + { .val = 'e', .name = "exists", .has_arg = no_argument }, + { .val = 'l', .name = "lost", .has_arg = no_argument }, + { .val = 'r', .name = "norelease", .has_arg = no_argument }, + { .name = NULL } }; char short_opts[] = "lraAde"; __u64 mask = 0; int c, rc; @@ -4858,13 +4996,12 @@ static int fill_hur_item(struct hsm_user_request *hur, unsigned int idx, static int lfs_hsm_request(int argc, char **argv, int action) { - struct option long_opts[] = { - {"filelist", 1, 0, 'l'}, - {"data", 1, 0, 'D'}, - {"archive", 1, 0, 'a'}, - {"mntpath", 1, 0, 'm'}, - {0, 0, 0, 0} - }; + struct option long_opts[] = { + { .val = 'a', .name = "archive", .has_arg = required_argument }, + { .val = 'D', .name = "data", .has_arg = required_argument }, + { .val = 'l', .name = "filelist", .has_arg = required_argument }, + { .val = 'm', .name = "mntpath", .has_arg = required_argument }, + { .name = NULL } }; dev_t last_dev = 0; char short_opts[] = "l:D:a:m:"; struct hsm_user_request *hur, *oldhur; @@ -5082,6 +5219,28 @@ static int lfs_swap_layouts(int argc, char **argv) static const char *const ladvise_names[] = LU_LADVISE_NAMES; +static const char *const lock_mode_names[] = LOCK_MODE_NAMES; + +static const char *const lockahead_results[] = { + [LLA_RESULT_SENT] = "Lock request sent", + [LLA_RESULT_DIFFERENT] = "Different matching lock found", + [LLA_RESULT_SAME] = "Matching lock on identical extent found", +}; + +int lfs_get_mode(const char *string) +{ + enum lock_mode_user mode; + + for (mode = 0; mode < ARRAY_SIZE(lock_mode_names); mode++) { + if (lock_mode_names[mode] == NULL) + continue; + if (strcmp(string, lock_mode_names[mode]) == 0) + return mode; + } + + return -EINVAL; +} + static enum lu_ladvise_type lfs_get_ladvice(const char *string) { enum lu_ladvise_type advice; @@ -5099,15 +5258,16 @@ static enum lu_ladvise_type lfs_get_ladvice(const char *string) static int lfs_ladvise(int argc, char **argv) { - struct option long_opts[] = { - {"advice", required_argument, 0, 'a'}, - {"background", no_argument, 0, 'b'}, - {"end", required_argument, 0, 'e'}, - {"start", required_argument, 0, 's'}, - {"length", required_argument, 0, 'l'}, - {0, 0, 0, 0} - }; - char short_opts[] = "a:be:l:s:"; + struct option long_opts[] = { + { .val = 'a', .name = "advice", .has_arg = required_argument }, + { .val = 'b', .name = "background", .has_arg = no_argument }, + { .val = 'e', .name = "end", .has_arg = required_argument }, + { .val = 'l', .name = "length", .has_arg = required_argument }, + { .val = 'm', .name = "mode", .has_arg = required_argument }, + { .val = 's', .name = "start", .has_arg = required_argument }, + { .val = 'u', .name = "unset", .has_arg = no_argument }, + { .name = NULL } }; + char short_opts[] = "a:be:l:m:s:u"; int c; int rc = 0; const char *path; @@ -5119,6 +5279,7 @@ static int lfs_ladvise(int argc, char **argv) unsigned long long length = 0; unsigned long long size_units; unsigned long long flags = 0; + int mode = 0; optind = 0; while ((c = getopt_long(argc, argv, short_opts, @@ -5147,6 +5308,9 @@ static int lfs_ladvise(int argc, char **argv) case 'b': flags |= LF_ASYNC; break; + case 'u': + flags |= LF_UNSET; + break; case 'e': size_units = 1; rc = llapi_parse_size(optarg, &end, @@ -5177,6 +5341,15 @@ static int lfs_ladvise(int argc, char **argv) return CMD_HELP; } break; + case 'm': + mode = lfs_get_mode(optarg); + if (mode < 0) { + fprintf(stderr, "%s: bad mode '%s', valid " + "modes are READ or WRITE\n", + argv[0], optarg); + return CMD_HELP; + } + break; case '?': return CMD_HELP; default: @@ -5199,6 +5372,13 @@ static int lfs_ladvise(int argc, char **argv) return CMD_HELP; } + if (advice_type == LU_LADVISE_LOCKNOEXPAND) { + fprintf(stderr, "%s: Lock no expand advice is a per file " + "descriptor advice, so when called from lfs, " + "it does nothing.\n", argv[0]); + return CMD_HELP; + } + if (argc <= optind) { fprintf(stderr, "%s: please give one or more file names\n", argv[0]); @@ -5220,6 +5400,18 @@ static int lfs_ladvise(int argc, char **argv) return CMD_HELP; } + if (advice_type != LU_LADVISE_LOCKAHEAD && mode != 0) { + fprintf(stderr, "%s: mode is only valid with lockahead\n", + argv[0]); + return CMD_HELP; + } + + if (advice_type == LU_LADVISE_LOCKAHEAD && mode == 0) { + fprintf(stderr, "%s: mode is required with lockahead\n", + argv[0]); + return CMD_HELP; + } + while (optind < argc) { int rc2; @@ -5240,6 +5432,11 @@ static int lfs_ladvise(int argc, char **argv) advice.lla_value2 = 0; advice.lla_value3 = 0; advice.lla_value4 = 0; + if (advice_type == LU_LADVISE_LOCKAHEAD) { + advice.lla_lockahead_mode = mode; + advice.lla_peradvice_flags = flags; + } + rc2 = llapi_ladvise(fd, flags, 1, &advice); close(fd); if (rc2 < 0) { @@ -5247,7 +5444,10 @@ static int lfs_ladvise(int argc, char **argv) "'%s': %s\n", argv[0], ladvise_names[advice_type], path, strerror(errno)); + + goto next; } + next: if (rc == 0 && rc2 < 0) rc = rc2;