From 85f386d63e0a942e9a59d48179949f89470d9158 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Mon, 26 May 2025 22:02:22 -0600 Subject: [PATCH] LU-19062 llapi: add layout pattern string functions 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 Change-Id: Ie21c7c75c685f3a15ac23e83562a12a3ea2540e5 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/59530 Tested-by: jenkins Tested-by: Maloo Reviewed-by: James Simmons Reviewed-by: Zhenyu Xu Reviewed-by: Oleg Drokin --- Documentation/man1/lfs-getstripe.1 | 20 +++++- Documentation/man1/lfs-setstripe.1 | 2 +- Documentation/man3/Makefile.am | 2 + Documentation/man3/llapi_lov_pattern_string.3 | 31 ++++++++++ Documentation/man3/llapi_lov_string_pattern.3 | 35 +++++++++++ lustre/include/lustre/lustreapi.h | 23 ++++--- lustre/include/uapi/linux/lustre/lustre_idl.h | 34 +++++------ lustre/include/uapi/linux/lustre/lustre_user.h | 40 ++++++------ lustre/tests/sanity-hsm.sh | 2 +- lustre/tests/sanity.sh | 12 ++-- lustre/utils/lfs.c | 27 +-------- lustre/utils/liblustreapi.c | 35 ++++------- lustre/utils/liblustreapi_hsm.c | 4 +- lustre/utils/liblustreapi_layout.c | 84 +++++++++++++++++++++++++- 14 files changed, 240 insertions(+), 111 deletions(-) create mode 100644 Documentation/man3/llapi_lov_pattern_string.3 create mode 100644 Documentation/man3/llapi_lov_string_pattern.3 diff --git a/Documentation/man1/lfs-getstripe.1 b/Documentation/man1/lfs-getstripe.1 index 0fb2559..8a5770a 100644 --- a/Documentation/man1/lfs-getstripe.1 +++ b/Documentation/man1/lfs-getstripe.1 @@ -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 diff --git a/Documentation/man1/lfs-setstripe.1 b/Documentation/man1/lfs-setstripe.1 index 08c1bc5..37d7fc9 100644 --- a/Documentation/man1/lfs-setstripe.1 +++ b/Documentation/man1/lfs-setstripe.1 @@ -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 diff --git a/Documentation/man3/Makefile.am b/Documentation/man3/Makefile.am index ebf7cc3..eaeaa27 100644 --- a/Documentation/man3/Makefile.am +++ b/Documentation/man3/Makefile.am @@ -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 index 0000000..07ce0f9 --- /dev/null +++ b/Documentation/man3/llapi_lov_pattern_string.3 @@ -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 +.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 index 0000000..8ecd295 --- /dev/null +++ b/Documentation/man3/llapi_lov_string_pattern.3 @@ -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 +.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) diff --git a/lustre/include/lustre/lustreapi.h b/lustre/include/lustre/lustreapi.h index 9e876f0..6d7d5ba 100644 --- a/lustre/include/lustre/lustreapi.h +++ b/lustre/include/lustre/lustreapi.h @@ -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 diff --git a/lustre/include/uapi/linux/lustre/lustre_idl.h b/lustre/include/uapi/linux/lustre/lustre_idl.h index 382aeab..3ef0a83 100644 --- a/lustre/include/uapi/linux/lustre/lustre_idl.h +++ b/lustre/include/uapi/linux/lustre/lustre_idl.h @@ -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 */ diff --git a/lustre/include/uapi/linux/lustre/lustre_user.h b/lustre/include/uapi/linux/lustre/lustre_user.h index 8215779..17409f2 100644 --- a/lustre/include/uapi/linux/lustre/lustre_user.h +++ b/lustre/include/uapi/linux/lustre/lustre_user.h @@ -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); diff --git a/lustre/tests/sanity-hsm.sh b/lustre/tests/sanity-hsm.sh index d41e213..2ec3842 100755 --- a/lustre/tests/sanity-hsm.sh +++ b/lustre/tests/sanity-hsm.sh @@ -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" diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 40cd85c..60fbb47 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -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 || diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index d97df53..b844c15 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -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(¶m.fp_layout, optarg); + ret = llapi_lov_string_pattern(optarg, ¶m.fp_layout); if (ret) goto err; param.fp_exclude_layout = !!neg_opt; diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index e24f1f6..2685944 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -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"; diff --git a/lustre/utils/liblustreapi_hsm.c b/lustre/utils/liblustreapi_hsm.c index 3bfbed4..aa9699a 100644 --- a/lustre/utils/liblustreapi_hsm.c +++ b/lustre/utils/liblustreapi_hsm.c @@ -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; diff --git a/lustre/utils/liblustreapi_layout.c b/lustre/utils/liblustreapi_layout.c index 5871354..193cdd9 100644 --- a/lustre/utils/liblustreapi_layout.c +++ b/lustre/utils/liblustreapi_layout.c @@ -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. -- 1.8.3.1