Whamcloud - gitweb
LU-14472 quota: skip non-exist or inact tgt for lfs_quota
[fs/lustre-release.git] / lustre / utils / lfs.c
index 5d6616a..68a74da 100644 (file)
@@ -134,9 +134,7 @@ static int lfs_pcc_state(int argc, char **argv);
 static int lfs_pcc(int argc, char **argv);
 static int lfs_pcc_list_commands(int argc, char **argv);
 static int lfs_migrate_to_dom(int fd, int fdv, char *name,
-                             __u64 migration_flags,
-                             struct llapi_stripe_param *param,
-                             struct llapi_layout *layout);
+                             __u64 migration_flags);
 
 struct pool_to_id_cbdata {
        const char *pool;
@@ -191,97 +189,34 @@ static inline int lfs_mirror_delete(int argc, char **argv)
 /* Setstripe and migrate share mostly the same parameters */
 #define SSM_CMD_COMMON(cmd) \
        "usage: "cmd" [--component-end|-E COMP_END]\n"                  \
-       "                 [--stripe-count|-c STRIPE_COUNT]\n"           \
-       "                 [--overstripe-count|-C STRIPE_COUNT]\n"       \
-       "                 [--stripe-index|-i START_OST_IDX]\n"          \
-       "                 [--stripe-size|-S STRIPE_SIZE]\n"             \
-       "                 [--extension-size|--ext-size|-z]\n"           \
+       "                 [--copy=LUSTRE_SRC]\n"                        \
+       "                 [--extension-size|--ext-size|-z SIZE]\n"      \
        "                 [--help|-h] [--layout|-L PATTERN]\n"          \
-       "                 [--mirror_count|-N[MIRROR_COUNT]]\n"          \
+       "                 [--layout|-L PATTERN]\n"                      \
+       "                 [--mirror-count|-N[MIRROR_COUNT]]\n"          \
        "                 [--ost|-o OST_INDICES]\n"                     \
+       "                 [--overstripe-count|-C STRIPE_COUNT]\n"       \
        "                 [--pool|-p POOL_NAME]\n"                      \
-       "                 [--yaml|-y YAML_TEMPLATE_FILE]\n"             \
-       "                 [--copy=LUSTRE_SRC]\n"
-
-#define SSM_HELP_COMMON \
-       "\tSTRIPE_COUNT: Number of OSTs to stripe on (0=fs default, -1 all)\n" \
-       "\t              Using -C instead of -c allows overstriping, which\n"  \
-       "\t              will place more than one stripe per OST if\n"         \
-       "\t              stripe_count is greater than the number of OSTs.\n"   \
-       "\tSTART_OST_IDX: OST index of first stripe (-1=default round robin)\n"\
-       "\tSTRIPE_SIZE:  Number of bytes on each OST (0=fs default)\n"         \
-       "\t              Optional K, M, or G suffix (for KB, MB, GB\n"         \
-       "\t              respectively).  Must be a multiple of 64KiB.\n"       \
-       "\tEXTENSION_SIZE:\n"                                                  \
-       "\t              Number of bytes the previous component is extended\n" \
-       "\t              each time. Optional K, M, or G suffix (for KB,\n"     \
-       "\t              MB, GB respectively)\n"                               \
-       "\tPOOL_NAME:    Name of OST pool to use (default none)\n"             \
-       "\tLAYOUT:       stripe pattern type: raid0, mdt (default raid0)\n"    \
-       "\tOST_INDICES:  List of OST indices, can be repeated multiple times\n"\
-       "\t              Indices be specified in a format of:\n"               \
-       "\t                -o OST_1,OST_I-OST_J,OST_N\n"                       \
-       "\t              Or:\n"                                                \
-       "\t                -o OST_1 -o OST_I-OST_J -o OST_N\n"                 \
-       "\t              If --pool is set with --ost then the OSTs\n"          \
-       "\t              must be the members of the pool.\n"                   \
-       "\tCOMP_END:     Extent end of component, start after previous end.\n" \
-       "\t              Optional K, M, or G suffix (for KiB, MiB, GiB), or\n" \
-       "\t              -1 or 'eof' for max file size). Must be a multiple\n" \
-       "\t              of stripe_size and a multiple of 64KiB.\n"            \
-       "\tYAML_TEMPLATE_FILE:\n"                                              \
-       "\t              YAML layout template file, can't be used with -c,\n"  \
-       "\t              -i, -S, -p, -o, or -E arguments.\n"                   \
-       "\tLUSTRE_SRC:   Lustre file/dir whose layout info is used to set\n"   \
-       "\t              another lustre file or directory, can't used with\n"  \
-       "\t              -c, -i, -S, -p, -o, or -E arguments.\n"
-
-#define MIRROR_CREATE_HELP                                                    \
-       "\tMIRROR_COUNT: Number of mirrors to be created with the upcoming\n"  \
-       "\t              setstripe layout options\n"                           \
-       "\t              It defaults to 1 if not specified; if specified,\n"   \
-       "\t              it must follow the option without a space.\n"         \
-       "\t              The option can also be repeated multiple times to\n"  \
-       "\t              separate mirrors that have different layouts.\n"      \
-       "\tSETSTRIPE_OPTIONS: Mirror layout as with 'setstripe'\n"             \
-       "\t              It can be a plain layout or a composite layout.\n"    \
-       "\t              If not specified, the stripe options inherited\n"     \
-       "\t              from the previous component will be used.\n"          \
-       "\tFLAGS:        set flags to the component of the current mirror.\n"  \
-       "\t              Only \"prefer\" flag is supported so far.\n"
-
-#define MIRROR_EXTEND_HELP                                                    \
-       MIRROR_CREATE_HELP                                                     \
-       "\tVICTIM_FILE:  The layout of victim_file will be split and used\n"   \
-       "\t              as a mirror added to the mirrored file.\n"            \
-       "\tno-verify:    This option indicates not to verify the mirror(s)\n"  \
-       "\t              from victim file(s) in case the victim file(s)\n"     \
-       "\t              contains the same data as the original mirrored\n"    \
-       "\t              file.\n"
-
-#define MIRROR_EXTEND_USAGE                                                   \
-       "                 {--mirror-count|-N[mirror_count]}\n"                 \
-       "                 [SETSTRIPE_OPTIONS|-f|--file VICTIM_FILE]\n"         \
+       "                 [--stripe-count|-c STRIPE_COUNT]\n"           \
+       "                 [--stripe-index|-i START_OST_IDX]\n"          \
+       "                 [--stripe-size|-S STRIPE_SIZE]\n"             \
+       "                 [--yaml|-y YAML_TEMPLATE_FILE]\n"
+
+#define MIRROR_EXTEND_USAGE                                            \
+       "                 {--mirror-count|-N[MIRROR_COUNT]}\n"          \
+       "                 [SETSTRIPE_OPTIONS|-f|--file VICTIM_FILE]\n"  \
        "                 [--no-verify]\n"
 
 #define SETSTRIPE_USAGE                                                        \
        SSM_CMD_COMMON("setstripe")                                     \
        MIRROR_EXTEND_USAGE                                             \
-       "                 <directory|filename>\n"                       \
-       SSM_HELP_COMMON                                                 \
-       MIRROR_EXTEND_HELP
+       "                 DIRECTORY|FILENAME\n"
 
 #define MIGRATE_USAGE                                                  \
        SSM_CMD_COMMON("migrate  ")                                     \
        "                 [--block|-b] [--non-block|-n]\n"              \
        "                 [--non-direct|-D] [--verbose|-v]\n"           \
-       "                 <filename>\n"                                 \
-       SSM_HELP_COMMON                                                 \
-       "\n"                                                            \
-       "\tblock:        Block file access during data migration (default)\n" \
-       "\tnon-block:    Abort migrations if concurrent access is detected\n" \
-       "\tnon-direct:   Do not use direct I/O to copy file contents\n" \
-       "\tverbose:      Print each filename as it is migrated\n"       \
+       "                 FILENAME\n"
 
 #define SETDIRSTRIPE_USAGE                                             \
        "               [--mdt-count|-c stripe_count>\n"                \
@@ -290,19 +225,9 @@ static inline int lfs_mirror_delete(int argc, char **argv)
        "               [--default|-D] [--mode|-o mode]\n"              \
        "               [--max-inherit|-X max_inherit]\n"               \
        "               [--max-inherit-rr max_inherit_rr] <dir>\n"      \
-       "\tstripe_count: stripe count of the striped directory\n"       \
-       "\tmdt_index: MDT index of first stripe\n"                      \
-       "\tmdt_hash:  hash type of the striped directory. mdt types:\n" \
-       "       crush     CRUSH hash algorithm (default)\n" \
-       "       fnv_1a_64 FNV-1a hash algorithm\n"              \
-       "       all_char  sum of characters % MDT_COUNT (not recommended)\n" \
-       "\tdefault_stripe: set default dirstripe of the directory\n"    \
-       "\tmode: the file access permission of the directory (octal)\n" \
        "To create dir with a foreign (free format) layout :\n"         \
        "setdirstripe|mkdir --foreign[=FOREIGN_TYPE] -x|-xattr STRING " \
-               "[--mode|-o MODE] [--flags HEX] <dir>\n" \
-       "\tmode: the file access permissions of the directory\n"        \
-       "\tforeign_type: none, daos, symlink, or numeric value\n"
+       "               [--mode|-o MODE] [--flags HEX] DIRECTORY\n"
 
 /**
  * command_t mirror_cmdlist - lfs mirror commands.
@@ -310,32 +235,24 @@ static inline int lfs_mirror_delete(int argc, char **argv)
 command_t mirror_cmdlist[] = {
        { .pc_name = "create", .pc_func = lfs_mirror_create,
          .pc_help = "Create a mirrored file.\n"
-               "usage: lfs mirror create {--mirror-count|-N[MIRROR_COUNT]}\n"
-               "\t\t[SETSTRIPE_OPTIONS] <filename|directory> ...\n"
-         MIRROR_CREATE_HELP },
+               "usage: lfs mirror create --mirror-count|-N[MIRROR_COUNT]\n"
+               "           [SETSTRIPE_OPTIONS] ... FILENAME|DIRECTORY ...\n" },
        { .pc_name = "delete", .pc_func = lfs_mirror_delete,
          .pc_help = "Delete a mirror from a file.\n"
-       "usage: lfs mirror delete {--mirror-id MIRROR_ID|-p POOL|\n"
-       "\t               --component-id|--comp-id|-I COMP_ID} <mirror_file>\n"
+       "usage: lfs mirror delete {--mirror-id <mirror_id> |\n"
+       "\t               --component-id|--comp-id|-I COMP_ID |\n"
+       "\t               -p <pool>} MIRRORED_FILE ...\n"
        },
        { .pc_name = "extend", .pc_func = lfs_mirror_extend,
          .pc_help = "Extend a mirrored file.\n"
-               "usage: lfs mirror extend {--mirror-count|-N[MIRROR_COUNT]}\n"
-               "\t\t[--no-verify] [SETSTRIPE_OPTIONS|-f VICTIM_FILE] ... <filename> ...\n"
-         MIRROR_EXTEND_HELP },
+               "usage: lfs mirror extend "
+               "{--mirror-count|-N[MIRROR_COUNT]} [--no-verify] "
+               "[SETSTRIPE_OPTIONS|-f VICTIM_FILE] ... FILENAME ...\n" },
        { .pc_name = "split", .pc_func = lfs_mirror_split,
          .pc_help = "Split a mirrored file.\n"
-       "usage: lfs mirror split [--destroy|-d] [-f NEW_FILE] [--help|-h]\n"
-       "\t\t{--mirror-id MIRROR_ID|--component-id|-I COMP_ID|-p POOL}\n"
-       "\t\t<mirrored file> ...\n"
-       "\tMIRROR_ID: The numerical unique identifier for a mirror.\n"
-       "\t           It can be fetched by the 'lfs getstripe' command.\n"
-       "\tCOMP_ID:   Unique component ID within a mirror.\n"
-       "\tPOOL:      Components using specified pool.\n"
-       "\tNEW_FILE:  This option indicates the layout of the split\n"
-       "\t           mirror will be stored into. If not specified,\n"
-       "\t           a new file named <mirrored_file>.mirror~MIRROR_ID\n"
-       "\t           will be used.\n" },
+       "usage: lfs mirror split {--mirror-id MIRROR_ID |\n"
+       "\t             --component-id|-I COMP_ID|-p POOL} [--destroy|-d]\n"
+       "\t             [-f NEW_FILE] MIRRORED_FILE ...\n" },
        { .pc_name = "read", .pc_func = lfs_mirror_read,
          .pc_help = "Read the content of a specified mirror of a file.\n"
                "usage: lfs mirror read {--mirror-id|-N MIRROR_ID}\n"
@@ -405,7 +322,6 @@ command_t cmdlist[] = {
         " or\n"
         "To add component(s) to an existing composite file:\n"
         SSM_CMD_COMMON("setstripe --component-add")
-        SSM_HELP_COMMON
         "To totally delete the default striping from an existing directory:\n"
         "usage: setstripe [--delete|-d] <directory>\n"
         " or\n"
@@ -483,32 +399,29 @@ command_t cmdlist[] = {
        {"find", lfs_find, 0,
         "find files matching given attributes recursively in directory tree.\n"
         "usage: find <directory|filename> ...\n"
-        "     [[!] --atime|-A [+-]N[smhdwy]] [[!] --ctime|-C [+-]N[smhdwy]]\n"
-        "     [[!] --mtime|-M [+-]N[smhdwy]]\n"
-        "     [[!] --btime|--Btime|-B [+-]N[smhdwy]] [--help|-h]\n"
-        "     [[!] --newer[XY] <reference>] [[!] --blocks|-b N]\n"
-        "     [--maxdepth|-D N] [[!] --mdt-index|--mdt|-m <uuid|index,...>]\n"
-        "     [[!] --name|-n <pattern>] [[!] --ost|-O <uuid|index,...>]\n"
-        "     [[!] --perm [/-]mode] [[!] --pool <pool>] [--print|-P]\n"
-        "     [--print0|-0] [[!] --projid <projid>]\n"
-        "     [[!] --size|-s [+-]N[bkMGTPE]]\n"
-        "     [[!] --stripe-count|-c [+-]<stripes>]\n"
-        "     [[!] --stripe-index|-i <index,...>]\n"
-        "     [[!] --stripe-size|-S [+-]N[kMGT]] [[!] --type|-t <filetype>]\n"
-        "     [[!] --extension-size|--ext-size|-z [+-]N[kMGT]]\n"
-        "     [[!] --gid|-g|--group|-G <gid>|<gname>]\n"
-        "     [[!] --uid|-u|--user|-U <uid>|<uname>]\n"
-        "     [[!] --layout|-L released,raid0,mdt]\n"
-        "     [[!] --foreign[=<foreign_type>]]\n"
-        "     [[!] --component-count [+-]<comp_cnt>]\n"
+        "     [[!] --atime|-A [+-]N[smhdwy]] [[!] --btime|-B [+-]N[smhdwy]]\n"
+        "     [[!] --ctime|-C [+-]N[smhdwy]] [[!] --mtime|-M [+-]N[smhdwy]]\n"
+        "     [[!] --blocks|-b N] [[!] --component-count [+-]<comp_cnt>]\n"
         "     [[!] --component-start [+-]N[kMGTPE]]\n"
         "     [[!] --component-end|-E [+-]N[kMGTPE]]\n"
         "     [[!] --component-flags {init,stale,prefer,offline,nosync,extension}]\n"
+        "     [[!] --extension-size|--ext-size|-z [+-]N[kMGT]]\n"
+        "     [[!] --foreign[=<foreign_type>]]\n"
+        "     [[!] --gid|-g|--group|-G <gid>|<gname>] [--help|-h]\n"
+        "     [[!] --layout|-L released,raid0,mdt] [--lazy]\n"
+        "     [--maxdepth|-D N] [[!] --mdt-count|-T [+-]<stripes>]\n"
+        "     [[!] --mdt-hash|-H <[^][blm],[^]fnv_1a_64,all_char,crush,...>\n"
+        "     [[!] --mdt-index|--mdt|-m <uuid|index,...>]\n"
         "     [[!] --mirror-count|-N [+-]<n>]\n"
         "     [[!] --mirror-state <[^]state>]\n"
-        "     [[!] --mdt-count|-T [+-]<stripes>]\n"
-        "     [[!] --mdt-hash|-H <[^][blm],[^]fnv_1a_64,all_char,crush,...>\n"
-        "     [[!] --mdt-index|-m <uuid|index,...>]\n"
+        "     [[!] --name|-n <pattern>] [[!] --newer[XY] <reference>]\n"
+        "     [[!] --ost|-O <uuid|index,...>] [[!] --perm [/-]mode]\n"
+        "     [[!] --pool <pool>] [--print|-P] [--print0|-0] [--printf <format>]\n"
+        "     [[!] --projid <projid>] [[!] --size|-s [+-]N[bkMGTPE]]\n"
+        "     [[!] --stripe-count|-c [+-]<stripes>]\n"
+        "     [[!] --stripe-index|-i <index,...>]\n"
+        "     [[!] --stripe-size|-S [+-]N[kMGT]] [[!] --type|-t <filetype>]\n"
+        "     [[!] --uid|-u|--user|-U <uid>|<uname>]\n"
         "\t !: used before an option indicates 'NOT' requested attribute\n"
         "\t -: used before a value indicates less than requested value\n"
         "\t +: used before a value indicates more than requested value\n"
@@ -531,48 +444,14 @@ command_t cmdlist[] = {
         "Usage: getname [--help|-h] [--instance|-i] [--fsname|-n] [path ...]"},
 #ifdef HAVE_SYS_QUOTA_H
        {"setquota", lfs_setquota, 0, "Set filesystem quotas.\n"
-        "usage: setquota {-u|-g|-p} UNAME|UID|GNAME|GID|PROJID\n"
-        "                -b BLOCK_SOFTLIMIT -B BLOCK_HARDLIMIT\n"
-        "                -i INODE_SOFTLIMIT -I INODE_HARDLIMIT <filesystem>\n"
-        "       setquota {-u|--user USER|UID|-g|--group GROUP|GID|-p|--projid PROJID}\n"
-        "                [--block-softlimit BLOCK_SOFTLIMIT]\n"
-        "                [--block-hardlimit BLOCK_HARDLIMIT]\n"
-        "                [--inode-softlimit INODE_SOFTLIMIT]\n"
-        "                [--inode-hardlimit INODE_HARDLIMIT] <filesystem>\n"
-        "       setquota [-t] {-h|--help|-u|--user|-g|--group|-p|--projid}\n"
-        "                [--block-grace 'notify'|BLOCK_GRACE]\n"
-        "                [--inode-grace 'notify'|INODE_GRACE] <filesystem>\n"
-        "       setquota {-U|-G|-P}\n"
-        "                -b BLOCK_SOFTLIMIT -B BLOCK_HARDLIMIT\n"
-        "                -i INODE_SOFTLIMIT -I INODE_HARDLIMIT <filesystem>\n"
-        "       setquota {-U|--default-usr|-G|--default-grp|-P|--default-prj}\n"
-        "                [--block-softlimit BLOCK_SOFTLIMIT]\n"
-        "                [--block-hardlimit BLOCK_HARDLIMIT]\n"
-        "                [--inode-softlimit INODE_SOFTLIMIT]\n"
-        "                [--inode-hardlimit INODE_HARDLIMIT] <filesystem>\n"
-        "       setquota {-u|-g|-p} UNAME|UID|GNAME|GID|PROJID\n"
-        "                {-d|--default}\n"
-        "       -b can be used instead of --block-softlimit/--block-grace\n"
-        "       -B can be used instead of --block-hardlimit\n"
-        "       -i can be used instead of --inode-softlimit/--inode-grace\n"
-        "       -I can be used instead of --inode-hardlimit\n"
-        "       -d can be used instead of --default\n\n"
-        "Note: The total quota space will be split into many qunits and\n"
-        "      balanced over all server targets, the minimal qunit size is\n"
-        "      1M bytes for block space and 1K inodes for inode space.\n\n"
-        "      The maximum quota grace time is 2^48 - 1 seconds.\n\n"
-        "      Quota space rebalancing process will stop when this mininum\n"
-        "      value is reached. As a result, quota exceeded can be returned\n"
-        "      while many targets still have 1MB or 1K inodes of spare\n"
-        "      quota space.\n\n"
-        "      When setting the grace time, 'notify' can be used as grace to\n"
-        "      be notified after the quota is over soft limit but prevents\n"
-        "      the soft limit from becoming the hard limit."},
+        "usage: setquota [-t][-D] {-u|-U|-g|-G|-p|-P} {-b|-B|-i|-I LIMIT} [--pool POOL] FILESYSTEM\n"
+        "       setquota {-u|-g|-p} --delete FILESYSTEM\n"},
        {"quota", lfs_quota, 0, "Display disk usage and limits.\n"
         "usage: quota [-q] [-v] [-h] [-o OBD_UUID|-i MDT_IDX|-I OST_IDX]\n"
-        "             [{-u|-g|-p} UNAME|UID|GNAME|GID|PROJID] <filesystem>\n"
-        "       quota [-o OBD_UUID|-i MDT_IDX|-I OST_IDX] -t {-u|-g|-p} <filesystem>\n"
-       "        quota [-q] [-v] [h] {-U|-G|-P} <filesystem>"},
+        "             [{-u|-g|-p} UNAME|UID|GNAME|GID|PROJID]\n"
+        "             [--pool <OST pool name>] <filesystem>\n"
+        "       quota -t <-u|-g|-p> [--pool <OST pool name>] <filesystem>\n"
+        "       quota [-q] [-v] [h] {-U|-G|-P} [--pool <OST pool name>] <filesystem>"},
        {"project", lfs_project, 0,
         "Change or list project attribute for specified file or directory.\n"
         "usage: project [-d|-r] <file|directory...>\n"
@@ -581,7 +460,7 @@ command_t cmdlist[] = {
         "         set project ID and/or inherit flag for specified file(s) or directories\n"
         "       project -c [-d|-r [-p id] [-0]] <file|directory...>\n"
         "         check project ID and flags on file(s) or directories, print outliers\n"
-        "       project -C [-r] [-k] <file|directory...>\n"
+        "       project -C [-d|-r] [-k] <file|directory...>\n"
         "         clear the project inherit flag and ID on the file or directory\n"
        },
 #endif
@@ -645,39 +524,15 @@ command_t cmdlist[] = {
        {"swap_layouts", lfs_swap_layouts, 0, "Swap layouts between 2 files.\n"
         "usage: swap_layouts <path1> <path2>"},
        {"migrate", lfs_setstripe_migrate, 0,
-        "migrate a directory between MDTs.\n"
-        "usage: migrate [--mdt-count|-c STRIPE_COUNT]\n"
+        "migrate directories and their inodes between MDTs.\n"
+        "usage: migrate [--mdt-count|-c STRIPE_COUNT] [--directory|-d]\n"
         "               [--mdt-hash|-H HASH_TYPE]\n"
         "               [--mdt-index|-m START_MDT_INDEX] [--verbose|-v]\n"
-        "               <directory>\n"
-        "\tmdt:        MDTs to stripe over, if only one MDT is specified\n"
-        "                      it's the MDT index of first stripe\n"
-        "\tmdt_count:  number of MDTs to stripe a directory over\n"
-        "\tmdt_hash:   hash type of the striped directory. mdt types:\n"
-        "              all_char  (type 1)sum of characters % MDT_COUNT\n"
-        "              fnv_1a_64 (type 2)FNV-1a hash algorithm (default)\n"
-        "              crush     (type 3)CRUSH hash algorithm\n"
+        "               DIRECTORY\n"
         "\n"
-        "migrate file objects from one OST "
-        "layout\nto another (may be not safe with concurent writes).\n"
-        "usage: migrate [--stripe-count|-c STRIPE_COUNT]\n"
-        "               [--overstripe-count|-C STRIPE_COUNT]\n"
-        "               [--stripe-index|-i START_OST_INDEX]\n"
-        "               [--stripe-size|-S STRIPE_SIZE]\n"
-        "               [--pool|-p <pool_name>] [--ost|-o OST_INDICES]\n"
-        "               [--block|-b] [--non-block|-n] [--non-direct|-D]\n"
-        "               <file|directory>\n"
-        "\tstripe_count:   number of OSTs to stripe a file over\n"
-        "\t                Using -C instead of -c allows overstriping, which\n"
-        "\t                will place more than one stripe per OST if\n"
-        "\t                stripe_count is greater than the number of OSTs\n"
-        "\tstripe_ost_index: index of the first OST to stripe a file over\n"
-        "\tstripe_size:      number of bytes to store before moving to the next OST\n"
-        "\tpool_name:        name of the predefined pool of OSTs\n"
-        "\tost_indices:      OSTs to stripe over, in order\n"
-        "\tblock:        Block file access during data migration (default)\n"
-        "\tnon-block:    Abort migrations if concurrent access is detected\n"
-        "\tnon-direct:       do not use direct I/O to copy file contents.\n"},
+        "migrate file objects from one OST layout to another\n"
+        "(may be not safe with concurent writes).\n"
+        MIGRATE_USAGE },
        {"mv", lfs_mv, 0,
         "To move directories between MDTs. This command is deprecated, "
         "use \"migrate\" instead.\n"
@@ -737,11 +592,10 @@ static int check_hashtype(const char *hashtype)
        int i;
 
        /* numeric hash type */
-       if (hashtype && strlen(hashtype) == 1 &&
-           (type_num > 0 && type_num < LMV_HASH_TYPE_MAX))
+       if (hashtype && lmv_is_known_hash_type(type_num))
                return type_num;
        /* string hash type */
-       for (i = LMV_HASH_TYPE_ALL_CHARS; i < LMV_HASH_TYPE_MAX; i++)
+       for (i = LMV_HASH_TYPE_ALL_CHARS; i < ARRAY_SIZE(mdt_hash_name); i++)
                if (strcmp(hashtype, mdt_hash_name[i]) == 0)
                        return i;
 
@@ -765,13 +619,6 @@ static uint32_t check_foreign_type_name(const char *foreign_type_name)
 
 static const char *error_loc = "syserror";
 
-enum {
-       MIGRATION_NONBLOCK      = 0x0001,
-       MIGRATION_MIRROR        = 0x0002,
-       MIGRATION_NONDIRECT     = 0x0004,
-       MIGRATION_VERBOSE       = 0x0008,
-};
-
 static int
 migrate_open_files(const char *name, __u64 migration_flags,
                   const struct llapi_stripe_param *param,
@@ -813,15 +660,24 @@ migrate_open_files(const char *name, __u64 migration_flags,
                *ptr = '\0';
        }
 
-       /* open file, direct io */
        /* even if the file is only read, WR mode is nedeed to allow
         * layout swap on fd
         */
-       rflags = O_RDWR | O_NOATIME;
-       if (!(migration_flags & MIGRATION_NONDIRECT))
+       /* Allow migrating even without the key on encrypted files */
+       rflags = O_RDWR | O_NOATIME | O_FILE_ENC;
+       if (!(migration_flags & LLAPI_MIGRATION_NONDIRECT))
                rflags |= O_DIRECT;
+source_open:
        fd = open(name, rflags);
        if (fd < 0) {
+               /* If encrypted file without the key,
+                * retry mirror extend in O_DIRECT.
+                */
+               if (errno == ENOKEY && !(rflags & O_DIRECT) &&
+                   migration_flags & LLAPI_MIGRATION_MIRROR) {
+                       rflags |= O_DIRECT;
+                       goto source_open;
+               }
                rc = -errno;
                error_loc = "cannot open source file";
                return rc;
@@ -834,9 +690,13 @@ migrate_open_files(const char *name, __u64 migration_flags,
        }
 
        do {
-               int open_flags = O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW;
+               int open_flags = O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW |
+                       /* Allow migrating without the key on encrypted files */
+                       O_FILE_ENC;
                mode_t open_mode = S_IRUSR | S_IWUSR;
 
+               if (rflags & O_DIRECT)
+                       open_flags |= O_DIRECT;
                random_value = random();
                rc = snprintf(volatile_file, sizeof(volatile_file),
                              "%s/%s:%.4X:%.4X:fd=%.2d", parent,
@@ -1187,7 +1047,7 @@ int lfs_layout_compid_by_pool(char *fname, const char *pool, int *comp_id)
                rc = -errno;
                goto free_layout;
        }
-       rc = llapi_layout_sanity(layout, fname, false, true);
+       rc = llapi_layout_sanity(layout, false, true);
        if (rc < 0) {
                llapi_layout_sanity_perror(errno);
                goto free_layout;
@@ -1266,14 +1126,29 @@ static int lfs_component_del(char *fname, __u32 comp_id,
 {
        int     rc = 0;
 
-       if (flags && neg_flags)
+       if (flags && neg_flags) {
+               fprintf(stderr,
+                       "%s: cannot specify both positive and negative flags\n",
+                       progname);
                return -EINVAL;
+       }
 
        if (!flags && neg_flags)
                flags = neg_flags | LCME_FL_NEG;
 
-       if ((flags && comp_id) || (!flags && !comp_id))
+       if (flags && comp_id) {
+               fprintf(stderr,
+                       "%s: cannot specify component ID and flags at the same time\n",
+                       progname);
+               return -EINVAL;
+       }
+
+       if (!flags && !comp_id) {
+               fprintf(stderr,
+                       "%s: neither flags nor component ID is specified\n",
+                       progname);
                return -EINVAL;
+       }
 
        if (flags) {
                if (flags & ~LCME_KNOWN_FLAGS) {
@@ -1372,14 +1247,13 @@ static int lfs_migrate(char *name, __u64 migration_flags,
         * if new layout used bigger DOM size, then mirroring is used
         */
        if (dom_new > dom_cur) {
-               rc = lfs_migrate_to_dom(fd, fdv, name, migration_flags, param,
-                                       layout);
+               rc = lfs_migrate_to_dom(fd, fdv, name, migration_flags);
                if (rc)
                        error_loc = "cannot migrate to DOM layout";
                goto out_closed;
        }
 
-       if (!(migration_flags & MIGRATION_NONBLOCK)) {
+       if (!(migration_flags & LLAPI_MIGRATION_NONBLOCK)) {
                /*
                 * Blocking mode (forced if servers do not support file lease).
                 * It is also the default mode, since we cannot distinguish
@@ -1423,7 +1297,7 @@ out_closed:
        if (rc < 0)
                fprintf(stderr, "error: %s: %s: %s: %s\n",
                        progname, name, error_loc, strerror(-rc));
-       else if (migration_flags & MIGRATION_VERBOSE)
+       else if (migration_flags & LLAPI_MIGRATION_VERBOSE)
                printf("%s\n", name);
 
        return rc;
@@ -1496,7 +1370,9 @@ static int mdthash_input(char *string, __u32 *inflags,
                __u32 flag;
        } mhflist[] = {
                {"migrating", LMV_HASH_FLAG_MIGRATION},
+               {"bad_type", LMV_HASH_FLAG_BAD_TYPE},
                {"badtype", LMV_HASH_FLAG_BAD_TYPE},
+               {"lost_lmv", LMV_HASH_FLAG_LOST_LMV},
                {"lostlmv", LMV_HASH_FLAG_LOST_LMV},
        };
 
@@ -1638,7 +1514,7 @@ static int mirror_create_sanity_check(const char *fname,
                        return -ENODATA;
                }
 
-               rc = llapi_layout_sanity(layout, fname, false, true);
+               rc = llapi_layout_sanity(layout, false, true);
 
                llapi_layout_free(layout);
 
@@ -1670,7 +1546,7 @@ static int mirror_create_sanity_check(const char *fname,
                        }
                }
 
-               rc = llapi_layout_sanity(list->m_layout, fname, false, true);
+               rc = llapi_layout_sanity(list->m_layout, false, true);
                if (rc) {
                        llapi_layout_sanity_perror(rc);
                        return rc;
@@ -1971,9 +1847,11 @@ static int mirror_extend_layout(char *name, struct llapi_layout *m_layout,
                        goto out;
                }
        }
+
        llapi_layout_comp_flags_set(m_layout, flags);
-       rc = migrate_open_files(name, MIGRATION_NONDIRECT, NULL, m_layout, &fd,
-                               &fdv);
+       rc = migrate_open_files(name,
+                            LLAPI_MIGRATION_NONDIRECT | LLAPI_MIGRATION_MIRROR,
+                            NULL, m_layout, &fd, &fdv);
        if (rc < 0)
                goto out;
 
@@ -2238,7 +2116,7 @@ static int mirror_split(const char *fname, __u32 id, const char *pool,
                return -EINVAL;
        }
 
-       rc = llapi_layout_sanity(layout, fname, false, true);
+       rc = llapi_layout_sanity(layout, false, true);
        if (rc) {
                llapi_layout_sanity_perror(rc);
                goto free_layout;
@@ -2294,7 +2172,15 @@ static int mirror_split(const char *fname, __u32 id, const char *pool,
                }
        }
 
-       fd = open(fname, O_RDWR);
+       if (!victim_file && mflags & MF_DESTROY)
+               /* Allow mirror split even without the key on encrypted files,
+                * and in this case of a 'split -d', open file with O_DIRECT
+                * (no IOs will be done).
+                */
+               fd = open(fname, O_RDWR | O_DIRECT | O_FILE_ENC);
+       else
+               fd = open(fname, O_RDWR);
+
        if (fd < 0) {
                fprintf(stderr,
                        "error %s: open file '%s' failed: %s\n",
@@ -2378,7 +2264,11 @@ again:
 
                                        open_flags = O_RDWR |
                                             (O_LOV_DELAY_CREATE & ~O_ACCMODE) |
-                                            O_CREAT | O_EXCL | O_NOFOLLOW;
+                                            O_CREAT | O_EXCL | O_NOFOLLOW |
+                                            /* O_DIRECT for mirror split -d */
+                                            O_DIRECT |
+                                            /* Allow split without the key */
+                                            O_FILE_ENC;
                                        fdv = open(file_path, open_flags,
                                                   S_IRUSR | S_IWUSR);
                                        if (fdv < 0)
@@ -2440,7 +2330,7 @@ again:
        data->lil_ids[1] = mirror_id;
        rc = llapi_lease_set(fd, data);
        if (rc <= 0) {
-               if (rc == -EINVAL && purge) {
+               if ((rc == -EINVAL || rc == -EBUSY) && purge) {
                        /* could be old MDS which prohibit fd==fdv */
                        purge = false;
                        goto again;
@@ -2471,9 +2361,7 @@ int lfs_mirror_resync_file(const char *fname, struct ll_ioc_lease *ioc,
                           __u16 *mirror_ids, int ids_nr);
 
 static int lfs_migrate_to_dom(int fd, int fdv, char *name,
-                             __u64 migration_flags,
-                             struct llapi_stripe_param *param,
-                             struct llapi_layout *layout)
+                             __u64 migration_flags)
 {
        struct ll_ioc_lease *data = NULL;
        int rc;
@@ -2484,11 +2372,15 @@ static int lfs_migrate_to_dom(int fd, int fdv, char *name,
                goto out_close;
        }
 
+       rc = migrate_nonblock(fd, fdv);
+       if (rc < 0)
+               goto out_release;
+
        /* Atomically put lease, merge layouts, resync and close. */
-       data = calloc(1, offsetof(typeof(*data), lil_ids[1024]));
+       data = calloc(1, offsetof(typeof(*data), lil_ids[1]));
        if (!data) {
                error_loc = "memory allocation";
-               goto out_close;
+               goto out_release;
        }
        data->lil_mode = LL_LEASE_UNLCK;
        data->lil_flags = LL_LEASE_LAYOUT_MERGE;
@@ -2518,6 +2410,8 @@ static int lfs_migrate_to_dom(int fd, int fdv, char *name,
                error_loc = "cannot delete old layout";
        goto out;
 
+out_release:
+       llapi_lease_release(fd);
 out_close:
        close(fd);
        close(fdv);
@@ -2525,7 +2419,7 @@ out:
        if (rc < 0)
                fprintf(stderr, "error: %s: %s: %s: %s\n",
                        progname, name, error_loc, strerror(-rc));
-       else if (migration_flags & MIGRATION_VERBOSE)
+       else if (migration_flags & LLAPI_MIGRATION_VERBOSE)
                printf("%s\n", name);
        if (data)
                free(data);
@@ -3438,6 +3332,7 @@ static void lfs_mirror_list_free(struct mirror_args *mirror_list)
 }
 
 enum {
+       LFS_SETQUOTA_DELETE = 1,
        LFS_POOL_OPT = 3,
        LFS_COMP_COUNT_OPT,
        LFS_COMP_START_OPT,
@@ -3457,6 +3352,7 @@ enum {
        LFS_NEWERXY_OPT,
        LFS_INHERIT_RR_OPT,
        LFS_FIND_PERM,
+       LFS_PRINTF_OPT,
 };
 
 #ifndef LCME_USER_MIRROR_FLAGS
@@ -3554,6 +3450,8 @@ static int lfs_setstripe_internal(int argc, char **argv,
                                                .has_arg = required_argument},
        { .val = 'd',   .name = "delete",       .has_arg = no_argument},
        { .val = 'd',   .name = "destroy",      .has_arg = no_argument},
+       /* used with "lfs migrate -m" */
+       { .val = 'd',   .name = "directory",    .has_arg = no_argument},
        /* --non-direct is only valid in migrate mode */
        { .val = 'D',   .name = "non-direct",   .has_arg = no_argument },
        { .val = 'E',   .name = "comp-end",     .has_arg = required_argument},
@@ -3585,7 +3483,6 @@ static int lfs_setstripe_internal(int argc, char **argv,
        { .val = 'p',   .name = "pool",         .has_arg = required_argument },
 /* find        { .val = 'P',   .name = "print",        .has_arg = no_argument }, */
 /* getstripe { .val = 'q', .name = "quiet",    .has_arg = no_argument }, */
-/* getstripe { .val = 'r', .name = "recursive",        .has_arg = no_argument }, */
 /* getstripe { .val = 'R', .name = "raw",      .has_arg = no_argument }, */
        { .val = 'S',   .name = "stripe-size",  .has_arg = required_argument },
        { .val = 'S',   .name = "stripe_size",  .has_arg = required_argument },
@@ -3770,11 +3667,11 @@ static int lfs_setstripe_internal(int argc, char **argv,
                                goto usage_error;
                        }
                        lsa.lsa_pattern = LLAPI_LAYOUT_OVERSTRIPING;
-                       /* fall through */
+                       fallthrough;
                case 'c':
                        errno = 0;
                        lsa.lsa_stripe_count = strtoul(optarg, &end, 0);
-                       if (errno != 0 || *end != '\0'||
+                       if (errno != 0 || *end != '\0'|| optarg == end ||
                            lsa.lsa_stripe_count < -1 ||
                            lsa.lsa_stripe_count > LOV_MAX_STRIPE_COUNT) {
                                fprintf(stderr,
@@ -3787,16 +3684,20 @@ static int lfs_setstripe_internal(int argc, char **argv,
                                lsa.lsa_stripe_count = LLAPI_LAYOUT_WIDE;
                        break;
                case 'd':
-                       /* delete the default striping pattern */
-                       delete = 1;
-                       if (opc == SO_MIRROR_SPLIT) {
-                               if (has_m_file) {
-                                       fprintf(stderr,
-                                             "%s %s: -d cannot used with -f\n",
-                                               progname, argv[0]);
-                                       goto usage_error;
+                       if (migrate_mode) {
+                               migrate_mdt_param.fp_max_depth = 1;
+                       } else {
+                               /* delete the default striping pattern */
+                               delete = 1;
+                               if (opc == SO_MIRROR_SPLIT) {
+                                       if (has_m_file) {
+                                               fprintf(stderr,
+                                                     "%s %s: -d cannot used with -f\n",
+                                                       progname, argv[0]);
+                                               goto usage_error;
+                                       }
+                                       mirror_flags |= MF_DESTROY;
                                }
-                               mirror_flags |= MF_DESTROY;
                        }
                        break;
                case 'D':
@@ -3806,7 +3707,7 @@ static int lfs_setstripe_internal(int argc, char **argv,
                                        progname, argv[0]);
                                goto usage_error;
                        }
-                       migration_flags |= MIGRATION_NONDIRECT;
+                       migration_flags |= LLAPI_MIGRATION_NONDIRECT;
                        break;
                case 'E':
                        if (lsa.lsa_comp_end != 0) {
@@ -3856,7 +3757,7 @@ static int lfs_setstripe_internal(int argc, char **argv,
                case 'i':
                        errno = 0;
                        lsa.lsa_stripe_off = strtol(optarg, &end, 0);
-                       if (errno != 0 || *end != '\0' ||
+                       if (errno != 0 || *end != '\0' || optarg == end ||
                            lsa.lsa_stripe_off < -1 ||
                            lsa.lsa_stripe_off > LOV_V1_INSANE_STRIPE_COUNT) {
                                fprintf(stderr,
@@ -3955,7 +3856,7 @@ static int lfs_setstripe_internal(int argc, char **argv,
                                        progname, argv[0]);
                                goto usage_error;
                        }
-                       migration_flags |= MIGRATION_NONBLOCK;
+                       migration_flags |= LLAPI_MIGRATION_NONBLOCK;
                        break;
                case 'N':
                        if (opc == SO_SETSTRIPE) {
@@ -4069,7 +3970,7 @@ static int lfs_setstripe_internal(int argc, char **argv,
                                goto usage_error;
                        }
                        migrate_mdt_param.fp_verbose = VERBOSE_DETAIL;
-                       migration_flags = MIGRATION_VERBOSE;
+                       migration_flags = LLAPI_MIGRATION_VERBOSE;
                        break;
                case 'x':
                        xattr = optarg;
@@ -4257,7 +4158,7 @@ static int lfs_setstripe_internal(int argc, char **argv,
                goto error;
        }
 
-       if ((migration_flags & MIGRATION_NONBLOCK) && migration_block) {
+       if ((migration_flags & LLAPI_MIGRATION_NONBLOCK) && migration_block) {
                fprintf(stderr,
                        "%s %s: options --non-block and --block are mutually exclusive\n",
                        progname, argv[0]);
@@ -4537,19 +4438,25 @@ static time_t set_time(struct find_param *param, time_t *time, time_t *set,
                switch (*endptr) {
                case  'y':
                        unit *= 52; /* 52 weeks + 1 day below */
-               case  'w':      /* fallthrough */
+                       fallthrough;
+               case  'w':
                        unit *= 7;
                        if (param->fp_time_margin == FP_DEFAULT_TIME_MARGIN)
                                param->fp_time_margin *= (1 + unit / 52);
                        unit += (*endptr == 'y'); /* +1 day for 365 days/year */
+                       fallthrough;
                case '\0': /* days are default unit if none used */
-               case  'd':      /* fallthrough */
+                       fallthrough;
+               case  'd':
                        unit *= 24;
-               case  'h':      /* fallthrough */
+                       fallthrough;
+               case  'h':
                        unit *= 60;
-               case  'm':      /* fallthrough */
+                       fallthrough;
+               case  'm':
                        unit *= 60;
-               case  's':      /* fallthrough */
+                       fallthrough;
+               case  's':
                        break;
                        /* don't need to multiply by 1 for seconds */
                default:
@@ -5011,11 +4918,15 @@ static int lfs_find(int argc, char **argv)
 /* find        { .val = 'o'    .name = "or", .has_arg = no_argument }, like find(1) */
        { .val = 'O',   .name = "obd",          .has_arg = required_argument },
        { .val = 'O',   .name = "ost",          .has_arg = required_argument },
+       { .val = LFS_FIND_PERM,
+                       .name = "perm",         .has_arg = required_argument },
        /* no short option for pool yet, can be 'p' after 2.18 */
        { .val = LFS_POOL_OPT,
                        .name = "pool",         .has_arg = required_argument },
        { .val = '0',   .name = "print0",       .has_arg = no_argument },
        { .val = 'P',   .name = "print",        .has_arg = no_argument },
+       { .val = LFS_PRINTF_OPT,
+                       .name = "printf",       .has_arg = required_argument },
        { .val = LFS_PROJID_OPT,
                        .name = "projid",       .has_arg = required_argument },
 /* getstripe { .val = 'q', .name = "quiet",    .has_arg = no_argument }, */
@@ -5025,16 +4936,13 @@ static int lfs_find(int argc, char **argv)
        { .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 = LFS_FIND_PERM,
-                       .name = "perm",         .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 },
+/* getstripe { .val = 'v', .name = "verbose",  .has_arg = no_argument }, */
        { .val = 'z',   .name = "extension-size",
                                                .has_arg = required_argument },
        { .val = 'z',   .name = "ext-size",     .has_arg = required_argument },
-/* getstripe { .val = 'v', .name = "verbose",  .has_arg = no_argument }, */
-/* getstripe { .val = 'y', .name = "yaml",     .has_arg = no_argument }, */
        { .name = NULL } };
        int optidx = 0;
        int pathstart = -1;
@@ -5050,7 +4958,7 @@ static int lfs_find(int argc, char **argv)
 
        /* when getopt_long_only() hits '!' it returns 1, puts "!" in optarg */
        while ((c = getopt_long_only(argc, argv,
-               "-0A:b:B:c:C:D:E:g:G:hH:i:L:m:M:n:N:O:Ppqrs:S:t:T:u:U:vz:",
+               "-0A:b:B:c:C:D:E:g:G:hH:i:L:m:M:n:N:O:Ppqrs:S:t:T:u:U:z:",
                long_opts, &optidx)) >= 0) {
                xtime = NULL;
                xsign = NULL;
@@ -5093,6 +5001,7 @@ static int lfs_find(int argc, char **argv)
                        xsign = &param.fp_asign;
                        param.fp_exclude_atime = !!neg_opt;
                        /* no break, this falls through to 'B' for btime */
+                       fallthrough;
                case 'B':
                        if (c == 'B') {
                                xtime = &param.fp_btime;
@@ -5100,6 +5009,7 @@ static int lfs_find(int argc, char **argv)
                                param.fp_exclude_btime = !!neg_opt;
                        }
                        /* no break, this falls through to 'C' for ctime */
+                       fallthrough;
                case 'C':
                        if (c == 'C') {
                                xtime = &param.fp_ctime;
@@ -5107,6 +5017,7 @@ static int lfs_find(int argc, char **argv)
                                param.fp_exclude_ctime = !!neg_opt;
                        }
                        /* no break, this falls through to 'M' for mtime */
+                       fallthrough;
                case 'M':
                        if (c == 'M') {
                                xtime = &param.fp_mtime;
@@ -5640,6 +5551,9 @@ err_free:
                        break;
                case 'P': /* we always print, this option is a no-op */
                        break;
+               case LFS_PRINTF_OPT:
+                       param.fp_format_printf_str = optarg;
+                       break;
                case LFS_PROJID_OPT:
                        rc = name2projid(&param.fp_projid, optarg);
                        if (rc) {
@@ -5794,6 +5708,8 @@ err_free:
                        goto err;
                }
        }
+       if (!param.fp_verbose)
+               param.fp_verbose = VERBOSE_DEFAULT;
 
        if (pathstart == -1) {
                fprintf(stderr, "error: %s: no filename|pathname\n",
@@ -6308,12 +6224,13 @@ static int lfs_getdirstripe(int argc, char **argv)
                case 't':
                        fprintf(stderr,
                                "warning: '-t' deprecated, use '--mdt-hash' or '-H' instead\n");
-                       /* fallthrough */
+                       fallthrough;
 #endif
                case 'H':
                        param.fp_verbose |= VERBOSE_HASH_TYPE;
                        break;
-               case 'i': /* fallthrough */
+               case 'i':
+                       fallthrough;
                case 'm':
                        param.fp_verbose |= VERBOSE_STRIPE_OFFSET;
                        break;
@@ -6344,7 +6261,7 @@ static int lfs_getdirstripe(int argc, char **argv)
                default:
                        fprintf(stderr, "%s: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
-                       /* fallthrough */
+                       fallthrough;
                case 'h':
                        return CMD_HELP;
                }
@@ -6606,13 +6523,14 @@ static int mntdf(char *mntdir, char *fsname, char *pool, enum mntdf_flags flags,
                if (!(tp->st_op & ops))
                        continue;
 
-               for (index = 0; ; index++) {
+               for (index = 0; index < LOV_ALL_STRIPES &&
+                    (!lsb || lsb->sb_count < LL_STATFS_MAX); index++) {
                        memset(&stat_buf, 0, sizeof(struct obd_statfs));
                        memset(&uuid_buf, 0, sizeof(struct obd_uuid));
                        type = flags & MNTDF_LAZY ?
                                tp->st_op | LL_STATFS_NODELAY : tp->st_op;
                        rc2 = llapi_obd_fstatfs(fd, type, index,
-                                              &stat_buf, &uuid_buf);
+                                               &stat_buf, &uuid_buf);
                        if (rc2 == -ENODEV)
                                break;
                        if (rc2 == -EAGAIN)
@@ -6835,13 +6753,13 @@ static int lfs_setdirstripe(int argc, char **argv)
                case 't':
                        fprintf(stderr,
                                "warning: '--hash-type' and '-t' deprecated, use '--mdt-hash' or '-H' instead\n");
-                       /* fallthrough */
+                       fallthrough;
 #endif
                case 'H':
                        lsa.lsa_pattern = check_hashtype(optarg);
                        if (lsa.lsa_pattern == 0) {
                                fprintf(stderr,
-                                       "%s %s: bad stripe hash type '%s'\n",
+                                       "%s %s: bad directory hash type '%s'\n",
                                        progname, argv[0], optarg);
                                return CMD_HELP;
                        }
@@ -6882,12 +6800,6 @@ static int lfs_setdirstripe(int argc, char **argv)
                        xattr = optarg;
                        break;
                case 'X':
-                       if (!default_stripe) {
-                               fprintf(stderr,
-                                       "%s %s: '--max-inherit' must be specified with '-D'\n",
-                                       progname, argv[0]);
-                               return CMD_HELP;
-                       }
                        errno = 0;
                        max_inherit = strtol(optarg, &end, 10);
                        if (errno != 0 || *end != '\0' || max_inherit < -2) {
@@ -6938,7 +6850,7 @@ static int lfs_setdirstripe(int argc, char **argv)
                default:
                        fprintf(stderr, "%s: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
-                       /* fallthrough */
+                       fallthrough;
                case 'h':
                        return CMD_HELP;
                }
@@ -7000,6 +6912,21 @@ static int lfs_setdirstripe(int argc, char **argv)
                previous_mode = umask(0);
        }
 
+       /* check max-inherit and warn user in some cases */
+       if (default_stripe &&
+           (lsa.lsa_stripe_count < 0 || lsa.lsa_stripe_count > 1)) {
+               if (max_inherit == LMV_INHERIT_UNLIMITED)
+                       fprintf(stderr,
+                       "%s %s: unrecommended max-inherit=-1 when default stripe-count=%lld\n",
+                       progname, argv[0], lsa.lsa_stripe_count);
+               else if (max_inherit > LMV_INHERIT_DEFAULT_STRIPED + 2 &&
+                        max_inherit != LMV_INHERIT_NONE)
+                       fprintf(stderr,
+                               "%s %s: unrecommended max-inherit=%d when default stripe-count=%lld\n",
+                               progname, argv[0], max_inherit,
+                               lsa.lsa_stripe_count);
+       }
+
        if (max_inherit_rr != LAYOUT_INHERIT_UNSET &&
            lsa.lsa_stripe_off != LLAPI_LAYOUT_DEFAULT &&
            lsa.lsa_stripe_off != LMV_OFFSET_DEFAULT) {
@@ -7059,12 +6986,17 @@ static int lfs_setdirstripe(int argc, char **argv)
                param->lsp_stripe_pattern = LMV_HASH_TYPE_UNKNOWN;
        param->lsp_pool = lsa.lsa_pool_name;
        param->lsp_is_specific = false;
+       if (max_inherit == LAYOUT_INHERIT_UNSET) {
+               if (lsa.lsa_stripe_count == 0 || lsa.lsa_stripe_count == 1)
+                       max_inherit = LMV_INHERIT_DEFAULT_PLAIN;
+               else
+                       max_inherit = LMV_INHERIT_DEFAULT_STRIPED;
+       }
+       param->lsp_max_inherit = max_inherit;
        if (default_stripe) {
-               if (max_inherit == LAYOUT_INHERIT_UNSET)
-                       max_inherit = LMV_INHERIT_DEFAULT;
+
                if (max_inherit_rr == LAYOUT_INHERIT_UNSET)
                        max_inherit_rr = LMV_INHERIT_RR_DEFAULT;
-               param->lsp_max_inherit = max_inherit;
                param->lsp_max_inherit_rr = max_inherit_rr;
        }
        if (strcmp(argv[0], "mkdir") == 0)
@@ -7248,7 +7180,7 @@ static int lfs_df(int argc, char **argv)
        char mntdir[PATH_MAX] = {'\0'}, path[PATH_MAX] = {'\0'};
        enum mntdf_flags flags = MNTDF_SHOW;
        int ops = LL_STATFS_LMV | LL_STATFS_LOV;
-       int c, rc = 0, index = 0;
+       int c, rc = 0, rc1 = 0, index = 0, arg_idx = 0;
        char fsname[PATH_MAX] = "", *pool_name = NULL;
        struct option long_opts[] = {
        { .val = 'h',   .name = "human-readable", .has_arg = no_argument },
@@ -7285,26 +7217,75 @@ static int lfs_df(int argc, char **argv)
                        return CMD_HELP;
                }
        }
-       if (optind < argc && !realpath(argv[optind], path)) {
-               rc = -errno;
-               fprintf(stderr, "%s: invalid path '%s': %s\n",
-                       progname, argv[optind], strerror(-rc));
+
+       /* Handle case where path is not specified */
+       if (optind == argc) {
+               while (!llapi_search_mounts(path, index++, mntdir, fsname)) {
+                       /* Check if we have a mount point */
+                       if (mntdir[0] == '\0')
+                               continue;
+
+                       rc = mntdf(mntdir, fsname, pool_name, flags, ops, NULL);
+                       if (rc || path[0] != '\0')
+                               break;
+
+                       fsname[0] = '\0'; /* avoid matching in next loop */
+                       mntdir[0] = '\0'; /* avoid matching in next loop */
+                       path[0] = '\0'; /* clean for next loop */
+               }
                return rc;
        }
 
-       while (!llapi_search_mounts(path, index++, mntdir, fsname)) {
-               /* Check if we have a mount point */
-               if (mntdir[0] == '\0')
+       /* Loop through all the remaining arguments. These are Lustre FS
+        * paths.
+        */
+       for (arg_idx = optind; arg_idx <= argc - 1; arg_idx++) {
+               bool valid = false;
+
+               fsname[0] = '\0'; /* start clean */
+               mntdir[0] = '\0'; /* start clean */
+               path[0] = '\0';   /* start clean */
+
+               /* path does not exists at all */
+               if (!realpath(argv[arg_idx], path)) {
+                       rc = -errno;
+                       fprintf(stderr, "error: invalid path '%s': %s\n",
+                               argv[arg_idx], strerror(-rc));
+                       /* save first seen error */
+                       if (!rc1)
+                               rc1 = rc;
+
                        continue;
+               }
 
-               rc = mntdf(mntdir, fsname, pool_name, flags, ops, NULL);
-               if (rc || path[0] != '\0')
-                       break;
-               fsname[0] = '\0'; /* avoid matching in next loop */
-               mntdir[0] = '\0'; /* avoid matching in next loop */
+               /* path exists but may not be a Lustre filesystem */
+               while (!llapi_search_mounts(path, index++, mntdir, fsname)) {
+                       /* Check if we have a mount point */
+                       if (mntdir[0] == '\0')
+                               continue;
+
+                       rc = mntdf(mntdir, fsname, pool_name, flags, ops, NULL);
+                       if (rc || path[0] != '\0') {
+                               valid = true;
+
+                               /* save first seen error */
+                               if (!rc1)
+                                       rc1 = rc;
+                               break;
+                       }
+               }
+
+               if (!valid) {
+                       llapi_printf(LLAPI_MSG_ERROR,
+                                    "%s:%s Not a Lustre filesystem\n",
+                                    argv[0], argv[arg_idx]);
+                       /* save first seen error */
+                       if (!rc1)
+                               rc1 = -EOPNOTSUPP;
+               }
        }
 
-       return rc;
+       return rc1;
 }
 
 static int print_instance(const char *mntdir, char *buf, size_t buflen,
@@ -7361,7 +7342,7 @@ static int lfs_getname(int argc, char **argv)
                default:
                        fprintf(stderr, "%s: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
-                       /* fallthrough */
+                       fallthrough;
                case 'h':
                        return CMD_HELP;
                }
@@ -7653,7 +7634,7 @@ quota_type:
                default:
                        fprintf(stderr, "%s: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
-                       /* fallthrough */
+                       fallthrough;
                case 'h':
                        return CMD_HELP;
                }
@@ -7701,6 +7682,8 @@ int lfs_setquota(int argc, char **argv)
        { .val = 'B',   .name = "block-hardlimit",
                                                .has_arg = required_argument },
        { .val = 'd',   .name = "default",      .has_arg = no_argument },
+       { .val = LFS_SETQUOTA_DELETE,
+                       .name = "delete",       .has_arg = no_argument },
        { .val = 'g',   .name = "group",        .has_arg = required_argument },
        { .val = 'G',   .name = "default-grp",  .has_arg = no_argument },
        { .val = 'h',   .name = "help",         .has_arg = no_argument },
@@ -7738,8 +7721,7 @@ int lfs_setquota(int argc, char **argv)
                                   * 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:dg:Ghi:I:p:Pu:U",
+       while ((c = getopt_long(argc, argv, "b:B:dDg:Ghi:I:p:Pu:U",
                long_opts, NULL)) != -1) {
                switch (c) {
                case 'U':
@@ -7797,9 +7779,19 @@ quota_type_def:
                        }
                        qctl->qc_type = qtype;
                        break;
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
                case 'd':
-                       qctl->qc_cmd = LUSTRE_Q_SETDEFAULT;
+#if LUSTRE_VERSION_CODE > OBD_OCD_VERSION(2, 15, 53, 0)
+                       fprintf(stderr, "'-d' deprecatd, use '-D' or '--default'\n");
+#endif
+                       /* falltrrough */
+#endif
+               case 'D':
                        use_default = true;
+                       qctl->qc_cmd = LUSTRE_Q_SETDEFAULT;
+                       break;
+               case LFS_SETQUOTA_DELETE:
+                       qctl->qc_cmd = LUSTRE_Q_DELETEQID;
                        break;
                case 'b':
                        ARG2ULL(dqb->dqb_bsoftlimit, optarg, 1024);
@@ -7862,7 +7854,7 @@ quota_type_def:
                        fprintf(stderr,
                                "%s setquota: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
-                       /* fallthrough */
+                       fallthrough;
                case 'h':
                        rc = CMD_HELP;
                        goto out;
@@ -7877,7 +7869,8 @@ quota_type_def:
                goto out;
        }
 
-       if (!use_default && limit_mask == 0) {
+       if (!use_default && qctl->qc_cmd != LUSTRE_Q_DELETEQID &&
+           limit_mask == 0) {
                fprintf(stderr,
                        "%s setquota: at least one limit must be specified\n",
                        progname);
@@ -7885,9 +7878,10 @@ quota_type_def:
                goto out;
        }
 
-       if (use_default && limit_mask != 0) {
+       if ((use_default || qctl->qc_cmd == LUSTRE_Q_DELETEQID)  &&
+           limit_mask != 0) {
                fprintf(stderr,
-                       "%s setquota: limits should not be specified when using default quota\n",
+                       "%s setquota: limits should not be specified when using default quota or deleting quota ID\n",
                        progname);
                rc = CMD_HELP;
                goto out;
@@ -7901,6 +7895,14 @@ quota_type_def:
                goto out;
        }
 
+       if (qctl->qc_cmd == LUSTRE_Q_DELETEQID  && qctl->qc_id == 0) {
+               fprintf(stderr,
+                       "%s setquota: can not delete root user/group/project\n",
+                       progname);
+               rc = CMD_HELP;
+               goto out;
+       }
+
        if (optind != argc - 1) {
                fprintf(stderr,
                        "%s setquota: filesystem not specified or unexpected argument '%s'\n",
@@ -7925,33 +7927,48 @@ quota_type_def:
        } else if ((!(limit_mask & BHLIMIT) ^ !(limit_mask & BSLIMIT)) ||
                   (!(limit_mask & IHLIMIT) ^ !(limit_mask & ISLIMIT))) {
                /* sigh, we can't just set blimits/ilimits */
-               struct if_quotactl tmp_qctl = {.qc_cmd  = LUSTRE_Q_GETQUOTA,
-                                              .qc_type = qctl->qc_type,
-                                              .qc_id   = qctl->qc_id};
+               struct if_quotactl *tmp_qctl;
 
-               rc = llapi_quotactl(mnt, &tmp_qctl);
-               if (rc < 0)
+               tmp_qctl = calloc(1, sizeof(*qctl) + LOV_MAXPOOLNAME + 1);
+               if (!tmp_qctl)
+                       goto out;
+
+               if (qctl->qc_cmd == LUSTRE_Q_SETQUOTAPOOL) {
+                       tmp_qctl->qc_cmd = LUSTRE_Q_GETQUOTAPOOL;
+                       strncpy(tmp_qctl->qc_poolname, qctl->qc_poolname,
+                               LOV_MAXPOOLNAME);
+               } else {
+                       tmp_qctl->qc_cmd  = LUSTRE_Q_GETQUOTA;
+               }
+               tmp_qctl->qc_type = qctl->qc_type;
+               tmp_qctl->qc_id = qctl->qc_id;
+
+               rc = llapi_quotactl(mnt, tmp_qctl);
+               if (rc < 0) {
+                       free(tmp_qctl);
                        goto out;
+               }
 
                if (!(limit_mask & BHLIMIT))
-                       dqb->dqb_bhardlimit = tmp_qctl.qc_dqblk.dqb_bhardlimit;
+                       dqb->dqb_bhardlimit = tmp_qctl->qc_dqblk.dqb_bhardlimit;
                if (!(limit_mask & BSLIMIT))
-                       dqb->dqb_bsoftlimit = tmp_qctl.qc_dqblk.dqb_bsoftlimit;
+                       dqb->dqb_bsoftlimit = tmp_qctl->qc_dqblk.dqb_bsoftlimit;
                if (!(limit_mask & IHLIMIT))
-                       dqb->dqb_ihardlimit = tmp_qctl.qc_dqblk.dqb_ihardlimit;
+                       dqb->dqb_ihardlimit = tmp_qctl->qc_dqblk.dqb_ihardlimit;
                if (!(limit_mask & ISLIMIT))
-                       dqb->dqb_isoftlimit = tmp_qctl.qc_dqblk.dqb_isoftlimit;
+                       dqb->dqb_isoftlimit = tmp_qctl->qc_dqblk.dqb_isoftlimit;
 
                /* Keep grace times if we have got no softlimit arguments */
                if ((limit_mask & BHLIMIT) && !(limit_mask & BSLIMIT)) {
                        dqb->dqb_valid |= QIF_BTIME;
-                       dqb->dqb_btime = tmp_qctl.qc_dqblk.dqb_btime;
+                       dqb->dqb_btime = tmp_qctl->qc_dqblk.dqb_btime;
                }
 
                if ((limit_mask & IHLIMIT) && !(limit_mask & ISLIMIT)) {
                        dqb->dqb_valid |= QIF_ITIME;
-                       dqb->dqb_itime = tmp_qctl.qc_dqblk.dqb_itime;
+                       dqb->dqb_itime = tmp_qctl->qc_dqblk.dqb_itime;
                }
+               free(tmp_qctl);
        }
 
        dqb->dqb_valid |= (limit_mask & (BHLIMIT | BSLIMIT)) ? QIF_BLIMITS : 0;
@@ -7961,9 +7978,13 @@ quota_type_def:
        if (rc) {
                if (*obd_type)
                        fprintf(stderr,
-                               "%s setquota: cannot quotactl '%s' '%s': %s",
+                               "%s setquota: cannot quotactl '%s' '%s': %s\n",
                                progname, obd_type,
                                obd_uuid2str(&qctl->obd_uuid), strerror(-rc));
+               else
+                       fprintf(stderr,
+                               "%s setquota: quotactl failed: %s\n",
+                               progname, strerror(-rc));
        }
 out:
        if (rc)
@@ -8287,6 +8308,28 @@ static int print_obd_quota(char *mnt, struct if_quotactl *qctl, int is_mdt,
                                goto out;
                        }
 
+                       /* no target for this index yet */
+                       if (rc == -ENODEV) {
+                               rc = 0;
+                               continue;
+                       }
+
+                       /* inactive target */
+                       if (rc == -ENODATA) {
+                               char name[UUID_MAX+8];
+
+                               snprintf(name, sizeof(name), "%s[inact]",
+                                       obd_uuid2str(&qctl->obd_uuid));
+                               memset(&qctl->qc_dqinfo, 0,
+                                      sizeof(qctl->qc_dqinfo));
+                               memset(&qctl->qc_dqblk, 0,
+                                      sizeof(qctl->qc_dqblk));
+                               print_quota(name, qctl, qctl->qc_valid, 0, h,
+                                           false);
+                               rc = 0;
+                               continue;
+                       }
+
                        if (!rc1)
                                rc1 = rc;
                        fprintf(stderr, "quotactl %s%d failed.\n",
@@ -9497,7 +9540,7 @@ static int lfs_data_version(int argc, char **argv)
                        fprintf(stderr,
                                "%s data_version: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
-                       /* fallthrough */
+                       fallthrough;
                case 'h':
                        return CMD_HELP;
                }
@@ -9641,7 +9684,7 @@ static int lfs_hsm_change_flags(int argc, char **argv, int mode)
                default:
                        fprintf(stderr, "%s: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
-                       /* fallthrough */
+                       fallthrough;
                case 'h':
                        return CMD_HELP;
                }
@@ -9875,7 +9918,7 @@ static int lfs_hsm_request(int argc, char **argv, int action)
                default:
                        fprintf(stderr, "%s: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
-                       /* fallthrough */
+                       fallthrough;
                case 'h':
                        return CMD_HELP;
                }
@@ -10175,7 +10218,7 @@ static int lfs_ladvise(int argc, char **argv)
                default:
                        fprintf(stderr, "%s: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
-                       /* fallthrough */
+                       fallthrough;
                case 'h':
                        return CMD_HELP;
                }
@@ -10364,7 +10407,7 @@ static int lfs_heat_set(int argc, char **argv)
                default:
                        fprintf(stderr, "%s: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
-                       /* fallthrough */
+                       fallthrough;
                case 'h':
                        return CMD_HELP;
                }
@@ -10665,7 +10708,8 @@ int lfs_mirror_resync_file(const char *fname, struct ll_ioc_lease *ioc,
                goto error;
        }
 
-       fd = open(fname, O_DIRECT | O_RDWR);
+       /* Allow mirror resync even without the key on encrypted files */
+       fd = open(fname, O_DIRECT | O_RDWR | O_FILE_ENC);
        if (fd < 0) {
                fprintf(stderr, "%s: cannot open '%s': %s.\n",
                        progname, fname, strerror(errno));
@@ -10816,7 +10860,7 @@ static inline int lfs_mirror_resync(int argc, char **argv)
                default:
                        fprintf(stderr, "%s: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
-                       /* fallthrough */
+                       fallthrough;
                case 'h':
                        rc = CMD_HELP;
                        goto error;
@@ -10962,7 +11006,7 @@ static inline int lfs_mirror_read(int argc, char **argv)
                default:
                        fprintf(stderr, "%s: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
-                       /* fallthrough */
+                       fallthrough;
                case 'h':
                        return CMD_HELP;
                }
@@ -11127,7 +11171,7 @@ static inline int lfs_mirror_write(int argc, char **argv)
                default:
                        fprintf(stderr, "%s: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
-                       /* fallthrough */
+                       fallthrough;
                case 'h':
                        return CMD_HELP;
                }
@@ -11377,7 +11421,7 @@ static inline int lfs_mirror_copy(int argc, char **argv)
                default:
                        fprintf(stderr, "%s: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
-                       /* fallthrough */
+                       fallthrough;
                case 'h':
                        return CMD_HELP;
                }
@@ -11603,13 +11647,13 @@ void print_chunks(const char *fname, struct verify_chunk *chunks,
  * Return: void.
  */
 static inline
-void print_checksums(struct verify_chunk *chunk, unsigned long *crc)
+void print_checksums(struct verify_chunk *chunk, unsigned long *crc,
+                    unsigned long long pos, unsigned long long len)
 {
        int i;
 
        fprintf(stdout,
-               "CRC-32 checksum value for chunk "DEXT":\n",
-               PEXT(&chunk->chunk));
+               "CRC-32 checksum value for chunk "DEXT":\n", pos, pos + len);
        for (i = 0; i < chunk->mirror_count; i++)
                fprintf(stdout, "Mirror %u:\t%#lx\n",
                        chunk->mirror_id[i], crc[i]);
@@ -11761,8 +11805,6 @@ int lfs_mirror_prepare_chunk(struct llapi_layout *layout,
                                goto error;
                        }
 
-                       chunks[idx].mirror_id[i] = mirror_id;
-                       i++;
                        if (i >= ARRAY_SIZE(chunks[idx].mirror_id)) {
                                fprintf(stderr,
                                        "%s: mirror_id array is too small.\n",
@@ -11770,6 +11812,8 @@ int lfs_mirror_prepare_chunk(struct llapi_layout *layout,
                                rc = -EINVAL;
                                goto error;
                        }
+                       chunks[idx].mirror_id[i] = mirror_id;
+                       i++;
 
 next:
                        rc = llapi_layout_comp_use(layout,
@@ -11875,7 +11919,7 @@ int lfs_mirror_verify_chunk(int fd, size_t file_size,
                }
 
                if (verbose)
-                       print_checksums(chunk, crc_array);
+                       print_checksums(chunk, crc_array, pos, buflen);
 
                /* compare CRC-32 checksum values */
                for (i = 1; i < chunk->mirror_count; i++) {
@@ -11963,7 +12007,8 @@ int lfs_mirror_verify_file(const char *fname, __u16 *mirror_ids, int ids_nr,
                goto error;
        }
 
-       fd = open(fname, O_DIRECT | O_RDONLY);
+       /* Allow mirror verify even without the key on encrypted files */
+       fd = open(fname, O_DIRECT | O_RDONLY | O_FILE_ENC);
        if (fd < 0) {
                fprintf(stderr, "%s: cannot open '%s': %s.\n",
                        progname, fname, strerror(errno));
@@ -12142,7 +12187,7 @@ static inline int lfs_mirror_verify(int argc, char **argv)
                default:
                        fprintf(stderr, "%s: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
-                       /* fallthrough */
+                       fallthrough;
                case 'h':
                        rc = CMD_HELP;
                        goto error;
@@ -12249,7 +12294,7 @@ static int lfs_getsom(int argc, char **argv)
                default:
                        fprintf(stderr, "%s: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
-                       /* fallthrough */
+                       fallthrough;
                case 'h':
                        return CMD_HELP;
                }
@@ -12352,7 +12397,7 @@ static int lfs_pcc_attach(int argc, char **argv)
                default:
                        fprintf(stderr, "%s: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
-                       /* fallthrough */
+                       fallthrough;
                case 'h':
                        return CMD_HELP;
                }
@@ -12429,7 +12474,7 @@ static int lfs_pcc_attach_fid(int argc, char **argv)
                default:
                        fprintf(stderr, "%s: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
-                       /* fallthrough */
+                       fallthrough;
                case 'h':
                        return CMD_HELP;
                }
@@ -12492,7 +12537,7 @@ static int lfs_pcc_detach(int argc, char **argv)
                default:
                        fprintf(stderr, "%s: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
-                       /* fallthrough */
+                       fallthrough;
                case 'h':
                        return CMD_HELP;
                }
@@ -12545,7 +12590,7 @@ static int lfs_pcc_detach_fid(int argc, char **argv)
                default:
                        fprintf(stderr, "%s: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
-                       /* fallthrough */
+                       fallthrough;
                case 'h':
                        return CMD_HELP;
                }