#include <libcfs/util/list.h>
#include <lustre/lustreapi.h>
-#include <lustre/lustre_idl.h>
#include "lustreapi_internal.h"
/**
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;
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);
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 ||
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;
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;
}
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;
}
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;
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;
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';
+ }
}
/**
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 ||
}
/**
- * 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
return -1;
if (pattern != LLAPI_LAYOUT_DEFAULT &&
- pattern != LLAPI_LAYOUT_RAID0) {
+ pattern != LLAPI_LAYOUT_RAID0 && pattern != LLAPI_LAYOUT_MDT) {
errno = EOPNOTSUPP;
return -1;
}
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.
*
}
/**
+ * 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
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 (new->llc_extent.e_end <= last->llc_extent.e_end) {
__llapi_comp_free(new);
errno = EINVAL;
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;
}
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);
}
/**
- * 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;
+ }
+
+ 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", &id, sizeof(id), 0);
+ 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;
}
/**
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;
+}
+
+/**
+ * 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;
+}