Whamcloud - gitweb
LU-19062 llapi: add layout pattern string functions
authorAndreas Dilger <adilger@whamcloud.com>
Tue, 27 May 2025 04:02:22 +0000 (22:02 -0600)
committerOleg Drokin <green@linuxhacker.ru>
Fri, 13 Jun 2025 01:36:16 +0000 (21:36 -0400)
Add llapi_lov_pattern_string() to print arbitrary pattern flags to
a string rather than layout2name() which only can print specific
hard-coded combinations of patterns.

Add llapi_lov_string_pattern() to convert layout pattern names to
flags.

Add enum lov_pattern that holds LOV_PATTERN constants, and use it.

Add description of patterns to lfs-getstripe.1.
Restore "-L, --layout" argument listing to lfs-setstripe.1.

Fixes: b6deb420a8 ("LU-17370 utils: simplify lfs help text")
Signed-off-by: Andreas Dilger <adilger@whamcloud.com>
Change-Id: Ie21c7c75c685f3a15ac23e83562a12a3ea2540e5

14 files changed:
Documentation/man1/lfs-getstripe.1
Documentation/man1/lfs-setstripe.1
Documentation/man3/Makefile.am
Documentation/man3/llapi_lov_pattern_string.3 [new file with mode: 0644]
Documentation/man3/llapi_lov_string_pattern.3 [new file with mode: 0644]
lustre/include/lustre/lustreapi.h
lustre/include/uapi/linux/lustre/lustre_idl.h
lustre/include/uapi/linux/lustre/lustre_user.h
lustre/tests/sanity-hsm.sh
lustre/tests/sanity.sh
lustre/utils/lfs.c
lustre/utils/liblustreapi.c
lustre/utils/liblustreapi_hsm.c
lustre/utils/liblustreapi_layout.c

index 0fb2559..8a5770a 100644 (file)
@@ -197,14 +197,28 @@ Print OST and MDT indexes in hexadecimal rather than decimal.
 Show only the file layout, which is one of:
 .RS 1.2i
 .TP
+.B bad
+Files that have an invalid layout and are inaccessible.
+.TP
+.B foreign
+Files that have a foreign (non-Lustre/free format) component.
+Such files may be inaccessible without external software integration.
+.TP
+.B hole
+Files that are missing a data object,
+possibly due to OST failure and layout reconstruction by LFSCK.
+.TP
+.B mdt
+Files that store the first data component on the MDT holding the inode.
+.TP
+.B overstriped
+Files have more than one stripe per OST for improved lock scalability.
+.TP
 .B raid0
 Traditional Lustre RAID-0 striping format.
 .TP
 .B released
 HSM-archived files that are not resident in the filesystem.
-.TP
-.B mdt
-Files that have the first data component on an MDT.
 .RE
 .TP
 .BR -m ", " --mdt ", " --mdt-index
index 08c1bc5..37d7fc9 100644 (file)
@@ -187,7 +187,7 @@ of
 allows the MDS to choose the starting index and it is strongly recommended, as
 this allows space and load balancing to be done by the MDS as needed.
 .TP
-
+.BR -L ", " --layout " \fILAYOUT_TYPE"
 The type of layout for that component, which can be one of:
 .RS
 .B raid0\fR - stripe the file data across
index ebf7cc3..eaeaa27 100644 (file)
@@ -79,6 +79,8 @@ LIBMAN =                                      \
        llapi_layout_stripe_count_set.3         \
        llapi_layout_stripe_size_get.3          \
        llapi_layout_stripe_size_set.3          \
+       llapi_lov_pattern_string.3              \
+       llapi_lov_string_pattern.3              \
        llapi_open_by_fid.3                     \
        llapi_open_by_fid_at.3                  \
        llapi_param_get_paths.3                 \
diff --git a/Documentation/man3/llapi_lov_pattern_string.3 b/Documentation/man3/llapi_lov_pattern_string.3
new file mode 100644 (file)
index 0000000..07ce0f9
--- /dev/null
@@ -0,0 +1,31 @@
+.TH LLAPI_LOV_STRING_PATTERN 3 2025-06-04 "Lustre User API" "Lustre Library Functions"
+.SH NAME
+llapi_lov_string_pattern \- convert pattern name string to LOV_PATTERN mask
+.SH SYNOPSIS
+.nf
+.B #include <lustre/lustreapi.h>
+.PP
+.BI "int llapi_lov_string_pattern(const char *" string ", enum lov_pattern *" pattern );
+.fi
+.SH DESCRIPTION
+.B llapi_lov_string_pattern()
+converts the comma-separated list of LOV pattern names in
+.I string
+to a mask of
+.B LOV_PATTERN_*
+flags returned in
+.IR pattern .
+.SH RETURN VALUES
+.BR llapi_lov_string_pattern( )
+returns 0 on success, or
+.B -EINVAL
+on failure (in which case, errno is set appropriately).
+.SH AVAILABILITY
+.BR llapi_lov_string_pattern ()
+is part of the
+.BR lustre (7)
+user application interface library since release 2.17.0
+.SH SEE ALSO
+.BR llapi_lov_pattern_string (3),
+.BR lustre (7),
+.BR lustreapi (7)
diff --git a/Documentation/man3/llapi_lov_string_pattern.3 b/Documentation/man3/llapi_lov_string_pattern.3
new file mode 100644 (file)
index 0000000..3194611
--- /dev/null
@@ -0,0 +1,35 @@
+.TH LLAPI_LOV_PATTERN_STRING 3 2025-06-04 "Lustre User API" "Lustre Library Functions"
+.SH NAME
+llapi_lov_pattern_string \- convert LOV_PATTERN mask to string
+.SH SYNOPSIS
+.nf
+.B #include <lustre/lustreapi.h>
+.PP
+.BI "int llapi_lov_pattern_string(enum lov_pattern " pattern ", char *" buf \
+                                ", size_t " buflen ");"
+.fi
+.SH DESCRIPTION
+.B llapi_lov_pattern_string()
+converts the
+.I pattern
+mask to a comma-separated string of pattern names
+in the
+.I buf
+buffer, up to
+.I buflen
+bytes in length.
+.SH RETURN VALUES
+.B llapi_lov_pattern_string()
+returns a pointer to the 
+.B buf
+string on success, or NULL on failure
+(currently only in case of buffer overflow).
+.SH AVAILABILITY
+.BR llapi_lov_pattern_string ()
+is part of the
+.BR lustre (7)
+user application interface library since release 2.17.0
+.SH SEE ALSO
+.BR llapi_lov_string_pattern (3),
+.BR lustre (7),
+.BR lustreapi (7)
index 9e876f0..6d7d5ba 100644 (file)
@@ -128,7 +128,7 @@ struct llapi_stripe_param {
        unsigned long long      lsp_stripe_size;
        char                    *lsp_pool;
        int                     lsp_stripe_offset;
-       int                     lsp_stripe_pattern;
+       enum lov_pattern        lsp_stripe_pattern;
        /* Number of stripes. Size of lsp_osts[] if lsp_specific is true.*/
        int                     lsp_stripe_count;
        bool                    lsp_is_specific;
@@ -147,7 +147,7 @@ enum {
        LLAPI_MIGRATION_VERBOSE         = 0x0008,
 };
 
-__u32 llapi_pattern_to_lov(uint64_t pattern);
+enum lov_pattern llapi_pattern_to_lov(uint64_t pattern);
 
 int llapi_file_open_param(const char *name, int flags, mode_t mode,
                          const struct llapi_stripe_param *param);
@@ -155,16 +155,18 @@ int llapi_file_is_encrypted(int fd);
 int llapi_file_create_foreign(const char *name, mode_t mode, __u32 type,
                              __u32 flags, char *foreign_lov);
 int llapi_file_create(const char *name, unsigned long long stripe_size,
-                     int stripe_offset, int stripe_count, int stripe_pattern);
+                     int stripe_offset, int stripe_count,
+                     enum lov_pattern stripe_pattern);
 int llapi_file_open(const char *name, int flags, int mode,
                    unsigned long long stripe_size, int stripe_offset,
-                   int stripe_count, int stripe_pattern);
+                   int stripe_count, enum lov_pattern stripe_pattern);
 int llapi_file_create_pool(const char *name, unsigned long long stripe_size,
                           int stripe_offset, int stripe_count,
-                          int stripe_pattern, char *pool_name);
+                          enum lov_pattern stripe_pattern, char *pool_name);
 int llapi_file_open_pool(const char *name, int flags, int mode,
                         unsigned long long stripe_size, int stripe_offset,
-                        int stripe_count, int stripe_pattern, char *pool_name);
+                        int stripe_count, enum lov_pattern stripe_pattern,
+                        char *pool_name);
 int llapi_poollist(const char *name);
 int llapi_get_poolbuf(const char *name, char **buf,
                      char ***poolist, int *poolcount);
@@ -492,7 +494,7 @@ int llapi_dir_create(const char *name, mode_t mode,
 int llapi_dir_create_foreign(const char *name, mode_t mode, __u32 type,
                             __u32 flags, const char *value);
 int llapi_dir_create_pool(const char *name, int flags, int stripe_offset,
-                         int stripe_count, int stripe_pattern,
+                         int stripe_count, enum lov_pattern stripe_pattern,
                          const char *poolname);
 int llapi_direntry_remove(char *dname);
 int llapi_unlink_foreign(char *dname);
@@ -713,8 +715,8 @@ int llapi_hsm_action_get_dfid(const struct hsm_copyaction_private *hcp,
 int llapi_hsm_action_get_fd(const struct hsm_copyaction_private *hcp);
 int llapi_hsm_import(const char *dst, int archive, const struct stat *st,
                     unsigned long long stripe_size, int stripe_offset,
-                    int stripe_count, int stripe_pattern, char *pool_name,
-                    struct lu_fid *newfid);
+                    int stripe_count, enum lov_pattern stripe_pattern,
+                    char *pool_name, struct lu_fid *newfid);
 
 /* HSM user interface */
 struct hsm_user_request *llapi_hsm_user_request_alloc(int itemcount,
@@ -1209,6 +1211,9 @@ int llapi_layout_flags_set(struct llapi_layout *layout, uint32_t flags);
 int llapi_layout_flags_get(struct llapi_layout *layout, uint32_t *flags);
 const char *llapi_layout_flags_string(uint32_t flags);
 __u16 llapi_layout_string_flags(char *string);
+char *llapi_lov_pattern_string(enum lov_pattern pattern, char *buf,
+                              size_t buflen);
+int llapi_lov_string_pattern(const char *string, enum lov_pattern *pattern);
 
 /**
  * llapi_layout_mirror_count_get() - Get mirror count from the header of
index 382aeab..3ef0a83 100644 (file)
@@ -1241,14 +1241,13 @@ struct lov_ost_data_v1 {          /* per-stripe data structure (little-endian)*/
 
 #define lov_mds_md lov_mds_md_v1
 struct lov_mds_md_v1 {            /* LOV EA mds/wire data (little-endian) */
-       __u32 lmm_magic;          /* magic number = LOV_MAGIC_V1 */
-       __u32 lmm_pattern;        /* LOV_PATTERN_RAID0, LOV_PATTERN_RAID1 */
-       struct ost_id   lmm_oi;   /* LOV object ID */
-       __u32 lmm_stripe_size;    /* size of stripe in bytes */
-       /* lmm_stripe_count used to be __u32 */
-       __u16 lmm_stripe_count;   /* num stripes in use for this object */
-       __u16 lmm_layout_gen;     /* layout generation number */
-       struct lov_ost_data_v1 lmm_objects[]; /* per-stripe data */
+       __u32                   lmm_magic;        /* LOV_MAGIC_V1 */
+       enum lov_pattern        lmm_pattern;      /* LOV_PATTERN_RAID0, ... */
+       struct ost_id           lmm_oi;           /* LOV object ID */
+       __u32                   lmm_stripe_size;  /* size of stripe in bytes */
+       __u16                   lmm_stripe_count; /* OST stripes in layout */
+       __u16                   lmm_layout_gen;   /* layout generation number */
+       struct lov_ost_data_v1  lmm_objects[];    /* per-stripe data */
 };
 
 #define MAX_MD_SIZE_OLD (sizeof(struct lov_mds_md) +                   \
@@ -1299,15 +1298,14 @@ struct lov_mds_md_v1 {            /* LOV EA mds/wire data (little-endian) */
 #define XATTR_JOB_MAX_LEN      13
 
 struct lov_mds_md_v3 {            /* LOV EA mds/wire data (little-endian) */
-       __u32 lmm_magic;          /* magic number = LOV_MAGIC_V3 */
-       __u32 lmm_pattern;        /* LOV_PATTERN_RAID0, LOV_PATTERN_RAID1 */
-       struct ost_id   lmm_oi;   /* LOV object ID */
-       __u32 lmm_stripe_size;    /* size of stripe in bytes */
-       /* lmm_stripe_count used to be __u32 */
-       __u16 lmm_stripe_count;   /* num stripes in use for this object */
-       __u16 lmm_layout_gen;     /* layout generation number */
-       char  lmm_pool_name[LOV_MAXPOOLNAME + 1]; /* must be 32bit aligned */
-       struct lov_ost_data_v1 lmm_objects[]; /* per-stripe data */
+       __u32                   lmm_magic;        /* LOV_MAGIC_V3 */
+       enum lov_pattern        lmm_pattern;      /* LOV_PATTERN_RAID0, ... */
+       struct ost_id           lmm_oi;           /* LOV object ID */
+       __u32                   lmm_stripe_size;  /* size of stripe in bytes */
+       __u16                   lmm_stripe_count; /* OST stripes in layout */
+       __u16                   lmm_layout_gen;   /* layout generation number */
+       char                    lmm_pool_name[LOV_MAXPOOLNAME + 1];
+       struct lov_ost_data_v1  lmm_objects[];    /* per-stripe data */
 };
 
 static inline __u32 lov_mds_md_size(__u16 stripes, __u32 lmm_magic)
@@ -2518,7 +2516,7 @@ struct lov_desc {
        __u32 ld_tgt_count;             /* how many OBD's */
        __u32 ld_active_tgt_count;      /* how many active */
        __s32 ld_default_stripe_count;  /* how many objects are used */
-       __u32 ld_pattern;               /* default PATTERN_RAID0 */
+       enum lov_pattern ld_pattern;    /* default LOV_PATTERN_RAID0 */
        __u64 ld_default_stripe_size;   /* in bytes */
        __s64 ld_default_stripe_offset; /* starting OST index */
        __u32 ld_padding_0;             /* unused */
index 8215779..17409f2 100644 (file)
@@ -785,29 +785,31 @@ enum ll_file_flags {
 #define LMV_USER_MAGIC_V0      0x0CD20CD0    /* old default lmv magic*/
 #define LMV_USER_MAGIC_SPECIFIC        0x0CD40CD0
 
-#define LOV_PATTERN_NONE               0x000
-#define LOV_PATTERN_RAID0              0x001
-#define LOV_PATTERN_RAID1              0x002
-#define LOV_PATTERN_MDT                        0x100
-#define LOV_PATTERN_OVERSTRIPING       0x200
-#define LOV_PATTERN_FOREIGN            0x400
-#define LOV_PATTERN_COMPRESS           0x800
-
-/* combine exclusive patterns as a bad pattern */
-#define LOV_PATTERN_BAD                (LOV_PATTERN_RAID1 | LOV_PATTERN_MDT | \
-                                LOV_PATTERN_FOREIGN)
-
-#define LOV_PATTERN_F_MASK     0xffff0000
-#define LOV_PATTERN_F_HOLE     0x40000000 /* there is hole in LOV EA */
-#define LOV_PATTERN_F_RELEASED 0x80000000 /* HSM released file */
-#define LOV_PATTERN_DEFAULT    0xffffffff
+enum lov_pattern {
+       LOV_PATTERN_NONE =              0x000,
+       LOV_PATTERN_RAID0 =             0x001,
+       LOV_PATTERN_RAID1 =             0x002,
+       LOV_PATTERN_MDT =               0x100,
+       LOV_PATTERN_OVERSTRIPING =      0x200,
+       LOV_PATTERN_FOREIGN =           0x400,
+       LOV_PATTERN_COMPRESS =          0x800,
+
+       /* combine exclusive patterns as a bad pattern */
+       LOV_PATTERN_BAD =               (LOV_PATTERN_RAID1 | LOV_PATTERN_MDT |
+                                        LOV_PATTERN_FOREIGN),
+
+       LOV_PATTERN_F_MASK =            0xffff0000,
+       LOV_PATTERN_F_HOLE =            0x40000000, /* hole in LOV EA objects */
+       LOV_PATTERN_F_RELEASED =        0x80000000, /* HSM released file */
+       LOV_PATTERN_DEFAULT =           0xffffffff
+};
 
 #define LOV_OFFSET_DEFAULT      ((__u16)-1)
 #define LMV_OFFSET_DEFAULT      ((__u32)-1)
 
-static inline bool lov_pattern_supported(__u32 pattern)
+static inline bool lov_pattern_supported(enum lov_pattern pattern)
 {
-       __u32 pattern_base = pattern & ~LOV_PATTERN_F_RELEASED;
+       enum lov_pattern pattern_base = pattern & ~LOV_PATTERN_F_RELEASED;
 
        return pattern_base == LOV_PATTERN_RAID0 ||
               pattern_base == (LOV_PATTERN_RAID0 | LOV_PATTERN_OVERSTRIPING) ||
@@ -818,7 +820,7 @@ static inline bool lov_pattern_supported(__u32 pattern)
  * having many extra checks on lov_pattern_supported, we have this separate
  * check for non-released, non-readonly, non-DOM components
  */
-static inline bool lov_pattern_supported_normal_comp(__u32 pattern)
+static inline bool lov_pattern_supported_normal_comp(enum lov_pattern pattern)
 {
        return pattern == LOV_PATTERN_RAID0 ||
               pattern == (LOV_PATTERN_RAID0 | LOV_PATTERN_OVERSTRIPING);
index 1a7002a..23ebfc2 100755 (executable)
@@ -1014,7 +1014,7 @@ test_11a() {
        echo -n "Verifying released pattern: "
        local PTRN=$($LFS getstripe -L $f)
        echo $PTRN
-       [[ $PTRN == released ]] || error "Is not released"
+       [[ $PTRN =~ released ]] || error "Is not released"
        local fid=$(path2fid $f)
        echo "Verifying new fid $fid in archive"
 
index 40cd85c..60fbb47 100755 (executable)
@@ -24045,10 +24045,10 @@ test_228c() {
 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
 
 test_229() { # LU-2482, LU-3448
-       [ $PARALLEL == "yes" ] && skip "skip parallel run"
-       [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
-       [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
-               skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
+       [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
+       (( $OSTCOUNT >= 2 )) || skip_env "needs >= 2 OSTs"
+       (( $MDS1_VERSION >= $(version_code 2.4.50.0-53-ga61ff5914b) )) ||
+               skip "need MDS >= 2.4.50.53 for HSM released file"
 
        rm -f $DIR/$tfile
 
@@ -24059,11 +24059,11 @@ test_229() { # LU-2482, LU-3448
        $LFS getstripe -v $DIR/$tfile
 
        local pattern=$($LFS getstripe -L $DIR/$tfile)
-       [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
+       [[ "$pattern" =~ "released" ]] || error "pattern error ($pattern)"
 
        local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
                error "getstripe"
-       [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
+       (( $stripe_count == 2 )) || error "stripe count not 2 ($stripe_count)"
        stat $DIR/$tfile || error "failed to stat released file"
 
        chown $RUNAS_ID $DIR/$tfile ||
index d97df53..b844c15 100644 (file)
@@ -5171,31 +5171,6 @@ static inline int gid2name(char **name, unsigned int id)
        return 0;
 }
 
-static int name2layout(__u32 *layout, char *name)
-{
-       char *ptr, *layout_name;
-
-       *layout = 0;
-       for (ptr = name; ; ptr = NULL) {
-               layout_name = strtok(ptr, ",");
-               if (!layout_name)
-                       break;
-               if (strcmp(layout_name, "released") == 0)
-                       *layout |= LOV_PATTERN_F_RELEASED;
-               else if (strcmp(layout_name, "raid0") == 0)
-                       *layout |= LOV_PATTERN_RAID0;
-               else if (strcmp(layout_name, "mdt") == 0)
-                       *layout |= LOV_PATTERN_MDT;
-               else if (strcmp(layout_name, "overstriping") == 0)
-                       *layout |= LOV_PATTERN_OVERSTRIPING;
-               else if (strcmp(layout_name, "foreign") == 0)
-                       *layout |= LOV_PATTERN_FOREIGN;
-               else
-                       return -1;
-       }
-       return 0;
-}
-
 static int name2attrs(char *name, __u64 *attrs, __u64 *neg_attrs)
 {
        char *ptr, *attr_name = name;
@@ -6317,7 +6292,7 @@ static int lfs_find(int argc, char **argv)
                        param.fp_lazy = 1;
                        break;
                case 'L':
-                       ret = name2layout(&param.fp_layout, optarg);
+                       ret = llapi_lov_string_pattern(optarg, &param.fp_layout);
                        if (ret)
                                goto err;
                        param.fp_exclude_layout = !!neg_opt;
index e24f1f6..2685944 100644 (file)
@@ -667,7 +667,8 @@ int llapi_file_is_encrypted(int fd)
 
 int llapi_file_open_pool(const char *name, int flags, int mode,
                         unsigned long long stripe_size, int stripe_offset,
-                        int stripe_count, int stripe_pattern, char *pool_name)
+                        int stripe_count, enum lov_pattern stripe_pattern,
+                        char *pool_name)
 {
        const struct llapi_stripe_param param = {
                .lsp_stripe_size = stripe_size,
@@ -681,7 +682,7 @@ int llapi_file_open_pool(const char *name, int flags, int mode,
 
 int llapi_file_open(const char *name, int flags, int mode,
                    unsigned long long stripe_size, int stripe_offset,
-                   int stripe_count, int stripe_pattern)
+                   int stripe_count, enum lov_pattern stripe_pattern)
 {
        return llapi_file_open_pool(name, flags, mode, stripe_size,
                                    stripe_offset, stripe_count,
@@ -790,7 +791,8 @@ out_err:
 }
 
 int llapi_file_create(const char *name, unsigned long long stripe_size,
-                     int stripe_offset, int stripe_count, int stripe_pattern)
+                     int stripe_offset, int stripe_count,
+                     enum lov_pattern stripe_pattern)
 {
        int fd;
 
@@ -806,7 +808,7 @@ int llapi_file_create(const char *name, unsigned long long stripe_size,
 
 int llapi_file_create_pool(const char *name, unsigned long long stripe_size,
                           int stripe_offset, int stripe_count,
-                          int stripe_pattern, char *pool_name)
+                          enum lov_pattern stripe_pattern, char *pool_name)
 {
        int fd;
 
@@ -1184,7 +1186,7 @@ out:
 }
 
 int llapi_dir_create_pool(const char *name, int mode, int stripe_offset,
-                         int stripe_count, int stripe_pattern,
+                         int stripe_count, enum lov_pattern stripe_pattern,
                          const char *pool_name)
 {
        const struct llapi_stripe_param param = {
@@ -2733,23 +2735,6 @@ int sattr_cache_get_defaults(const char *const fsname,
        return 0;
 }
 
-static char *layout2name(__u32 layout_pattern)
-{
-       if (layout_pattern & LOV_PATTERN_F_RELEASED)
-               return "released";
-       else if (layout_pattern & LOV_PATTERN_FOREIGN)
-               return "foreign";
-       else if (layout_pattern == LOV_PATTERN_MDT)
-               return "mdt";
-       else if (layout_pattern == LOV_PATTERN_RAID0)
-               return "raid0";
-       else if (layout_pattern ==
-                       (LOV_PATTERN_RAID0 | LOV_PATTERN_OVERSTRIPING))
-               return "raid0,overstriped";
-       else
-               return "unknown";
-}
-
 enum lov_dump_flags {
        LDF_IS_DIR      = 0x0001,
        LDF_IS_RAW      = 0x0002,
@@ -2927,13 +2912,17 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
        }
 
        if ((verbose & VERBOSE_PATTERN)) {
+               char buf[128];
+
                llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
                if (verbose & ~VERBOSE_PATTERN)
                        llapi_printf(LLAPI_MSG_NORMAL, "%s%spattern:       ",
                                     space, prefix);
                if (lov_pattern_supported(lum->lmm_pattern))
                        llapi_printf(LLAPI_MSG_NORMAL, "%s",
-                                    layout2name(lum->lmm_pattern));
+                                    llapi_lov_pattern_string(lum->lmm_pattern,
+                                                       buf, sizeof(buf)) ?:
+                                                       "overflow");
                else
                        llapi_printf(LLAPI_MSG_NORMAL, "%x", lum->lmm_pattern);
                separator = (!yaml && is_dir) ? " " : "\n";
index 3bfbed4..aa9699a 100644 (file)
@@ -1421,8 +1421,8 @@ int llapi_hsm_action_get_fd(const struct hsm_copyaction_private *hcp)
  */
 int llapi_hsm_import(const char *dst, int archive, const struct stat *st,
                     unsigned long long stripe_size, int stripe_offset,
-                    int stripe_count, int stripe_pattern, char *pool_name,
-                    struct lu_fid *newfid)
+                    int stripe_count, enum lov_pattern stripe_pattern,
+                    char *pool_name, struct lu_fid *newfid)
 {
        struct hsm_user_import   hui;
        int                      fd;
index 5871354..193cdd9 100644 (file)
@@ -727,11 +727,11 @@ out_layout:
        goto out;
 }
 
-__u32 llapi_pattern_to_lov(uint64_t pattern)
+enum lov_pattern llapi_pattern_to_lov(uint64_t llapi_pattern)
 {
-       __u32 lov_pattern;
+       enum lov_pattern lov_pattern;
 
-       switch (pattern) {
+       switch (llapi_pattern) {
        case LLAPI_LAYOUT_DEFAULT:
                lov_pattern = LOV_PATTERN_RAID0;
                break;
@@ -1928,6 +1928,84 @@ __u16 llapi_layout_string_flags(char *string)
        return 0;
 }
 
+static struct {
+       enum lov_pattern         llpn_pattern;
+       const char              *llpn_pattern_name;
+} lov_pattern_names[] = {
+       { LOV_PATTERN_RAID0,            "raid0" },
+       { LOV_PATTERN_RAID1,            "raid1" },
+       { LOV_PATTERN_MDT,              "mdt" },
+       { LOV_PATTERN_OVERSTRIPING,     "overstriped" },  /* getstripe */
+       { LOV_PATTERN_OVERSTRIPING,     "overstriping" }, /* setstripe compat */
+       { LOV_PATTERN_BAD,              "bad" },
+       { LOV_PATTERN_FOREIGN,          "foreign" },
+       { LOV_PATTERN_COMPRESS,         "compress" },
+       { LOV_PATTERN_F_HOLE,           "hole" },
+       { LOV_PATTERN_F_RELEASED,       "released" },
+       { LOV_PATTERN_DEFAULT,          "default" },
+       { 0, NULL }
+};
+
+int llapi_lov_string_pattern(const char *string, enum lov_pattern *pattern)
+{
+       const char *p;
+
+       *pattern = 0;
+       for (p = string; p != NULL; p = strchr(p, ',')) {
+               int i;
+
+               while (*p == ',')
+                       p++;
+               if (*p == '\0')
+                       break;
+               for (i = 0; lov_pattern_names[i].llpn_pattern != 0; i++) {
+                       int l;
+
+                       l = strlen(lov_pattern_names[i].llpn_pattern_name);
+                       if (strncmp(p, lov_pattern_names[i].llpn_pattern_name,
+                                   l))
+                               continue;
+                       *pattern |= lov_pattern_names[i].llpn_pattern;
+                       break;
+               }
+               if (lov_pattern_names[i].llpn_pattern == 0) {
+                       errno = EINVAL;
+                       return -errno;
+               }
+       }
+
+       return 0;
+}
+
+char *llapi_lov_pattern_string(enum lov_pattern pattern, char *buf,
+                              size_t buflen)
+{
+       char *p = buf;
+       int l = 0;
+       int i;
+
+       p[0] = '\0';
+       for (i = 0; lov_pattern_names[i].llpn_pattern && pattern; i++) {
+               if ((lov_pattern_names[i].llpn_pattern & pattern) ==
+                   lov_pattern_names[i].llpn_pattern) {
+                       l += snprintf(p, buflen - l, "%s%s", buf[0] ? "," : "",
+                                     lov_pattern_names[i].llpn_pattern_name);
+                       pattern &= ~lov_pattern_names[i].llpn_pattern;
+                       if (l >= buflen) {
+                               errno = EOVERFLOW;
+                               return NULL;
+                       }
+                       p = buf + l;
+               }
+       }
+
+       if (pattern)
+               snprintf(buf, buflen, "%sunknown_%x", buf[0] ? "," : "",
+                       pattern);
+
+       return buf;
+}
+
 /**
  * llapi_layout_mirror_count_is_valid() - Check the validity of mirror count.
  * @count: Mirror count value to be checked.