Whamcloud - gitweb
LU-9771 flr: resync support and test tool
[fs/lustre-release.git] / lustre / utils / liblustreapi_layout.c
index 7f364fd..2ff37b6 100644 (file)
@@ -38,7 +38,6 @@
 
 #include <libcfs/util/list.h>
 #include <lustre/lustreapi.h>
-#include <lustre/lustre_idl.h>
 #include "lustreapi_internal.h"
 
 /**
@@ -516,8 +515,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 = 0;
                offset += lum_size;
        }
 
@@ -560,6 +560,7 @@ llapi_layout_to_lum(const struct llapi_layout *layout)
                        goto error;
                } else {
                        lum = blob;
+                       comp_v1 = (struct lov_comp_md_v1 *)lum;
                        blob = (struct lov_user_md *)((char *)lum + lum_size);
                        lum_size += blob_size;
                }
@@ -569,6 +570,8 @@ llapi_layout_to_lum(const struct llapi_layout *layout)
                        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;
 
@@ -611,7 +614,7 @@ llapi_layout_to_lum(const struct llapi_layout *layout)
                        lmm_objects[i].l_ost_idx =
                                comp->llc_objects[i].l_ost_idx;
 
-               if (comp_v1 != NULL) {
+               if (layout->llot_is_composite) {
                        ent = &comp_v1->lcm_entries[ent_idx];
                        ent->lcme_id = comp->llc_id;
                        ent->lcme_flags = comp->llc_flags;
@@ -647,10 +650,12 @@ static void get_parent_dir(const char *path, char *buf, size_t size)
        strncpy(buf, path, size);
        p = strrchr(buf, '/');
 
-       if (p != NULL)
+       if (p != NULL) {
                *p = '\0';
-       else if (size >= 2)
+       } else if (size >= 2) {
                strncpy(buf, ".", 2);
+               buf[size - 1] = '\0';
+       }
 }
 
 /**
@@ -1204,7 +1209,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
@@ -1222,7 +1227,8 @@ 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;
        }
@@ -1505,6 +1511,31 @@ 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;
+}
+
 /**
  * Fetch the start and end offset of the current layout component.
  *
@@ -1688,6 +1719,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,6 +1775,9 @@ int llapi_layout_comp_add(struct llapi_layout *layout)
        /* 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;
@@ -1766,11 +1827,10 @@ int llapi_layout_comp_del(struct llapi_layout *layout)
                return -1;
        }
 
+       layout->llot_cur_comp =
+               list_entry(comp->llc_list.prev, typeof(*comp), llc_list);
        list_del_init(&comp->llc_list);
        __llapi_comp_free(comp);
-       layout->llot_cur_comp =
-               list_entry(comp->llc_list.prev, typeof(*comp),
-                          llc_list);
 
        return 0;
 }
@@ -1785,26 +1845,26 @@ int llapi_layout_comp_del(struct llapi_layout *layout)
  * \retval     =0 : moved successfully
  * \retval     <0 if error occurs
  */
-int llapi_layout_comp_move_at(struct llapi_layout *layout, uint32_t id)
+int llapi_layout_comp_use_id(struct llapi_layout *layout, uint32_t comp_id)
 {
        struct llapi_layout_comp *comp;
 
        comp = __llapi_layout_cur_comp(layout);
        if (comp == NULL)
-               return -1;
+               return -1; /* use previously set errno */
 
        if (!layout->llot_is_composite) {
                errno = EINVAL;
                return -1;
        }
 
-       if (id == 0) {
+       if (comp_id == LCME_ID_INVAL) {
                errno = EINVAL;
                return -1;
        }
 
        list_for_each_entry(comp, &layout->llot_comp_list, llc_list) {
-               if (comp->llc_id == id) {
+               if (comp->llc_id == comp_id) {
                        layout->llot_cur_comp = comp;
                        return 0;
                }
@@ -1818,15 +1878,17 @@ int llapi_layout_comp_move_at(struct llapi_layout *layout, uint32_t id)
  *
  * \param[in] layout   composite layout
  * \param[in] pos      the position to be moved, it can be:
- *                     LLAPI_LAYOUT_COMP_POS_FIRST: move to head
- *                     LLAPI_LAYOUT_COMP_POS_LAST: move to tail
- *                     LLAPI_LAYOUT_COMP_POS_NEXT: move to next
+ *                     LLAPI_LAYOUT_COMP_USE_FIRST: use first component
+ *                     LLAPI_LAYOUT_COMP_USE_LAST: use last component
+ *                     LLAPI_LAYOUT_COMP_USE_NEXT: use component after current
+ *                     LLAPI_LAYOUT_COMP_USE_PREV: use component before current
  *
  * \retval     =0 : moved successfully
- * \retval     =1 : already at the tail when move to the next
+ * \retval     =1 : at last component with NEXT, at first component with PREV
  * \retval     <0 if error occurs
  */
-int llapi_layout_comp_move(struct llapi_layout *layout, uint32_t pos)
+int llapi_layout_comp_use(struct llapi_layout *layout,
+                         enum llapi_layout_comp_use pos)
 {
        struct llapi_layout_comp *comp, *head, *tail;
 
@@ -1835,25 +1897,39 @@ int llapi_layout_comp_move(struct llapi_layout *layout, uint32_t pos)
                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);
-       tail = list_entry(layout->llot_comp_list.prev, typeof(*tail),
-                         llc_list);
-
-       if (pos == LLAPI_LAYOUT_COMP_POS_NEXT) {
-               if (comp == tail)
+       head = list_entry(layout->llot_comp_list.next, typeof(*head), llc_list);
+       tail = list_entry(layout->llot_comp_list.prev, typeof(*tail), llc_list);
+       switch (pos) {
+       case LLAPI_LAYOUT_COMP_USE_FIRST:
+               layout->llot_cur_comp = head;
+               break;
+       case LLAPI_LAYOUT_COMP_USE_NEXT:
+               if (comp == tail) {
+                       errno = ENOENT;
                        return 1;
+               }
                layout->llot_cur_comp = list_entry(comp->llc_list.next,
                                                   typeof(*comp), llc_list);
-       } else if (pos == LLAPI_LAYOUT_COMP_POS_FIRST) {
-               layout->llot_cur_comp = head;
-       } else if (pos == LLAPI_LAYOUT_COMP_POS_LAST) {
+               break;
+       case LLAPI_LAYOUT_COMP_USE_LAST:
                layout->llot_cur_comp = tail;
-       } else {
+               break;
+       case LLAPI_LAYOUT_COMP_USE_PREV:
+               if (comp == head) {
+                       errno = ENOENT;
+                       return 1;
+               }
+               layout->llot_cur_comp = list_entry(comp->llc_list.prev,
+                                                  typeof(*comp), llc_list);
+               break;
+       default:
                errno = EINVAL;
                return -1;
        }
@@ -1912,35 +1988,72 @@ out:
 }
 
 /**
- * Delete component(s) by the specified component id (accepting lcme_id
- * wildcards also) from an existing file.
+ * Delete component(s) by the specified component id or component flags
+ * from an existing file.
  *
  * \param[in] path     path name of the file
- * \param[in] id       unique component ID or an lcme_id
- *                     (LCME_ID_NONE | LCME_FL_* )
+ * \param[in] id       unique component ID
+ * \param[in] flags    flags: LCME_FL_* or;
+ *                     negative flags: (LCME_FL_NEG|LCME_FL_*)
  */
-int llapi_layout_file_comp_del(const char *path, uint32_t id)
+int llapi_layout_file_comp_del(const char *path, uint32_t id, uint32_t flags)
 {
-       int rc, fd;
+       int rc, fd, lum_size;
+       struct llapi_layout *layout;
+       struct llapi_layout_comp *comp;
+       struct lov_user_md *lum;
 
-       if (path == NULL || id == 0) {
+       if (path == NULL || id > LCME_ID_MAX || (flags & ~LCME_KNOWN_FLAGS)) {
                errno = EINVAL;
                return -1;
        }
 
-       fd = open(path, O_RDWR);
-       if (fd < 0)
+       /* Can only specify ID or flags, not both. */
+       if (id != 0 && flags != 0) {
+               errno = EINVAL;
                return -1;
+       }
 
-       rc = fsetxattr(fd, XATTR_LUSTRE_LOV".del", &id, sizeof(id), 0);
+       layout = llapi_layout_alloc();
+       if (layout == NULL)
+               return -1;
+
+       llapi_layout_comp_extent_set(layout, 0, LUSTRE_EOF);
+       comp = __llapi_layout_cur_comp(layout);
+       if (comp == NULL) {
+               llapi_layout_free(layout);
+               return -1;
+       }
+
+       comp->llc_id = id;
+       comp->llc_flags = flags;
+
+       lum = llapi_layout_to_lum(layout);
+       if (lum == NULL) {
+               llapi_layout_free(layout);
+               return -1;
+       }
+       lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
+
+       fd = open(path, O_RDWR);
+       if (fd < 0) {
+               rc = -1;
+               goto out;
+       }
+
+       rc = fsetxattr(fd, XATTR_LUSTRE_LOV".del", lum, lum_size, 0);
        if (rc < 0) {
                int tmp_errno = errno;
                close(fd);
                errno = tmp_errno;
-               return -1;
+               rc = -1;
+               goto out;
        }
        close(fd);
-       return 0;
+out:
+       free(lum);
+       llapi_layout_free(layout);
+       return rc;
 }
 
 /**
@@ -1957,3 +2070,16 @@ int llapi_layout_file_comp_set(const char *path,
        errno = EOPNOTSUPP;
        return -1;
 }
+
+/**
+ * Check if the file layout is composite.
+ *
+ * \param[in] layout   the file layout to check
+ *
+ * \retval true                composite
+ * \retval false       not composite
+ */
+bool llapi_layout_is_composite(struct llapi_layout *layout)
+{
+       return layout->llot_is_composite;
+}