Whamcloud - gitweb
LU-9771 flr: lfs mirror create and extend commands
[fs/lustre-release.git] / lustre / utils / liblustreapi_layout.c
index 0168de2..ae2826e 100644 (file)
@@ -38,7 +38,6 @@
 
 #include <libcfs/util/list.h>
 #include <lustre/lustreapi.h>
-#include <lustre/lustre_idl.h>
 #include "lustreapi_internal.h"
 
 /**
@@ -71,6 +70,7 @@ struct llapi_layout {
        uint32_t        llot_gen;
        uint32_t        llot_flags;
        bool            llot_is_composite;
+       uint16_t        llot_mirror_count;
        /* Cursor pointing to one of the components in llot_comp_list */
        struct llapi_layout_comp *llot_cur_comp;
        struct list_head          llot_comp_list;
@@ -318,6 +318,7 @@ static struct llapi_layout *__llapi_layout_alloc(void)
        layout->llot_gen = 0;
        layout->llot_flags = 0;
        layout->llot_is_composite = false;
+       layout->llot_mirror_count = 1;
        layout->llot_cur_comp = NULL;
        INIT_LIST_HEAD(&layout->llot_comp_list);
 
@@ -378,7 +379,9 @@ llapi_layout_from_lum(const struct lov_user_md *lum, int lum_size)
        if (lum->lmm_magic == LOV_MAGIC_COMP_V1) {
                comp_v1 = (struct lov_comp_md_v1 *)lum;
                ent_count = comp_v1->lcm_entry_count;
+               layout->llot_gen = comp_v1->lcm_layout_gen;
                layout->llot_is_composite = true;
+               layout->llot_mirror_count = comp_v1->lcm_mirror_count + 1;
                layout->llot_gen = comp_v1->lcm_layout_gen;
                layout->llot_flags = comp_v1->lcm_flags;
        } else if (lum->lmm_magic == LOV_MAGIC_V1 ||
@@ -507,7 +510,7 @@ llapi_layout_to_lum(const struct llapi_layout *layout)
                        comp_cnt++;
 
                lum_size = sizeof(*comp_v1) + comp_cnt * sizeof(*ent);
-               lum = malloc(lum_size);
+               lum = calloc(lum_size, 1);
                if (lum == NULL) {
                        errno = ENOMEM;
                        return NULL;
@@ -516,8 +519,9 @@ llapi_layout_to_lum(const struct llapi_layout *layout)
                comp_v1->lcm_magic = LOV_USER_MAGIC_COMP_V1;
                comp_v1->lcm_size = lum_size;
                comp_v1->lcm_layout_gen = 0;
-               comp_v1->lcm_flags = 0;
+               comp_v1->lcm_flags = layout->llot_flags;
                comp_v1->lcm_entry_count = comp_cnt;
+               comp_v1->lcm_mirror_count = layout->llot_mirror_count - 1;
                offset += lum_size;
        }
 
@@ -567,9 +571,9 @@ llapi_layout_to_lum(const struct llapi_layout *layout)
 
                blob->lmm_magic = magic;
                if (pattern == LLAPI_LAYOUT_DEFAULT)
-                       blob->lmm_pattern = 0;
-               else if (pattern == LLAPI_LAYOUT_RAID0)
                        blob->lmm_pattern = LOV_PATTERN_RAID0;
+               else if (pattern == LLAPI_LAYOUT_MDT)
+                       blob->lmm_pattern = LOV_PATTERN_MDT;
                else
                        blob->lmm_pattern = pattern;
 
@@ -732,7 +736,7 @@ static bool is_any_specified(const struct llapi_layout *layout)
        if (comp == NULL)
                return false;
 
-       if (layout->llot_is_composite)
+       if (layout->llot_is_composite || layout->llot_mirror_count != 1)
                return true;
 
        return comp->llc_pattern != LLAPI_LAYOUT_DEFAULT ||
@@ -1207,7 +1211,7 @@ int llapi_layout_pattern_get(const struct llapi_layout *layout,
 }
 
 /**
- * Set the RAID pattern of \a layout.
+ * Set the pattern of \a layout.
  *
  * \param[in] layout   layout to set pattern in
  * \param[in] pattern  value to be set
@@ -1225,7 +1229,7 @@ int llapi_layout_pattern_set(struct llapi_layout *layout, uint64_t pattern)
                return -1;
 
        if (pattern != LLAPI_LAYOUT_DEFAULT &&
-           pattern != LLAPI_LAYOUT_RAID0) {
+           pattern != LLAPI_LAYOUT_RAID0 && pattern != LLAPI_LAYOUT_MDT) {
                errno = EOPNOTSUPP;
                return -1;
        }
@@ -1508,6 +1512,92 @@ int llapi_layout_file_create(const char *path, int open_flags, int mode,
                                      layout);
 }
 
+int llapi_layout_flags_get(struct llapi_layout *layout, uint32_t *flags)
+{
+       if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       *flags = layout->llot_flags;
+       return 0;
+}
+
+/**
+ * Set flags to the header of a component layout.
+ */
+int llapi_layout_flags_set(struct llapi_layout *layout, uint32_t flags)
+{
+       if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       layout->llot_flags = flags;
+       return 0;
+}
+
+/**
+ * llapi_layout_mirror_count_is_valid() - Check the validity of mirror count.
+ * @count: Mirror count value to be checked.
+ *
+ * This function checks the validity of mirror count.
+ *
+ * Return: true on success or false on failure.
+ */
+static bool llapi_layout_mirror_count_is_valid(uint16_t count)
+{
+       return count >= 0 && count <= LUSTRE_MIRROR_COUNT_MAX;
+}
+
+/**
+ * llapi_layout_mirror_count_get() - Get mirror count from the header of
+ *                                  a layout.
+ * @layout: Layout to get mirror count from.
+ * @count:  Returned mirror count value.
+ *
+ * This function gets mirror count from the header of a layout.
+ *
+ * Return: 0 on success or -1 on failure.
+ */
+int llapi_layout_mirror_count_get(struct llapi_layout *layout,
+                                 uint16_t *count)
+{
+       if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       *count = layout->llot_mirror_count;
+       return 0;
+}
+
+/**
+ * llapi_layout_mirror_count_set() - Set mirror count to the header of a layout.
+ * @layout: Layout to set mirror count in.
+ * @count:  Mirror count value to be set.
+ *
+ * This function sets mirror count to the header of a layout.
+ *
+ * Return: 0 on success or -1 on failure.
+ */
+int llapi_layout_mirror_count_set(struct llapi_layout *layout,
+                                 uint16_t count)
+{
+       if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       if (!llapi_layout_mirror_count_is_valid(count)) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       layout->llot_mirror_count = count;
+       return 0;
+}
+
 /**
  * Fetch the start and end offset of the current layout component.
  *
@@ -1691,6 +1781,33 @@ int llapi_layout_comp_id_get(const struct llapi_layout *layout, uint32_t *id)
 }
 
 /**
+ * Return the mirror id of the current layout component.
+ *
+ * \param[in] layout   the layout component
+ * \param[out] id      stored the returned mirror ID
+ *
+ * \retval     0 on success
+ * \retval     <0 if error occurs
+ */
+int llapi_layout_mirror_id_get(const struct llapi_layout *layout, uint32_t *id)
+{
+       struct llapi_layout_comp *comp;
+
+       comp = __llapi_layout_cur_comp(layout);
+       if (comp == NULL)
+               return -1;
+
+       if (id == NULL) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       *id = mirror_id_of(comp->llc_id);
+
+       return 0;
+}
+
+/**
  * Adds a component to \a layout, the new component will be added to
  * the tail of components list and it'll inherit attributes of existing
  * ones. The \a layout will change it's current component pointer to
@@ -1717,12 +1834,6 @@ int llapi_layout_comp_add(struct llapi_layout *layout)
        last = list_entry(layout->llot_comp_list.prev, typeof(*last),
                          llc_list);
 
-       /* Inherit some attributes from existing component */
-       new->llc_stripe_size = comp->llc_stripe_size;
-       new->llc_stripe_count = comp->llc_stripe_count;
-       if (comp->llc_pool_name[0] != '\0')
-               strncpy(new->llc_pool_name, comp->llc_pool_name,
-                       sizeof(comp->llc_pool_name));
        if (new->llc_extent.e_end <= last->llc_extent.e_end) {
                __llapi_comp_free(new);
                errno = EINVAL;
@@ -1842,8 +1953,11 @@ int llapi_layout_comp_use(struct llapi_layout *layout,
                return -1;
 
        if (!layout->llot_is_composite) {
-               errno = EINVAL;
-               return -1;
+               if (pos == LLAPI_LAYOUT_COMP_USE_FIRST ||
+                   pos == LLAPI_LAYOUT_COMP_USE_LAST)
+                       return 0;
+               errno = ENOENT;
+               return 1;
        }
 
        head = list_entry(layout->llot_comp_list.next, typeof(*head), llc_list);
@@ -2025,3 +2139,78 @@ bool llapi_layout_is_composite(struct llapi_layout *layout)
 {
        return layout->llot_is_composite;
 }
+
+/**
+ * llapi_layout_merge() - Merge a composite layout into another one.
+ * @dst_layout: Destination composite layout.
+ * @src_layout: Source composite layout.
+ *
+ * This function copies all of the components from @src_layout and
+ * appends them to @dst_layout.
+ *
+ * Return: 0 on success or -1 on failure.
+ */
+int llapi_layout_merge(struct llapi_layout **dst_layout,
+                      const struct llapi_layout *src_layout)
+{
+       struct llapi_layout *new_layout = *dst_layout;
+       struct llapi_layout_comp *new = NULL;
+       struct llapi_layout_comp *comp = NULL;
+       int i = 0;
+
+       if (src_layout == NULL ||
+           list_empty((struct list_head *)&src_layout->llot_comp_list))
+               return 0;
+
+       if (new_layout == NULL) {
+               new_layout = __llapi_layout_alloc();
+               if (new_layout == NULL) {
+                       errno = ENOMEM;
+                       return -1;
+               }
+       }
+
+       list_for_each_entry(comp, &src_layout->llot_comp_list, llc_list) {
+               new = __llapi_comp_alloc(0);
+               if (new == NULL) {
+                       errno = ENOMEM;
+                       goto error;
+               }
+
+               new->llc_pattern = comp->llc_pattern;
+               new->llc_stripe_size = comp->llc_stripe_size;
+               new->llc_stripe_count = comp->llc_stripe_count;
+               new->llc_stripe_offset = comp->llc_stripe_offset;
+
+               if (comp->llc_pool_name[0] != '\0')
+                       strncpy(new->llc_pool_name, comp->llc_pool_name,
+                               sizeof(new->llc_pool_name));
+
+               for (i = 0; i < comp->llc_objects_count; i++) {
+                       if (__llapi_comp_objects_realloc(new,
+                           stripe_number_roundup(i)) < 0) {
+                               errno = EINVAL;
+                               __llapi_comp_free(new);
+                               goto error;
+                       }
+                       new->llc_objects[i].l_ost_idx = \
+                               comp->llc_objects[i].l_ost_idx;
+               }
+
+               new->llc_objects_count = comp->llc_objects_count;
+               new->llc_extent.e_start = comp->llc_extent.e_start;
+               new->llc_extent.e_end = comp->llc_extent.e_end;
+               new->llc_id = comp->llc_id;
+               new->llc_flags = comp->llc_flags;
+
+               list_add_tail(&new->llc_list, &new_layout->llot_comp_list);
+               new_layout->llot_cur_comp = new;
+       }
+       new_layout->llot_is_composite = true;
+
+       *dst_layout = new_layout;
+       return 0;
+error:
+       llapi_layout_free(new_layout);
+       return -1;
+}