From fed241911f61b1d76aa7d80bfd370c822a3926ef Mon Sep 17 00:00:00 2001 From: Patrick Farrell Date: Mon, 3 Jun 2019 19:22:09 +0300 Subject: [PATCH] LU-10070 lod: SEL: Add flag & setstripe support The self-extending layouts feature adds a new layout flag and also uses the stripe size field differently. This patch implements this basic functionality, to be used in subsequent patches. Cray-bug-id: LUS-2528 Signed-off-by: Patrick Farrell Change-Id: I4392b70266cbab5bc8fa42afc3c360b954d5918a Reviewed-on: https://review.whamcloud.com/33782 Tested-by: jenkins Reviewed-by: Alexey Lyashkov Tested-by: Maloo Reviewed-by: Patrick Farrell Reviewed-by: Oleg Drokin --- lustre/doc/lfs-setstripe.1 | 57 +++++++++++++- lustre/doc/llapi_layout_extension_size_get.3 | 57 ++++++++++++++ lustre/doc/llapi_layout_extension_size_set.3 | 1 + lustre/doc/llapi_layout_stripe_size_get.3 | 2 + lustre/include/lustre/lustreapi.h | 22 ++++++ lustre/include/uapi/linux/lustre/lustre_user.h | 42 +++++++---- lustre/lod/lod_qos.c | 2 +- lustre/utils/lfs.c | 100 ++++++++++++++++++------- lustre/utils/liblustreapi.c | 27 +++++-- lustre/utils/liblustreapi_layout.c | 68 +++++++++++++++-- 10 files changed, 318 insertions(+), 60 deletions(-) create mode 100644 lustre/doc/llapi_layout_extension_size_get.3 create mode 100644 lustre/doc/llapi_layout_extension_size_set.3 diff --git a/lustre/doc/lfs-setstripe.1 b/lustre/doc/lfs-setstripe.1 index ddd474d..0ff3660 100644 --- a/lustre/doc/lfs-setstripe.1 +++ b/lustre/doc/lfs-setstripe.1 @@ -62,9 +62,9 @@ or replace the default file layout on an existing .br Create a new composite .I file -with one or more component layouts, or set or replace the default file layout -on an existing -.IR directory . +with one or more component layouts (where \fIend\fR marks the end of the +current component), or set or replace the default file layout on an existing +.IR directory. .TP .B lfs setstripe --component-add -E \fIend1\fR [\fISTRIPE_OPTIONS\fR] \ ... <\fIfile\fR> @@ -321,6 +321,28 @@ specified component, or use to add more components to the end of the file. .RE .TP +.B -z, --extension-size, ext-size\fR <\fIext_size\fR> +This option modifies the \fB-E\fR option, components which have this +option specified are created as pairs of components, extendable and +extension ones. +.PP +.RS +The extendable component starts at offset 0 if this is the first +component of the file. In this case it ends at offset \fIext_size\fR and +it gets the flag \fBinit\fR (initialized). The extendable component starts +at the end of the previous component if this is not the first component of +the file. In this case it ends at the same offset (0-length component). +.PP +The extension component covers the rest of the specified region up to +the \fIend\fR specified by \fB-E\fR option and gets the flag \fBextension\fR. +This component covers the space reserved for the extendable component but +not used immediately, the later extension of the extendable component is done +by \fIext_size\fR each time until the extension component is used up. This is +used to control the space on OSTs the stripe is located on, in case one of +them is low on space, the remaining extension component region is added to the +next component. +.RE +.TP .B --component-add Add components to the end an existing composite file. It is not possible to add components incrementally to the default directory layout, since the @@ -453,6 +475,35 @@ This creates a file with composite layout, the component has 1 stripe and covers [0, 4MiB), the second component has 4 stripes and covers [4MiB, 64MiB), the last component stripes over all available OSTs and covers [64MiB, EOF). .TP +.B lfs setstripe -E -1 -z 64M /mnt/lustre/file1 +This creates a file with a composite layout, the component one covers [0, 64MiB) +and the second component the rest [64MiB, EOF) originally. Once written beyond +64MiB the component one is extended to [0, 128MiB), once written beyond 128MiB +it is extended to [0, 192MiB), etc; the second component is shortened +appropriately. +.PP +.RS +When one of the OSTs of the first component layout is low on space, e.g. while +writing beyond 192MiB, the first component is left as [0, 192MiB), and a new +component is allocated between them, its layout repeats the first component +layout but initialized on different OSTs so that the full OSTs are avoided. +It is allocated and immediately extended to [192MiB, 256MiB), the following +extension component is shortended again. +.RE +.TP +.B lfs setstripe -E 1G -z 64M -E 100G -z 256M -E -1 -z 1G /mnt/lustre/file1 +This creates a file with a composite layout, the component one covers [0, +64MiB), the third component covers [1G, 1G), the fifth component covers +[100GiB, 100GiB) originally. The second, fourth and sixth extension components +cover the left space accordingly. The process of writing is similar to above, +but when one of the OSTs of the first component layout is low on space, e.g. +while writing beyond 192MiB in the example above, the first component is left +as [0, 192MiB), the second (extension) component is removed, and its range +spills over to the third and the fourth components - they are moved left to +start at 192MiB instead of 100GiB; the third component is immediately extended +and becomes [192MiB, 448MiB), the fourth (the extension one) component becomes +[448MiB, 100GiB). +.TP .B lfs setstripe --component-add -E eof -c 4 /mnt/lustre/file1 This add a component which starts at the end of last existing component to the end of file. diff --git a/lustre/doc/llapi_layout_extension_size_get.3 b/lustre/doc/llapi_layout_extension_size_get.3 new file mode 100644 index 0000000..57a0d31 --- /dev/null +++ b/lustre/doc/llapi_layout_extension_size_get.3 @@ -0,0 +1,57 @@ +.TH llapi_layout_extension_size_get 3 "2019 May 23" "Lustre User API" +.SH NAME +llapi_layout_extension_size_get, llapi_layout_extension_size_set \- get or set +the extension size of an extension component of a Lustre file +.SH SYNOPSIS +.nf +.B #include +.PP +.BI "int llapi_layout_extension_size_get(const struct llapi_layout *" layout ", +.BI " uint64_t *" ext_size ); +.PP +.BI "int llapi_layout_extension_size_set(struct llapi_layout *" layout ", +.BI " uint64_t " ext_size ); +.fi +.SH DESCRIPTION +.PP +The extension size is the unit of increasing the previous component size when +writing within the region of the current extension component. At the time of the +change the OSTs of the previous component layout are checked if they have +at least \fIext_size\fR free space. In case there is no enough free space, +the space covered by the extension component spills over to the next component +(see examples in \fBlfs-setstripe (1)\fR). +.PP +In case of a random write to a middle of the extension component, the extension +happens from the beginning of the extension component up to the current writing +position plus the \fIext_size\fR. However, the check for low space is still +done for the \fIext_size\fR. +.PP +.B llapi_layout_extension_size_get() +stores into +.I ext_size +the extension size of +.IR layout . +.PP +.B llapi_layout_extension_size_get() +sets the extension size of +.I layout +to +.IR ext_size . +.SH RETURN VALUES +.B llapi_layout_extension_size_get() +and +.B llapi_layout_extension_size_set() +return 0 on success, or -1 if an error occurred (in which case, errno is +set appropriately). +.SH ERRORS +.TP 15 +.SM EINVAL +An invalid argument was specified. +.SH "SEE ALSO" +.BR lfs-setstripe (1), +.BR llapi_layout_alloc (3), +.BR llapi_layout_file_open (3), +.BR llapi_layout_stripe_size_set (3), +.BR llapi_layout_stripe_size_get (3), +.BR llapi_layout (7), +.BR lustreapi (7) diff --git a/lustre/doc/llapi_layout_extension_size_set.3 b/lustre/doc/llapi_layout_extension_size_set.3 new file mode 100644 index 0000000..1711f41 --- /dev/null +++ b/lustre/doc/llapi_layout_extension_size_set.3 @@ -0,0 +1 @@ +.so man3/llapi_layout_extension_size_get.3 diff --git a/lustre/doc/llapi_layout_stripe_size_get.3 b/lustre/doc/llapi_layout_stripe_size_get.3 index 52f0c1e..abc1b4a 100644 --- a/lustre/doc/llapi_layout_stripe_size_get.3 +++ b/lustre/doc/llapi_layout_stripe_size_get.3 @@ -47,5 +47,7 @@ An invalid argument was specified. .SH "SEE ALSO" .BR llapi_layout_alloc (3), .BR llapi_layout_file_open (3), +.BR llapi_layout_extension_size_set (3), +.BR llapi_layout_extension_size_get (3), .BR llapi_layout (7), .BR lustreapi (7) diff --git a/lustre/include/lustre/lustreapi.h b/lustre/include/lustre/lustreapi.h index 72358b9..831143c 100644 --- a/lustre/include/lustre/lustreapi.h +++ b/lustre/include/lustre/lustreapi.h @@ -734,6 +734,27 @@ int llapi_layout_stripe_size_get(const struct llapi_layout *layout, */ int llapi_layout_stripe_size_set(struct llapi_layout *layout, uint64_t size); + +/******************** Extension Size ********************/ + +/** + * Store the extension size of \a layout in \a size. + * + * \retval 0 Success. + * \retval -1 Invalid argument, errno set to EINVAL. + */ +int llapi_layout_extension_size_get(const struct llapi_layout *layout, + uint64_t *size); + +/** + * Set the extension size of \a layout to \a stripe_size. + * + * \retval 0 Success. + * \retval -1 Invalid argument, errno set to EINVAL. + */ +int llapi_layout_extension_size_set(struct llapi_layout *layout, uint64_t size); + + /******************** Stripe Pattern ********************/ /** @@ -935,6 +956,7 @@ static const struct comp_flag_name { { LCME_FL_PREF_RW, "prefer" }, { LCME_FL_OFFLINE, "offline" }, { LCME_FL_NOSYNC, "nosync" }, + { LCME_FL_EXTENSION, "extension" }, }; /** diff --git a/lustre/include/uapi/linux/lustre/lustre_user.h b/lustre/include/uapi/linux/lustre/lustre_user.h index a9c7f64..86bfb05 100644 --- a/lustre/include/uapi/linux/lustre/lustre_user.h +++ b/lustre/include/uapi/linux/lustre/lustre_user.h @@ -661,6 +661,12 @@ struct lov_foreign_md { (le32_to_cpu(((struct lov_foreign_md *)lfm)->lfm_length) + \ offsetof(struct lov_foreign_md, lfm_value)) +/** + * The stripe size fields are shared for the extension size storage, however + * the extension size is stored in KB, not bytes. + */ +#define SEL_UNIT_SIZE 1024llu + struct lu_extent { __u64 e_start; __u64 e_end; @@ -681,29 +687,37 @@ static inline bool lu_extent_is_whole(struct lu_extent *e) } enum lov_comp_md_entry_flags { - LCME_FL_STALE = 0x00000001, /* FLR: stale data */ - LCME_FL_PREF_RD = 0x00000002, /* FLR: preferred for reading */ - LCME_FL_PREF_WR = 0x00000004, /* FLR: preferred for writing */ - LCME_FL_PREF_RW = LCME_FL_PREF_RD | LCME_FL_PREF_WR, - LCME_FL_OFFLINE = 0x00000008, /* Not used */ - LCME_FL_INIT = 0x00000010, /* instantiated */ - LCME_FL_NOSYNC = 0x00000020, /* FLR: no sync for the mirror */ - LCME_FL_NEG = 0x80000000 /* used to indicate a negative flag, - won't be stored on disk */ + LCME_FL_STALE = 0x00000001, /* FLR: stale data */ + LCME_FL_PREF_RD = 0x00000002, /* FLR: preferred for reading */ + LCME_FL_PREF_WR = 0x00000004, /* FLR: preferred for writing */ + LCME_FL_PREF_RW = LCME_FL_PREF_RD | LCME_FL_PREF_WR, + LCME_FL_OFFLINE = 0x00000008, /* Not used */ + LCME_FL_INIT = 0x00000010, /* instantiated */ + LCME_FL_NOSYNC = 0x00000020, /* FLR: no sync for the mirror */ + LCME_FL_EXTENSION = 0x00000040, /* extension comp, never init */ + LCME_FL_NEG = 0x80000000 /* used to indicate a negative flag, + * won't be stored on disk + */ }; #define LCME_KNOWN_FLAGS (LCME_FL_NEG | LCME_FL_INIT | LCME_FL_STALE | \ - LCME_FL_PREF_RW | LCME_FL_NOSYNC) -/* The flags can be set by users at mirror creation time. */ -#define LCME_USER_FLAGS (LCME_FL_PREF_RW) + LCME_FL_PREF_RW | LCME_FL_NOSYNC | \ + LCME_FL_EXTENSION) + +/* The mirror flags can be set by users at creation time. */ +#define LCME_USER_MIRROR_FLAGS (LCME_FL_PREF_RW) + +/* The allowed flags obtained from the client at component creation time. */ +#define LCME_CL_COMP_FLAGS (LCME_USER_MIRROR_FLAGS | LCME_FL_EXTENSION) -/* The flags are for mirrors */ +/* The mirror flags sent by client */ #define LCME_MIRROR_FLAGS (LCME_FL_NOSYNC) /* These flags have meaning when set in a default layout and will be inherited * from the default/template layout set on a directory. */ -#define LCME_TEMPLATE_FLAGS (LCME_FL_PREF_RW | LCME_FL_NOSYNC) +#define LCME_TEMPLATE_FLAGS (LCME_FL_PREF_RW | LCME_FL_NOSYNC | \ + LCME_FL_EXTENSION) /* the highest bit in obdo::o_layout_version is used to mark if the file is * being resynced. */ diff --git a/lustre/lod/lod_qos.c b/lustre/lod/lod_qos.c index fbc35cd..3b87fa9 100644 --- a/lustre/lod/lod_qos.c +++ b/lustre/lod/lod_qos.c @@ -2029,7 +2029,7 @@ int lod_qos_parse_config(const struct lu_env *env, struct lod_object *lo, lod_comp->llc_extent = *ext; lod_comp->llc_flags = comp_v1->lcm_entries[i].lcme_flags & - LCME_USER_FLAGS; + LCME_CL_COMP_FLAGS; } pool_name = NULL; diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 9ffb589..b0ff694 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -1111,7 +1111,6 @@ static int lfs_component_del(char *fname, __u32 comp_id, if ((flags && comp_id) || (!flags && !comp_id)) return -EINVAL; - /* LCME_FL_INIT is the only supported flag in PFL */ if (flags) { if (flags & ~LCME_KNOWN_FLAGS) { fprintf(stderr, @@ -2099,6 +2098,7 @@ static int parse_targets(__u32 *tgts, int size, int offset, char *arg, struct lfs_setstripe_args { unsigned long long lsa_comp_end; unsigned long long lsa_stripe_size; + unsigned long long lsa_extension_size; long long lsa_stripe_count; long long lsa_stripe_off; __u32 lsa_comp_flags; @@ -2107,6 +2107,7 @@ struct lfs_setstripe_args { unsigned int lsa_mirror_count; int lsa_nr_tgts; bool lsa_first_comp; + bool lsa_extension_comp; __u32 *lsa_tgts; char *lsa_pool_name; }; @@ -2180,8 +2181,10 @@ static int comp_args_to_layout(struct llapi_layout **composite, { struct llapi_layout *layout = *composite; uint64_t prev_end = 0; + uint64_t size; int i = 0, rc; +new_comp: if (layout == NULL) { layout = llapi_layout_alloc(); if (layout == NULL) { @@ -2190,6 +2193,7 @@ static int comp_args_to_layout(struct llapi_layout **composite, return -ENOMEM; } *composite = layout; + lsa->lsa_first_comp = true; } else { uint64_t start; @@ -2215,18 +2219,37 @@ static int comp_args_to_layout(struct llapi_layout **composite, return rc; } } - /* reset lsa_first_comp */ - lsa->lsa_first_comp = false; + + rc = llapi_layout_comp_flags_set(layout, lsa->lsa_comp_flags); + if (rc) { + fprintf(stderr, "Set flags 0x%x failed: %s\n", + lsa->lsa_comp_flags, strerror(errno)); + return rc; + } if (set_extent) { + uint64_t comp_end = lsa->lsa_comp_end; + + /* Extension space handling: + * If this is the first component, length is extension_size. + * If not, it is zero length, so it can be removed if there is + * insufficient space to extend it. + */ + if (lsa->lsa_extension_comp && lsa->lsa_first_comp) + comp_end = prev_end + lsa->lsa_extension_size; + else if (lsa->lsa_extension_comp) + comp_end = prev_end; + rc = llapi_layout_comp_extent_set(layout, prev_end, - lsa->lsa_comp_end); + comp_end); if (rc) { - fprintf(stderr, "Set extent [%lu, %llu) failed. %s\n", - prev_end, lsa->lsa_comp_end, strerror(errno)); + fprintf(stderr, "Set extent [%lu, %lu) failed. %s\n", + prev_end, comp_end, strerror(errno)); return rc; } } + /* reset lsa_first_comp */ + lsa->lsa_first_comp = false; /* Data-on-MDT component setting */ if (lsa->lsa_pattern == LLAPI_LAYOUT_MDT) { @@ -2280,10 +2303,17 @@ static int comp_args_to_layout(struct llapi_layout **composite, } } - rc = llapi_layout_stripe_size_set(layout, lsa->lsa_stripe_size); + size = lsa->lsa_comp_flags & LCME_FL_EXTENSION ? + lsa->lsa_extension_size : lsa->lsa_stripe_size; + + if (lsa->lsa_comp_flags & LCME_FL_EXTENSION) + rc = llapi_layout_extension_size_set(layout, size); + else + rc = llapi_layout_stripe_size_set(layout, size); + if (rc) { - fprintf(stderr, "Set stripe size %llu failed: %s\n", - lsa->lsa_stripe_size, strerror(errno)); + fprintf(stderr, "Set stripe size %lu failed: %s\n", + size, strerror(errno)); return rc; } @@ -2294,13 +2324,6 @@ static int comp_args_to_layout(struct llapi_layout **composite, return rc; } - rc = llapi_layout_comp_flags_set(layout, lsa->lsa_comp_flags); - if (rc) { - fprintf(stderr, "Set flags 0x%x failed: %s\n", - lsa->lsa_comp_flags, strerror(errno)); - return rc; - } - if (lsa->lsa_pool_name != NULL) { rc = llapi_layout_pool_name_set(layout, lsa->lsa_pool_name); if (rc) { @@ -2342,6 +2365,13 @@ static int comp_args_to_layout(struct llapi_layout **composite, return rc; } + /* Create the second, virtual component of extension space */ + if (lsa->lsa_extension_comp) { + lsa->lsa_comp_flags |= LCME_FL_EXTENSION; + lsa->lsa_extension_comp = false; + goto new_comp; + } + return 0; } @@ -2806,6 +2836,8 @@ static int lfs_setstripe_internal(int argc, char **argv, { .val = 'v', .name = "verbose", .has_arg = no_argument}, { .val = 'x', .name = "xattr", .has_arg = required_argument }, { .val = 'y', .name = "yaml", .has_arg = required_argument }, + { .val = 'z', .name = "ext-size", .has_arg = required_argument}, + { .val = 'z', .name = "extension-size", .has_arg = required_argument}, { .name = NULL } }; setstripe_args_init(&lsa); @@ -2817,7 +2849,7 @@ static int lfs_setstripe_internal(int argc, char **argv, snprintf(cmd, sizeof(cmd), "%s %s", progname, argv[0]); progname = cmd; while ((c = getopt_long(argc, argv, - "bc:C:dDE:f:H:i:I:m:N::no:p:L:s:S:vx:y:", + "bc:C:dDE:f:H:i:I:m:N::no:p:L:s:S:vx:y:z:", long_opts, NULL)) >= 0) { switch (c) { case 0: @@ -2895,7 +2927,7 @@ static int lfs_setstripe_internal(int argc, char **argv, result = -EINVAL; goto usage_error; } - if (last_mirror->m_flags & ~LCME_USER_FLAGS) { + if (last_mirror->m_flags & ~LCME_USER_MIRROR_FLAGS) { fprintf(stderr, "%s: unsupported mirror flags: %s\n", progname, optarg); @@ -2990,9 +3022,8 @@ static int lfs_setstripe_internal(int argc, char **argv, if (lsa.lsa_comp_end != 0) { result = comp_args_to_layout(lpp, &lsa, true); if (result) { - fprintf(stderr, - "%s %s: invalid layout\n", - progname, argv[0]); + fprintf(stderr, "%s: invalid layout\n", + progname); goto usage_error; } @@ -3232,6 +3263,19 @@ static int lfs_setstripe_internal(int argc, char **argv, from_yaml = true; template = optarg; break; + case 'z': + result = llapi_parse_size(optarg, + &lsa.lsa_extension_size, + &size_units, 0); + if (result) { + fprintf(stderr, + "%s %s: invalid extension size '%s'\n", + progname, argv[0], optarg); + goto usage_error; + } + + lsa.lsa_extension_comp = true; + break; default: fprintf(stderr, "%s %s: unrecognized option '%s'\n", progname, argv[0], argv[optind - 1]); @@ -3285,8 +3329,12 @@ static int lfs_setstripe_internal(int argc, char **argv, if (lsa.lsa_comp_end != 0) { result = comp_args_to_layout(lpp, &lsa, true); - if (result) + if (result) { + fprintf(stderr, "error: %s: invalid layout\n", + progname); + result = -EINVAL; goto error; + } } if (mirror_flags & MF_NO_VERIFY) { @@ -3305,9 +3353,6 @@ static int lfs_setstripe_internal(int argc, char **argv, } } - /* Only LCME_FL_INIT flags is used in PFL, and it shouldn't be - * altered by user space tool, so we don't need to support the - * --component-set for this moment. */ if (comp_set && !comp_id) { fprintf(stderr, "%s %s: --component-set doesn't have component-id set\n", progname, argv[0]); @@ -3374,8 +3419,11 @@ static int lfs_setstripe_internal(int argc, char **argv, result = adjust_first_extent(fname, layout); if (result == -ENODATA) comp_add = 0; - else if (result != 0) + else if (result != 0) { + fprintf(stderr, "error: %s: invalid layout\n", + progname); goto error; + } } if (from_yaml && from_copy) { diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index e3a32e3..4065574 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -2629,6 +2629,7 @@ enum lov_dump_flags { LDF_INDENT = 0x0004, LDF_SKIP_OBJS = 0x0008, LDF_YAML = 0x0010, + LDF_EXTENSION = 0x0020, }; static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path, @@ -2642,6 +2643,7 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path, bool indent = flags & LDF_INDENT; bool yaml = flags & LDF_YAML; bool skip_objs = flags & LDF_SKIP_OBJS; + bool extension = flags & LDF_EXTENSION; char *prefix = is_dir ? "" : "lmm_"; char *separator = ""; char *space = indent ? " " : ""; @@ -2725,12 +2727,12 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path, " stripe count."); } else { llapi_printf(LLAPI_MSG_NORMAL, "%d", - lum->lmm_stripe_count == - (typeof(lum->lmm_stripe_count))(-1) - ? -1 : lum->lmm_stripe_count); + extension ? 0 : + (__s16)lum->lmm_stripe_count); } } else { llapi_printf(LLAPI_MSG_NORMAL, "%hd", + extension ? 0 : (__s16)lum->lmm_stripe_count); } if (!yaml && is_dir) @@ -2741,7 +2743,10 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path, if (verbose & VERBOSE_STRIPE_SIZE) { llapi_printf(LLAPI_MSG_NORMAL, "%s", separator); - if (verbose & ~VERBOSE_STRIPE_SIZE) + if (verbose & ~VERBOSE_STRIPE_SIZE && extension) + llapi_printf(LLAPI_MSG_NORMAL, "%s%sextension_size: ", + space, prefix); + else if (verbose & ~VERBOSE_STRIPE_SIZE) llapi_printf(LLAPI_MSG_NORMAL, "%s%sstripe_size: ", space, prefix); if (is_dir && !is_raw && lum->lmm_stripe_size == 0) { @@ -2755,7 +2760,10 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path, "Cannot determine default" " stripe size."); } else { - llapi_printf(LLAPI_MSG_NORMAL, "%u", + /* Extension size is in KiB */ + llapi_printf(LLAPI_MSG_NORMAL, "%llu", + extension ? + lum->lmm_stripe_size * SEL_UNIT_SIZE : lum->lmm_stripe_size); } if (!yaml && is_dir) @@ -3393,7 +3401,7 @@ static void lov_dump_comp_v1(struct find_param *param, char *path, struct lov_user_md_v1 *v1; char pool_name[LOV_MAXPOOLNAME + 1]; int obdindex = param->fp_obd_index; - int i, j, match; + int i, j, match, ext; bool obdstripe = false; __u16 mirror_index = 0; __u16 mirror_id = 0; @@ -3521,9 +3529,10 @@ static void lov_dump_comp_v1(struct find_param *param, char *path, objects = lov_v1v3_objects(v1); lov_v1v3_pool_name(v1, pool_name); + ext = entry->lcme_flags & LCME_FL_EXTENSION ? LDF_EXTENSION : 0; lov_dump_user_lmm_v1v3(v1, pool_name, objects, path, obdindex, param->fp_max_depth, param->fp_verbose, - flags); + flags | ext); } if (print_last_init_comp(param)) { /** @@ -3542,9 +3551,11 @@ static void lov_dump_comp_v1(struct find_param *param, char *path, objects = lov_v1v3_objects(v1); lov_v1v3_pool_name(v1, pool_name); + entry = &comp_v1->lcm_entries[i]; + ext = entry->lcme_flags & LCME_FL_EXTENSION ? LDF_EXTENSION : 0; lov_dump_user_lmm_v1v3(v1, pool_name, objects, path, obdindex, param->fp_max_depth, param->fp_verbose, - flags); + flags | ext); } } diff --git a/lustre/utils/liblustreapi_layout.c b/lustre/utils/liblustreapi_layout.c index 8bdb276..4976a14 100644 --- a/lustre/utils/liblustreapi_layout.c +++ b/lustre/utils/liblustreapi_layout.c @@ -1152,6 +1152,13 @@ static bool llapi_layout_stripe_count_is_valid(int64_t stripe_count) llapi_stripe_count_is_valid(stripe_count)); } +static bool llapi_layout_extension_size_is_valid(uint64_t ext_size) +{ + return (ext_size != 0 && + llapi_stripe_size_is_aligned(ext_size) && + !llapi_stripe_size_is_too_big(ext_size)); +} + static bool llapi_layout_stripe_size_is_valid(uint64_t stripe_size) { return stripe_size == LLAPI_LAYOUT_DEFAULT || @@ -1196,18 +1203,20 @@ int llapi_layout_stripe_count_set(struct llapi_layout *layout, } /** - * Get the stripe size of \a layout. + * Get the stripe/extension size of \a layout. * * \param[in] layout layout to get stripe size from * \param[out] size integer to store stripe size in + * \param[in] extension flag if extenion size is requested * * \retval 0 on success * \retval -1 if arguments are invalid */ -int llapi_layout_stripe_size_get(const struct llapi_layout *layout, - uint64_t *size) +static int layout_stripe_size_get(const struct llapi_layout *layout, + uint64_t *size, bool extension) { struct llapi_layout_comp *comp; + int comp_ext; comp = __llapi_layout_cur_comp(layout); if (comp == NULL) @@ -1218,39 +1227,82 @@ int llapi_layout_stripe_size_get(const struct llapi_layout *layout, return -1; } + comp_ext = comp->llc_flags & LCME_FL_EXTENSION; + if ((comp_ext && !extension) || (!comp_ext && extension)) { + errno = EINVAL; + return -1; + } + *size = comp->llc_stripe_size; + if (comp->llc_flags & LCME_FL_EXTENSION) + *size *= SEL_UNIT_SIZE; return 0; } +int llapi_layout_stripe_size_get(const struct llapi_layout *layout, + uint64_t *size) +{ + return layout_stripe_size_get(layout, size, false); +} + +int llapi_layout_extension_size_get(const struct llapi_layout *layout, + uint64_t *size) +{ + return layout_stripe_size_get(layout, size, true); +} + /** - * Set the stripe size of \a layout. + * Set the stripe/extension size of \a layout. * * \param[in] layout layout to set stripe size in * \param[in] size value to be set + * \param[in] extension flag if extenion size is passed * * \retval 0 on success * \retval -1 if arguments are invalid */ -int llapi_layout_stripe_size_set(struct llapi_layout *layout, - uint64_t size) +static int layout_stripe_size_set(struct llapi_layout *layout, + uint64_t size, bool extension) { struct llapi_layout_comp *comp; + int comp_ext; comp = __llapi_layout_cur_comp(layout); if (comp == NULL) return -1; - if (!llapi_layout_stripe_size_is_valid(size)) { + comp_ext = comp->llc_flags & LCME_FL_EXTENSION; + if ((comp_ext && !extension) || (!comp_ext && extension)) { errno = EINVAL; return -1; } - comp->llc_stripe_size = size; + if (comp_ext) + size /= SEL_UNIT_SIZE; + + if ((comp_ext && !llapi_layout_extension_size_is_valid(size)) || + (!comp_ext && !llapi_layout_stripe_size_is_valid(size))) { + errno = EINVAL; + return -1; + } + comp->llc_stripe_size = size; return 0; } +int llapi_layout_stripe_size_set(struct llapi_layout *layout, + uint64_t size) +{ + return layout_stripe_size_set(layout, size, false); +} + +int llapi_layout_extension_size_set(struct llapi_layout *layout, + uint64_t size) +{ + return layout_stripe_size_set(layout, size, true); +} + /** * Get the RAID pattern of \a layout. * -- 1.8.3.1