Whamcloud - gitweb
LU-10070 lod: SEL: Add flag & setstripe support 82/33782/22
authorPatrick Farrell <paf@cray.com>
Mon, 3 Jun 2019 16:22:09 +0000 (19:22 +0300)
committerOleg Drokin <green@whamcloud.com>
Fri, 12 Jul 2019 05:20:54 +0000 (05:20 +0000)
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 <paf@cray.com>
Change-Id: I4392b70266cbab5bc8fa42afc3c360b954d5918a
Reviewed-on: https://review.whamcloud.com/33782
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: Alexey Lyashkov <c17817@cray.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Patrick Farrell <pfarrell@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/doc/lfs-setstripe.1
lustre/doc/llapi_layout_extension_size_get.3 [new file with mode: 0644]
lustre/doc/llapi_layout_extension_size_set.3 [new file with mode: 0644]
lustre/doc/llapi_layout_stripe_size_get.3
lustre/include/lustre/lustreapi.h
lustre/include/uapi/linux/lustre/lustre_user.h
lustre/lod/lod_qos.c
lustre/utils/lfs.c
lustre/utils/liblustreapi.c
lustre/utils/liblustreapi_layout.c

index ddd474d..0ff3660 100644 (file)
@@ -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 (file)
index 0000000..57a0d31
--- /dev/null
@@ -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 <lustre/lustreapi.h>
+.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 (file)
index 0000000..1711f41
--- /dev/null
@@ -0,0 +1 @@
+.so man3/llapi_layout_extension_size_get.3
index 52f0c1e..abc1b4a 100644 (file)
@@ -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)
index 72358b9..831143c 100644 (file)
@@ -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" },
 };
 
 /**
index a9c7f64..86bfb05 100644 (file)
@@ -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. */
index fbc35cd..3b87fa9 100644 (file)
@@ -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;
index 9ffb589..b0ff694 100644 (file)
@@ -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) {
index e3a32e3..4065574 100644 (file)
@@ -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);
        }
 }
 
index 8bdb276..4976a14 100644 (file)
@@ -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.
  *