4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * All rights reserved. This program and the accompanying materials
7 * are made available under the terms of the GNU Lesser General Public License
8 * (LGPL) version 2.1 or (at your discretion) any later version.
9 * (LGPL) version 2.1 accompanies this distribution, and is available at
10 * http://www.gnu.org/licenses/lgpl-2.1.html
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
20 * lustre/utils/liblustreapi_layout.c
22 * lustreapi library for layout calls for interacting with the layout of
23 * Lustre files while hiding details of the internal data structures
26 * Copyright (c) 2016, Intel Corporation.
28 * Author: Ned Bass <bass6@llnl.gov>
37 #include <sys/xattr.h>
38 #include <sys/param.h>
40 #include <libcfs/util/list.h>
41 #include <lustre/lustreapi.h>
42 #include "lustreapi_internal.h"
45 * Layout component, which contains all attributes of a plain
48 struct llapi_layout_comp {
50 uint64_t llc_stripe_size;
51 uint64_t llc_stripe_count;
52 uint64_t llc_stripe_offset;
53 /* Add 1 so user always gets back a null terminated string. */
54 char llc_pool_name[LOV_MAXPOOLNAME + 1];
55 /** Number of objects in llc_objects array if was initialized. */
56 uint32_t llc_objects_count;
57 struct lov_user_ost_data_v1 *llc_objects;
58 /* fields used only for composite layouts */
59 struct lu_extent llc_extent; /* [start, end) of component */
60 uint32_t llc_id; /* unique ID of component */
61 uint32_t llc_flags; /* LCME_FL_* flags */
62 struct list_head llc_list; /* linked to the llapi_layout
67 * An Opaque data type abstracting the layout of a Lustre file.
70 uint32_t llot_magic; /* LLAPI_LAYOUT_MAGIC */
73 bool llot_is_composite;
74 uint16_t llot_mirror_count;
75 /* Cursor pointing to one of the components in llot_comp_list */
76 struct llapi_layout_comp *llot_cur_comp;
77 struct list_head llot_comp_list;
81 * Compute the number of elements in the lmm_objects array of \a lum
82 * with size \a lum_size.
84 * \param[in] lum the struct lov_user_md to check
85 * \param[in] lum_size the number of bytes in \a lum
87 * \retval number of elements in array lum->lmm_objects
89 static int llapi_layout_objects_in_lum(struct lov_user_md *lum, size_t lum_size)
94 if (lum_size < lov_user_md_size(0, LOV_MAGIC_V1))
97 if (lum->lmm_magic == __swab32(LOV_MAGIC_V1) ||
98 lum->lmm_magic == __swab32(LOV_MAGIC_V3))
99 magic = __swab32(lum->lmm_magic);
101 magic = lum->lmm_magic;
103 base_size = lov_user_md_size(0, magic);
105 if (lum_size <= base_size)
108 return (lum_size - base_size) / sizeof(lum->lmm_objects[0]);
112 * Byte-swap the fields of struct lov_user_md.
114 * XXX Rather than duplicating swabbing code here, we should eventually
115 * refactor the needed functions in lustre/ptlrpc/pack_generic.c
116 * into a library that can be shared between kernel and user code.
119 llapi_layout_swab_lov_user_md(struct lov_user_md *lum, int lum_size)
121 int i, j, ent_count, obj_count;
122 struct lov_comp_md_v1 *comp_v1 = NULL;
123 struct lov_comp_md_entry_v1 *ent;
124 struct lov_user_ost_data *lod;
126 if (lum->lmm_magic != __swab32(LOV_MAGIC_V1) &&
127 lum->lmm_magic != __swab32(LOV_MAGIC_V3) &&
128 lum->lmm_magic != __swab32(LOV_MAGIC_COMP_V1))
131 if (lum->lmm_magic == __swab32(LOV_MAGIC_COMP_V1))
132 comp_v1 = (struct lov_comp_md_v1 *)lum;
134 if (comp_v1 != NULL) {
135 __swab32s(&comp_v1->lcm_magic);
136 __swab32s(&comp_v1->lcm_size);
137 __swab32s(&comp_v1->lcm_layout_gen);
138 __swab16s(&comp_v1->lcm_flags);
139 __swab16s(&comp_v1->lcm_entry_count);
140 ent_count = comp_v1->lcm_entry_count;
145 for (i = 0; i < ent_count; i++) {
146 if (comp_v1 != NULL) {
147 ent = &comp_v1->lcm_entries[i];
148 __swab32s(&ent->lcme_id);
149 __swab32s(&ent->lcme_flags);
150 __swab64s(&ent->lcme_extent.e_start);
151 __swab64s(&ent->lcme_extent.e_end);
152 __swab32s(&ent->lcme_offset);
153 __swab32s(&ent->lcme_size);
155 lum = (struct lov_user_md *)((char *)comp_v1 +
157 lum_size = ent->lcme_size;
159 obj_count = llapi_layout_objects_in_lum(lum, lum_size);
161 __swab32s(&lum->lmm_magic);
162 __swab32s(&lum->lmm_pattern);
163 __swab32s(&lum->lmm_stripe_size);
164 __swab16s(&lum->lmm_stripe_count);
165 __swab16s(&lum->lmm_stripe_offset);
167 if (lum->lmm_magic != LOV_MAGIC_V1) {
168 struct lov_user_md_v3 *v3;
169 v3 = (struct lov_user_md_v3 *)lum;
170 lod = v3->lmm_objects;
172 lod = lum->lmm_objects;
175 for (j = 0; j < obj_count; j++)
176 __swab32s(&lod[j].l_ost_idx);
181 * (Re-)allocate llc_objects[] to \a num_stripes stripes.
183 * Copy over existing llc_objects[], if any, to the new llc_objects[].
185 * \param[in] layout existing layout to be modified
186 * \param[in] num_stripes number of stripes in new layout
188 * \retval 0 if the objects are re-allocated successfully
189 * \retval -1 on error with errno set
191 static int __llapi_comp_objects_realloc(struct llapi_layout_comp *comp,
192 unsigned int new_stripes)
194 struct lov_user_ost_data_v1 *new_objects;
197 if (new_stripes > LOV_MAX_STRIPE_COUNT) {
202 if (new_stripes == comp->llc_objects_count)
205 if (new_stripes != 0 && new_stripes <= comp->llc_objects_count)
208 new_objects = realloc(comp->llc_objects,
209 sizeof(*new_objects) * new_stripes);
210 if (new_objects == NULL && new_stripes != 0) {
215 for (i = comp->llc_objects_count; i < new_stripes; i++)
216 new_objects[i].l_ost_idx = LLAPI_LAYOUT_IDX_MAX;
218 comp->llc_objects = new_objects;
219 comp->llc_objects_count = new_stripes;
225 * Allocate storage for a llapi_layout_comp with \a num_stripes stripes.
227 * \param[in] num_stripes number of stripes in new layout
229 * \retval valid pointer if allocation succeeds
230 * \retval NULL if allocation fails
232 static struct llapi_layout_comp *__llapi_comp_alloc(unsigned int num_stripes)
234 struct llapi_layout_comp *comp;
236 if (num_stripes > LOV_MAX_STRIPE_COUNT) {
241 comp = calloc(1, sizeof(*comp));
247 comp->llc_objects = NULL;
248 comp->llc_objects_count = 0;
250 if (__llapi_comp_objects_realloc(comp, num_stripes) < 0) {
256 comp->llc_pattern = LLAPI_LAYOUT_DEFAULT;
257 comp->llc_stripe_size = LLAPI_LAYOUT_DEFAULT;
258 comp->llc_stripe_count = LLAPI_LAYOUT_DEFAULT;
259 comp->llc_stripe_offset = LLAPI_LAYOUT_DEFAULT;
260 comp->llc_pool_name[0] = '\0';
261 comp->llc_extent.e_start = 0;
262 comp->llc_extent.e_end = LUSTRE_EOF;
265 INIT_LIST_HEAD(&comp->llc_list);
271 * Free memory allocated for \a comp
273 * \param[in] comp previously allocated by __llapi_comp_alloc()
275 static void __llapi_comp_free(struct llapi_layout_comp *comp)
277 if (comp->llc_objects != NULL)
278 free(comp->llc_objects);
283 * Free memory allocated for \a layout.
285 * \param[in] layout previously allocated by llapi_layout_alloc()
287 void llapi_layout_free(struct llapi_layout *layout)
289 struct llapi_layout_comp *comp, *n;
294 list_for_each_entry_safe(comp, n, &layout->llot_comp_list, llc_list) {
295 list_del_init(&comp->llc_list);
296 __llapi_comp_free(comp);
302 * Allocate and initialize a llapi_layout structure.
304 * \retval valid llapi_layout pointer on success
305 * \retval NULL if memory allocation fails
307 static struct llapi_layout *__llapi_layout_alloc(void)
309 struct llapi_layout *layout;
311 layout = calloc(1, sizeof(*layout));
312 if (layout == NULL) {
318 layout->llot_magic = LLAPI_LAYOUT_MAGIC;
319 layout->llot_gen = 0;
320 layout->llot_flags = 0;
321 layout->llot_is_composite = false;
322 layout->llot_mirror_count = 1;
323 layout->llot_cur_comp = NULL;
324 INIT_LIST_HEAD(&layout->llot_comp_list);
330 * Allocate and initialize a new plain layout.
332 * \retval valid llapi_layout pointer on success
333 * \retval NULL if memory allocation fails
335 struct llapi_layout *llapi_layout_alloc(void)
337 struct llapi_layout_comp *comp;
338 struct llapi_layout *layout;
340 layout = __llapi_layout_alloc();
344 comp = __llapi_comp_alloc(0);
350 list_add_tail(&comp->llc_list, &layout->llot_comp_list);
351 layout->llot_cur_comp = comp;
357 * Convert the data from a lov_user_md to a newly allocated llapi_layout.
358 * The caller is responsible for freeing the returned pointer.
360 * \param[in] lum LOV user metadata structure to copy data from
361 * \param[in] lum_size size the the lum passed in
363 * \retval valid llapi_layout pointer on success
364 * \retval NULL if memory allocation fails
366 static struct llapi_layout *
367 llapi_layout_from_lum(const struct lov_user_md *lum, int lum_size)
369 struct lov_comp_md_v1 *comp_v1 = NULL;
370 struct lov_comp_md_entry_v1 *ent;
371 struct lov_user_md *v1;
372 struct llapi_layout *layout;
373 struct llapi_layout_comp *comp;
374 int i, ent_count = 0, obj_count;
376 layout = __llapi_layout_alloc();
380 if (lum->lmm_magic == LOV_MAGIC_COMP_V1) {
381 comp_v1 = (struct lov_comp_md_v1 *)lum;
382 ent_count = comp_v1->lcm_entry_count;
383 layout->llot_gen = comp_v1->lcm_layout_gen;
384 layout->llot_is_composite = true;
385 layout->llot_mirror_count = comp_v1->lcm_mirror_count + 1;
386 layout->llot_gen = comp_v1->lcm_layout_gen;
387 layout->llot_flags = comp_v1->lcm_flags;
388 } else if (lum->lmm_magic == LOV_MAGIC_V1 ||
389 lum->lmm_magic == LOV_MAGIC_V3) {
391 layout->llot_is_composite = false;
394 if (ent_count == 0) {
399 v1 = (struct lov_user_md *)lum;
400 for (i = 0; i < ent_count; i++) {
401 if (comp_v1 != NULL) {
402 ent = &comp_v1->lcm_entries[i];
403 v1 = (struct lov_user_md *)((char *)comp_v1 +
405 lum_size = ent->lcme_size;
410 obj_count = llapi_layout_objects_in_lum(v1, lum_size);
411 comp = __llapi_comp_alloc(obj_count);
416 comp->llc_extent.e_start = ent->lcme_extent.e_start;
417 comp->llc_extent.e_end = ent->lcme_extent.e_end;
418 comp->llc_id = ent->lcme_id;
419 comp->llc_flags = ent->lcme_flags;
421 comp->llc_extent.e_start = 0;
422 comp->llc_extent.e_end = LUSTRE_EOF;
427 if (v1->lmm_pattern == LOV_PATTERN_RAID0)
428 comp->llc_pattern = LLAPI_LAYOUT_RAID0;
430 /* Lustre only supports RAID0 for now. */
431 comp->llc_pattern = v1->lmm_pattern;
433 if (v1->lmm_stripe_size == 0)
434 comp->llc_stripe_size = LLAPI_LAYOUT_DEFAULT;
436 comp->llc_stripe_size = v1->lmm_stripe_size;
438 if (v1->lmm_stripe_count == (typeof(v1->lmm_stripe_count))-1)
439 comp->llc_stripe_count = LLAPI_LAYOUT_WIDE;
440 else if (v1->lmm_stripe_count == 0)
441 comp->llc_stripe_count = LLAPI_LAYOUT_DEFAULT;
443 comp->llc_stripe_count = v1->lmm_stripe_count;
445 if (v1->lmm_stripe_offset ==
446 (typeof(v1->lmm_stripe_offset))-1)
447 comp->llc_stripe_offset = LLAPI_LAYOUT_DEFAULT;
449 comp->llc_stripe_offset = v1->lmm_stripe_offset;
451 if (v1->lmm_magic != LOV_USER_MAGIC_V1) {
452 const struct lov_user_md_v3 *lumv3;
453 lumv3 = (struct lov_user_md_v3 *)v1;
454 snprintf(comp->llc_pool_name,
455 sizeof(comp->llc_pool_name),
456 "%s", lumv3->lmm_pool_name);
457 memcpy(comp->llc_objects, lumv3->lmm_objects,
458 obj_count * sizeof(lumv3->lmm_objects[0]));
460 const struct lov_user_md_v1 *lumv1;
461 lumv1 = (struct lov_user_md_v1 *)v1;
462 memcpy(comp->llc_objects, lumv1->lmm_objects,
463 obj_count * sizeof(lumv1->lmm_objects[0]));
467 comp->llc_stripe_offset =
468 comp->llc_objects[0].l_ost_idx;
470 list_add_tail(&comp->llc_list, &layout->llot_comp_list);
471 layout->llot_cur_comp = comp;
476 llapi_layout_free(layout);
481 * Convert the data from a llapi_layout to a newly allocated lov_user_md.
482 * The caller is responsible for freeing the returned pointer.
484 * \param[in] layout the layout to copy from
486 * \retval valid lov_user_md pointer on success
487 * \retval NULL if memory allocation fails or the layout is invalid
489 static struct lov_user_md *
490 llapi_layout_to_lum(const struct llapi_layout *layout)
492 struct llapi_layout_comp *comp;
493 struct lov_comp_md_v1 *comp_v1 = NULL;
494 struct lov_comp_md_entry_v1 *ent;
495 struct lov_user_md *lum = NULL;
500 if (layout == NULL ||
501 list_empty((struct list_head *)&layout->llot_comp_list)) {
506 /* Allocate header of lov_comp_md_v1 if necessary */
507 if (layout->llot_is_composite) {
510 list_for_each_entry(comp, &layout->llot_comp_list, llc_list)
513 lum_size = sizeof(*comp_v1) + comp_cnt * sizeof(*ent);
514 lum = calloc(lum_size, 1);
519 comp_v1 = (struct lov_comp_md_v1 *)lum;
520 comp_v1->lcm_magic = LOV_USER_MAGIC_COMP_V1;
521 comp_v1->lcm_size = lum_size;
522 comp_v1->lcm_layout_gen = 0;
523 comp_v1->lcm_flags = layout->llot_flags;
524 comp_v1->lcm_entry_count = comp_cnt;
525 comp_v1->lcm_mirror_count = layout->llot_mirror_count - 1;
529 list_for_each_entry(comp, &layout->llot_comp_list, llc_list) {
530 struct lov_user_md *blob;
533 int i, obj_count = 0;
534 struct lov_user_ost_data *lmm_objects;
535 uint64_t pattern = comp->llc_pattern;
537 if ((pattern & LLAPI_LAYOUT_SPECIFIC) != 0) {
538 if (comp->llc_objects_count <
539 comp->llc_stripe_count) {
543 magic = LOV_USER_MAGIC_SPECIFIC;
544 obj_count = comp->llc_stripe_count;
545 pattern &= ~LLAPI_LAYOUT_SPECIFIC;
546 } else if (strlen(comp->llc_pool_name) != 0) {
547 magic = LOV_USER_MAGIC_V3;
549 magic = LOV_USER_MAGIC_V1;
551 /* All stripes must be specified when the pattern contains
552 * LLAPI_LAYOUT_SPECIFIC */
553 for (i = 0; i < obj_count; i++) {
554 if (comp->llc_objects[i].l_ost_idx ==
555 LLAPI_LAYOUT_IDX_MAX) {
561 blob_size = lov_user_md_size(obj_count, magic);
562 blob = realloc(lum, lum_size + blob_size);
568 comp_v1 = (struct lov_comp_md_v1 *)lum;
569 blob = (struct lov_user_md *)((char *)lum + lum_size);
570 lum_size += blob_size;
573 blob->lmm_magic = magic;
574 if (pattern == LLAPI_LAYOUT_DEFAULT)
575 blob->lmm_pattern = LOV_PATTERN_RAID0;
576 else if (pattern == LLAPI_LAYOUT_MDT)
577 blob->lmm_pattern = LOV_PATTERN_MDT;
579 blob->lmm_pattern = pattern;
581 if (comp->llc_stripe_size == LLAPI_LAYOUT_DEFAULT)
582 blob->lmm_stripe_size = 0;
584 blob->lmm_stripe_size = comp->llc_stripe_size;
586 if (comp->llc_stripe_count == LLAPI_LAYOUT_DEFAULT)
587 blob->lmm_stripe_count = 0;
588 else if (comp->llc_stripe_count == LLAPI_LAYOUT_WIDE)
589 blob->lmm_stripe_count = LOV_ALL_STRIPES;
591 blob->lmm_stripe_count = comp->llc_stripe_count;
593 if (comp->llc_stripe_offset == LLAPI_LAYOUT_DEFAULT)
594 blob->lmm_stripe_offset = -1;
596 blob->lmm_stripe_offset = comp->llc_stripe_offset;
598 if (magic == LOV_USER_MAGIC_V3 ||
599 magic == LOV_USER_MAGIC_SPECIFIC) {
600 struct lov_user_md_v3 *lumv3 =
601 (struct lov_user_md_v3 *)blob;
603 if (comp->llc_pool_name[0] != '\0') {
604 strncpy(lumv3->lmm_pool_name,
606 sizeof(lumv3->lmm_pool_name));
608 memset(lumv3->lmm_pool_name, 0,
609 sizeof(lumv3->lmm_pool_name));
611 lmm_objects = lumv3->lmm_objects;
613 lmm_objects = blob->lmm_objects;
616 for (i = 0; i < obj_count; i++)
617 lmm_objects[i].l_ost_idx =
618 comp->llc_objects[i].l_ost_idx;
620 if (layout->llot_is_composite) {
621 ent = &comp_v1->lcm_entries[ent_idx];
622 ent->lcme_id = comp->llc_id;
623 ent->lcme_flags = comp->llc_flags;
624 ent->lcme_extent.e_start = comp->llc_extent.e_start;
625 ent->lcme_extent.e_end = comp->llc_extent.e_end;
626 ent->lcme_size = blob_size;
627 ent->lcme_offset = offset;
629 comp_v1->lcm_size += blob_size;
643 * Get the parent directory of a path.
645 * \param[in] path path to get parent of
646 * \param[out] buf buffer in which to store parent path
647 * \param[in] size size in bytes of buffer \a buf
649 static void get_parent_dir(const char *path, char *buf, size_t size)
653 strncpy(buf, path, size);
654 p = strrchr(buf, '/');
658 } else if (size >= 2) {
659 strncpy(buf, ".", 2);
660 buf[size - 1] = '\0';
665 * Substitute unspecified attribute values in \a layout with values
666 * from fs global settings. (lov.stripesize, lov.stripecount,
669 * \param[in] layout layout to inherit values from
670 * \param[in] path file path of the filesystem
672 static void inherit_sys_attributes(struct llapi_layout *layout,
675 struct llapi_layout_comp *comp;
676 unsigned int ssize, scount, soffset;
679 rc = sattr_cache_get_defaults(NULL, path, &scount, &ssize, &soffset);
683 list_for_each_entry(comp, &layout->llot_comp_list, llc_list) {
684 if (comp->llc_pattern == LLAPI_LAYOUT_DEFAULT)
685 comp->llc_pattern = LLAPI_LAYOUT_RAID0;
686 if (comp->llc_stripe_size == LLAPI_LAYOUT_DEFAULT)
687 comp->llc_stripe_size = ssize;
688 if (comp->llc_stripe_count == LLAPI_LAYOUT_DEFAULT)
689 comp->llc_stripe_count = scount;
690 if (comp->llc_stripe_offset == LLAPI_LAYOUT_DEFAULT)
691 comp->llc_stripe_offset = soffset;
696 * Get the current component of \a layout.
698 * \param[in] layout layout to get current component
700 * \retval valid llapi_layout_comp pointer on success
701 * \retval NULL on error
703 static struct llapi_layout_comp *
704 __llapi_layout_cur_comp(const struct llapi_layout *layout)
706 struct llapi_layout_comp *comp;
708 if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
712 if (layout->llot_cur_comp == NULL) {
716 /* Verify data consistency */
717 list_for_each_entry(comp, &layout->llot_comp_list, llc_list)
718 if (comp == layout->llot_cur_comp)
725 * Test if any attributes of \a layout are specified.
727 * \param[in] layout the layout to check
729 * \retval true any attributes are specified
730 * \retval false all attributes are unspecified
732 static bool is_any_specified(const struct llapi_layout *layout)
734 struct llapi_layout_comp *comp;
736 comp = __llapi_layout_cur_comp(layout);
740 if (layout->llot_is_composite || layout->llot_mirror_count != 1)
743 return comp->llc_pattern != LLAPI_LAYOUT_DEFAULT ||
744 comp->llc_stripe_size != LLAPI_LAYOUT_DEFAULT ||
745 comp->llc_stripe_count != LLAPI_LAYOUT_DEFAULT ||
746 comp->llc_stripe_offset != LLAPI_LAYOUT_DEFAULT ||
747 strlen(comp->llc_pool_name);
751 * Check if the given \a lum_size is large enough to hold the required
754 * \param[in] lum the struct lov_user_md to check
755 * \param[in] lum_size the number of bytes in \a lum
757 * \retval true the \a lum_size is too small
758 * \retval false the \a lum_size is large enough
760 static bool llapi_layout_lum_truncated(struct lov_user_md *lum, size_t lum_size)
764 if (lum_size < sizeof(lum->lmm_magic))
767 if (lum->lmm_magic == LOV_MAGIC_V1 ||
768 lum->lmm_magic == __swab32(LOV_MAGIC_V1))
769 magic = LOV_MAGIC_V1;
770 else if (lum->lmm_magic == LOV_MAGIC_V3 ||
771 lum->lmm_magic == __swab32(LOV_MAGIC_V3))
772 magic = LOV_MAGIC_V3;
773 else if (lum->lmm_magic == LOV_MAGIC_COMP_V1 ||
774 lum->lmm_magic == __swab32(LOV_MAGIC_COMP_V1))
775 magic = LOV_MAGIC_COMP_V1;
779 if (magic == LOV_MAGIC_V1 || magic == LOV_MAGIC_V3)
780 return lum_size < lov_user_md_size(0, magic);
782 return lum_size < sizeof(struct lov_comp_md_v1);
785 /* Verify if the objects count in lum is consistent with the
786 * stripe count in lum. It applies to regular file only. */
787 static bool llapi_layout_lum_valid(struct lov_user_md *lum, int lum_size)
789 struct lov_comp_md_v1 *comp_v1 = NULL;
790 int i, ent_count, obj_count;
792 if (lum->lmm_magic == LOV_MAGIC_COMP_V1) {
793 comp_v1 = (struct lov_comp_md_v1 *)lum;
794 ent_count = comp_v1->lcm_entry_count;
795 } else if (lum->lmm_magic == LOV_MAGIC_V1 ||
796 lum->lmm_magic == LOV_MAGIC_V3) {
802 for (i = 0; i < ent_count; i++) {
804 lum = (struct lov_user_md *)((char *)comp_v1 +
805 comp_v1->lcm_entries[i].lcme_offset);
806 lum_size = comp_v1->lcm_entries[i].lcme_size;
808 obj_count = llapi_layout_objects_in_lum(lum, lum_size);
811 if (!(comp_v1->lcm_entries[i].lcme_flags &
812 LCME_FL_INIT) && obj_count != 0)
814 } else if (obj_count != lum->lmm_stripe_count) {
822 * Get the striping layout for the file referenced by file descriptor \a fd.
824 * If the filesystem does not support the "lustre." xattr namespace, the
825 * file must be on a non-Lustre filesystem, so set errno to ENOTTY per
826 * convention. If the file has no "lustre.lov" data, the file will
827 * inherit default values, so return a default layout.
829 * If the kernel gives us back less than the expected amount of data,
830 * we fail with errno set to EINTR.
832 * \param[in] fd open file descriptor
833 * \param[in] flags open file descriptor
835 * \retval valid llapi_layout pointer on success
836 * \retval NULL if an error occurs
838 struct llapi_layout *llapi_layout_get_by_fd(int fd, uint32_t flags)
841 struct lov_user_md *lum;
842 struct llapi_layout *layout = NULL;
846 lum_len = XATTR_SIZE_MAX;
847 lum = malloc(lum_len);
851 bytes_read = fgetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_len);
852 if (bytes_read < 0) {
853 if (errno == EOPNOTSUPP)
855 else if (errno == ENODATA)
856 layout = llapi_layout_alloc();
860 /* Return an error if we got back a partial layout. */
861 if (llapi_layout_lum_truncated(lum, bytes_read)) {
866 llapi_layout_swab_lov_user_md(lum, bytes_read);
868 /* Directories may have a positive non-zero lum->lmm_stripe_count
869 * yet have an empty lum->lmm_objects array. For non-directories the
870 * amount of data returned from the kernel must be consistent
871 * with the stripe count. */
872 if (fstat(fd, &st) < 0)
875 if (!S_ISDIR(st.st_mode) && !llapi_layout_lum_valid(lum, bytes_read)) {
880 layout = llapi_layout_from_lum(lum, bytes_read);
887 * Get the expected striping layout for a file at \a path.
889 * Substitute expected inherited attribute values for unspecified
890 * attributes. Unspecified attributes may belong to directories and
891 * never-written-to files, and indicate that default values will be
892 * assigned when files are created or first written to. A default value
893 * is inherited from the parent directory if the attribute is specified
894 * there, otherwise it is inherited from the filesystem root.
895 * Unspecified attributes normally have the value LLAPI_LAYOUT_DEFAULT.
897 * The complete \a path need not refer to an existing file or directory,
898 * but some leading portion of it must reside within a lustre filesystem.
899 * A use case for this interface would be to obtain the literal striping
900 * values that would be assigned to a new file in a given directory.
902 * \param[in] path path for which to get the expected layout
904 * \retval valid llapi_layout pointer on success
905 * \retval NULL if an error occurs
907 static struct llapi_layout *llapi_layout_expected(const char *path)
909 struct llapi_layout *path_layout = NULL;
910 char donor_path[PATH_MAX];
915 fd = open(path, O_RDONLY);
916 if (fd < 0 && errno != ENOENT)
922 path_layout = llapi_layout_get_by_fd(fd, 0);
928 if (path_layout == NULL) {
929 if (errno != ENODATA && errno != ENOENT)
932 path_layout = llapi_layout_alloc();
933 if (path_layout == NULL)
937 if (is_any_specified(path_layout)) {
938 inherit_sys_attributes(path_layout, path);
942 llapi_layout_free(path_layout);
944 rc = stat(path, &st);
945 if (rc < 0 && errno != ENOENT)
948 /* If path is a not a directory or doesn't exist, inherit layout
949 * from parent directory. */
950 if ((rc == 0 && !S_ISDIR(st.st_mode)) ||
951 (rc < 0 && errno == ENOENT)) {
952 get_parent_dir(path, donor_path, sizeof(donor_path));
953 path_layout = llapi_layout_get_by_path(donor_path, 0);
954 if (path_layout != NULL) {
955 if (is_any_specified(path_layout)) {
956 inherit_sys_attributes(path_layout, donor_path);
959 llapi_layout_free(path_layout);
963 /* Inherit layout from the filesystem root. */
964 rc = llapi_search_mounts(path, 0, donor_path, NULL);
967 path_layout = llapi_layout_get_by_path(donor_path, 0);
968 if (path_layout == NULL)
971 inherit_sys_attributes(path_layout, donor_path);
976 * Get the striping layout for the file at \a path.
978 * If \a flags contains LAYOUT_GET_EXPECTED, substitute
979 * expected inherited attribute values for unspecified attributes. See
980 * llapi_layout_expected().
982 * \param[in] path path for which to get the layout
983 * \param[in] flags flags to control how layout is retrieved
985 * \retval valid llapi_layout pointer on success
986 * \retval NULL if an error occurs
988 struct llapi_layout *llapi_layout_get_by_path(const char *path, uint32_t flags)
990 struct llapi_layout *layout = NULL;
994 if (flags & LAYOUT_GET_EXPECTED)
995 return llapi_layout_expected(path);
997 fd = open(path, O_RDONLY);
1001 layout = llapi_layout_get_by_fd(fd, flags);
1010 * Get the layout for the file with FID \a fidstr in filesystem \a lustre_dir.
1012 * \param[in] lustre_dir path within Lustre filesystem containing \a fid
1013 * \param[in] fid Lustre identifier of file to get layout for
1015 * \retval valid llapi_layout pointer on success
1016 * \retval NULL if an error occurs
1018 struct llapi_layout *llapi_layout_get_by_fid(const char *lustre_dir,
1019 const lustre_fid *fid,
1024 int saved_msg_level = llapi_msg_get_level();
1025 struct llapi_layout *layout = NULL;
1027 /* Prevent llapi internal routines from writing to console
1028 * while executing this function, then restore previous message
1030 llapi_msg_set_level(LLAPI_MSG_OFF);
1031 fd = llapi_open_by_fid(lustre_dir, fid, O_RDONLY);
1032 llapi_msg_set_level(saved_msg_level);
1037 layout = llapi_layout_get_by_fd(fd, flags);
1046 * Get the stripe count of \a layout.
1048 * \param[in] layout layout to get stripe count from
1049 * \param[out] count integer to store stripe count in
1051 * \retval 0 on success
1052 * \retval -1 if arguments are invalid
1054 int llapi_layout_stripe_count_get(const struct llapi_layout *layout,
1057 struct llapi_layout_comp *comp;
1059 comp = __llapi_layout_cur_comp(layout);
1063 if (count == NULL) {
1068 *count = comp->llc_stripe_count;
1074 * The llapi_layout API functions have these extra validity checks since
1075 * they use intuitively named macros to denote special behavior, whereas
1076 * the old API uses 0 and -1.
1079 static bool llapi_layout_stripe_count_is_valid(int64_t stripe_count)
1081 return stripe_count == LLAPI_LAYOUT_DEFAULT ||
1082 stripe_count == LLAPI_LAYOUT_WIDE ||
1083 (stripe_count != 0 && stripe_count != -1 &&
1084 llapi_stripe_count_is_valid(stripe_count));
1087 static bool llapi_layout_stripe_size_is_valid(uint64_t stripe_size)
1089 return stripe_size == LLAPI_LAYOUT_DEFAULT ||
1090 (stripe_size != 0 &&
1091 llapi_stripe_size_is_aligned(stripe_size) &&
1092 !llapi_stripe_size_is_too_big(stripe_size));
1095 static bool llapi_layout_stripe_index_is_valid(int64_t stripe_index)
1097 return stripe_index == LLAPI_LAYOUT_DEFAULT ||
1098 (stripe_index >= 0 &&
1099 llapi_stripe_index_is_valid(stripe_index));
1103 * Set the stripe count of \a layout.
1105 * \param[in] layout layout to set stripe count in
1106 * \param[in] count value to be set
1108 * \retval 0 on success
1109 * \retval -1 if arguments are invalid
1111 int llapi_layout_stripe_count_set(struct llapi_layout *layout,
1114 struct llapi_layout_comp *comp;
1116 comp = __llapi_layout_cur_comp(layout);
1120 if (!llapi_layout_stripe_count_is_valid(count)) {
1125 comp->llc_stripe_count = count;
1131 * Get the stripe size of \a layout.
1133 * \param[in] layout layout to get stripe size from
1134 * \param[out] size integer to store stripe size in
1136 * \retval 0 on success
1137 * \retval -1 if arguments are invalid
1139 int llapi_layout_stripe_size_get(const struct llapi_layout *layout,
1142 struct llapi_layout_comp *comp;
1144 comp = __llapi_layout_cur_comp(layout);
1153 *size = comp->llc_stripe_size;
1159 * Set the stripe size of \a layout.
1161 * \param[in] layout layout to set stripe size in
1162 * \param[in] size value to be set
1164 * \retval 0 on success
1165 * \retval -1 if arguments are invalid
1167 int llapi_layout_stripe_size_set(struct llapi_layout *layout,
1170 struct llapi_layout_comp *comp;
1172 comp = __llapi_layout_cur_comp(layout);
1176 if (!llapi_layout_stripe_size_is_valid(size)) {
1181 comp->llc_stripe_size = size;
1187 * Get the RAID pattern of \a layout.
1189 * \param[in] layout layout to get pattern from
1190 * \param[out] pattern integer to store pattern in
1192 * \retval 0 on success
1193 * \retval -1 if arguments are invalid
1195 int llapi_layout_pattern_get(const struct llapi_layout *layout,
1198 struct llapi_layout_comp *comp;
1200 comp = __llapi_layout_cur_comp(layout);
1204 if (pattern == NULL) {
1209 *pattern = comp->llc_pattern;
1215 * Set the pattern of \a layout.
1217 * \param[in] layout layout to set pattern in
1218 * \param[in] pattern value to be set
1220 * \retval 0 on success
1221 * \retval -1 if arguments are invalid or RAID pattern
1224 int llapi_layout_pattern_set(struct llapi_layout *layout, uint64_t pattern)
1226 struct llapi_layout_comp *comp;
1228 comp = __llapi_layout_cur_comp(layout);
1232 if (pattern != LLAPI_LAYOUT_DEFAULT &&
1233 pattern != LLAPI_LAYOUT_RAID0 && pattern != LLAPI_LAYOUT_MDT) {
1238 comp->llc_pattern = pattern |
1239 (comp->llc_pattern & LLAPI_LAYOUT_SPECIFIC);
1244 static inline int stripe_number_roundup(int stripe_number)
1246 unsigned int round_up = (stripe_number + 8) & ~7;
1247 return round_up > LOV_MAX_STRIPE_COUNT ?
1248 LOV_MAX_STRIPE_COUNT : round_up;
1252 * Set the OST index of stripe number \a stripe_number to \a ost_index.
1254 * If only the starting stripe's OST index is specified, then this can use
1255 * the normal LOV_MAGIC_{V1,V3} layout type. If multiple OST indices are
1256 * given, then allocate an array to hold the list of indices and ensure that
1257 * the LOV_USER_MAGIC_SPECIFIC layout is used when creating the file.
1259 * \param[in] layout layout to set OST index in
1260 * \param[in] stripe_number stripe number to set index for
1261 * \param[in] ost_index the index to set
1263 * \retval 0 on success
1264 * \retval -1 if arguments are invalid or an unsupported stripe number
1265 * was specified, error returned in errno
1267 int llapi_layout_ost_index_set(struct llapi_layout *layout, int stripe_number,
1270 struct llapi_layout_comp *comp;
1272 comp = __llapi_layout_cur_comp(layout);
1276 if (!llapi_layout_stripe_index_is_valid(ost_index)) {
1281 if (stripe_number == 0 && ost_index == LLAPI_LAYOUT_DEFAULT) {
1282 comp->llc_stripe_offset = ost_index;
1283 comp->llc_pattern &= ~LLAPI_LAYOUT_SPECIFIC;
1284 __llapi_comp_objects_realloc(comp, 0);
1285 } else if (stripe_number >= 0 &&
1286 stripe_number < LOV_MAX_STRIPE_COUNT) {
1287 if (ost_index >= LLAPI_LAYOUT_IDX_MAX) {
1292 /* Preallocate a few more stripes to avoid realloc() overhead.*/
1293 if (__llapi_comp_objects_realloc(comp,
1294 stripe_number_roundup(stripe_number)) < 0)
1297 comp->llc_objects[stripe_number].l_ost_idx = ost_index;
1299 if (stripe_number == 0)
1300 comp->llc_stripe_offset = ost_index;
1302 comp->llc_pattern |= LLAPI_LAYOUT_SPECIFIC;
1304 if (comp->llc_stripe_count == LLAPI_LAYOUT_DEFAULT ||
1305 comp->llc_stripe_count <= stripe_number)
1306 comp->llc_stripe_count = stripe_number + 1;
1316 * Get the OST index associated with stripe \a stripe_number.
1318 * Stripes are indexed starting from zero.
1320 * \param[in] layout layout to get index from
1321 * \param[in] stripe_number stripe number to get index for
1322 * \param[out] index integer to store index in
1324 * \retval 0 on success
1325 * \retval -1 if arguments are invalid
1327 int llapi_layout_ost_index_get(const struct llapi_layout *layout,
1328 uint64_t stripe_number, uint64_t *index)
1330 struct llapi_layout_comp *comp;
1332 comp = __llapi_layout_cur_comp(layout);
1336 if (index == NULL) {
1341 if (stripe_number >= comp->llc_stripe_count ||
1342 stripe_number >= comp->llc_objects_count) {
1347 if (comp->llc_stripe_offset == LLAPI_LAYOUT_DEFAULT)
1348 *index = LLAPI_LAYOUT_DEFAULT;
1350 *index = comp->llc_objects[stripe_number].l_ost_idx;
1357 * Get the pool name of layout \a layout.
1359 * \param[in] layout layout to get pool name from
1360 * \param[out] dest buffer to store pool name in
1361 * \param[in] n size in bytes of buffer \a dest
1363 * \retval 0 on success
1364 * \retval -1 if arguments are invalid
1366 int llapi_layout_pool_name_get(const struct llapi_layout *layout, char *dest,
1369 struct llapi_layout_comp *comp;
1371 comp = __llapi_layout_cur_comp(layout);
1380 strncpy(dest, comp->llc_pool_name, n);
1386 * Set the name of the pool of layout \a layout.
1388 * \param[in] layout layout to set pool name in
1389 * \param[in] pool_name pool name to set
1391 * \retval 0 on success
1392 * \retval -1 if arguments are invalid or pool name is too long
1394 int llapi_layout_pool_name_set(struct llapi_layout *layout,
1395 const char *pool_name)
1397 struct llapi_layout_comp *comp;
1400 comp = __llapi_layout_cur_comp(layout);
1404 if (pool_name == NULL) {
1409 /* Strip off any 'fsname.' portion. */
1410 ptr = strchr(pool_name, '.');
1412 pool_name = ptr + 1;
1414 if (strlen(pool_name) > LOV_MAXPOOLNAME) {
1419 strncpy(comp->llc_pool_name, pool_name, sizeof(comp->llc_pool_name));
1425 * Open and possibly create a file with a given \a layout.
1427 * If \a layout is NULL this function acts as a simple wrapper for
1428 * open(). By convention, ENOTTY is returned in errno if \a path
1429 * refers to a non-Lustre file.
1431 * \param[in] path name of the file to open
1432 * \param[in] open_flags open() flags
1433 * \param[in] mode permissions to create new file with
1434 * \param[in] layout layout to create new file with
1436 * \retval non-negative file descriptor on successful open
1437 * \retval -1 if an error occurred
1439 int llapi_layout_file_open(const char *path, int open_flags, mode_t mode,
1440 const struct llapi_layout *layout)
1445 struct lov_user_md *lum;
1449 (layout != NULL && layout->llot_magic != LLAPI_LAYOUT_MAGIC)) {
1454 /* Object creation must be postponed until after layout attributes
1455 * have been applied. */
1456 if (layout != NULL && (open_flags & O_CREAT))
1457 open_flags |= O_LOV_DELAY_CREATE;
1459 fd = open(path, open_flags, mode);
1461 if (layout == NULL || fd < 0)
1464 lum = llapi_layout_to_lum(layout);
1473 if (lum->lmm_magic == LOV_USER_MAGIC_COMP_V1)
1474 lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
1475 else if (lum->lmm_magic == LOV_USER_MAGIC_SPECIFIC)
1476 lum_size = lov_user_md_size(lum->lmm_stripe_count,
1479 lum_size = lov_user_md_size(0, lum->lmm_magic);
1481 rc = fsetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_size, 0);
1490 errno = errno == EOPNOTSUPP ? ENOTTY : errno;
1496 * Create a file with a given \a layout.
1498 * Force O_CREAT and O_EXCL flags on so caller is assured that file was
1499 * created with the given \a layout on successful function return.
1501 * \param[in] path name of the file to open
1502 * \param[in] open_flags open() flags
1503 * \param[in] mode permissions to create new file with
1504 * \param[in] layout layout to create new file with
1506 * \retval non-negative file descriptor on successful open
1507 * \retval -1 if an error occurred
1509 int llapi_layout_file_create(const char *path, int open_flags, int mode,
1510 const struct llapi_layout *layout)
1512 return llapi_layout_file_open(path, open_flags|O_CREAT|O_EXCL, mode,
1516 int llapi_layout_flags_get(struct llapi_layout *layout, uint32_t *flags)
1518 if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1523 *flags = layout->llot_flags;
1528 * Set flags to the header of a component layout.
1530 int llapi_layout_flags_set(struct llapi_layout *layout, uint32_t flags)
1532 if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1537 layout->llot_flags = flags;
1542 * llapi_layout_mirror_count_is_valid() - Check the validity of mirror count.
1543 * @count: Mirror count value to be checked.
1545 * This function checks the validity of mirror count.
1547 * Return: true on success or false on failure.
1549 static bool llapi_layout_mirror_count_is_valid(uint16_t count)
1551 return count >= 0 && count <= LUSTRE_MIRROR_COUNT_MAX;
1555 * llapi_layout_mirror_count_get() - Get mirror count from the header of
1557 * @layout: Layout to get mirror count from.
1558 * @count: Returned mirror count value.
1560 * This function gets mirror count from the header of a layout.
1562 * Return: 0 on success or -1 on failure.
1564 int llapi_layout_mirror_count_get(struct llapi_layout *layout,
1567 if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1572 *count = layout->llot_mirror_count;
1577 * llapi_layout_mirror_count_set() - Set mirror count to the header of a layout.
1578 * @layout: Layout to set mirror count in.
1579 * @count: Mirror count value to be set.
1581 * This function sets mirror count to the header of a layout.
1583 * Return: 0 on success or -1 on failure.
1585 int llapi_layout_mirror_count_set(struct llapi_layout *layout,
1588 if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1593 if (!llapi_layout_mirror_count_is_valid(count)) {
1598 layout->llot_mirror_count = count;
1603 * Fetch the start and end offset of the current layout component.
1605 * \param[in] layout the layout component
1606 * \param[out] start extent start, inclusive
1607 * \param[out] end extent end, exclusive
1609 * \retval 0 on success
1610 * \retval <0 if error occurs
1612 int llapi_layout_comp_extent_get(const struct llapi_layout *layout,
1613 uint64_t *start, uint64_t *end)
1615 struct llapi_layout_comp *comp;
1617 comp = __llapi_layout_cur_comp(layout);
1621 if (start == NULL || end == NULL) {
1626 *start = comp->llc_extent.e_start;
1627 *end = comp->llc_extent.e_end;
1633 * Set the layout extent of a layout.
1635 * \param[in] layout the layout to be set
1636 * \param[in] start extent start, inclusive
1637 * \param[in] end extent end, exclusive
1639 * \retval 0 on success
1640 * \retval <0 if error occurs
1642 int llapi_layout_comp_extent_set(struct llapi_layout *layout,
1643 uint64_t start, uint64_t end)
1645 struct llapi_layout_comp *prev, *next, *comp;
1647 comp = __llapi_layout_cur_comp(layout);
1657 * We need to make sure the extent to be set is valid: the new
1658 * extent must be adjacent with the prev & next component.
1660 if (comp->llc_list.prev != &layout->llot_comp_list) {
1661 prev = list_entry(comp->llc_list.prev, typeof(*prev),
1663 if (start != prev->llc_extent.e_end) {
1669 if (comp->llc_list.next != &layout->llot_comp_list) {
1670 next = list_entry(comp->llc_list.next, typeof(*next),
1672 if (end != next->llc_extent.e_start) {
1678 comp->llc_extent.e_start = start;
1679 comp->llc_extent.e_end = end;
1680 layout->llot_is_composite = true;
1686 * Gets the attribute flags of the current component.
1688 * \param[in] layout the layout component
1689 * \param[out] flags stored the returned component flags
1691 * \retval 0 on success
1692 * \retval <0 if error occurs
1694 int llapi_layout_comp_flags_get(const struct llapi_layout *layout,
1697 struct llapi_layout_comp *comp;
1699 comp = __llapi_layout_cur_comp(layout);
1703 if (flags == NULL) {
1708 *flags = comp->llc_flags;
1714 * Sets the specified flags of the current component leaving other flags as-is.
1716 * \param[in] layout the layout component
1717 * \param[in] flags component flags to be set
1719 * \retval 0 on success
1720 * \retval <0 if error occurs
1722 int llapi_layout_comp_flags_set(struct llapi_layout *layout, uint32_t flags)
1724 struct llapi_layout_comp *comp;
1726 comp = __llapi_layout_cur_comp(layout);
1730 comp->llc_flags |= flags;
1736 * Clears the flags specified in the flags leaving other flags as-is.
1738 * \param[in] layout the layout component
1739 * \param[in] flags component flags to be cleared
1741 * \retval 0 on success
1742 * \retval <0 if error occurs
1744 int llapi_layout_comp_flags_clear(struct llapi_layout *layout,
1747 struct llapi_layout_comp *comp;
1749 comp = __llapi_layout_cur_comp(layout);
1753 comp->llc_flags &= ~flags;
1759 * Fetches the file-unique component ID of the current layout component.
1761 * \param[in] layout the layout component
1762 * \param[out] id stored the returned component ID
1764 * \retval 0 on success
1765 * \retval <0 if error occurs
1767 int llapi_layout_comp_id_get(const struct llapi_layout *layout, uint32_t *id)
1769 struct llapi_layout_comp *comp;
1771 comp = __llapi_layout_cur_comp(layout);
1785 * Return the mirror id of the current layout component.
1787 * \param[in] layout the layout component
1788 * \param[out] id stored the returned mirror ID
1790 * \retval 0 on success
1791 * \retval <0 if error occurs
1793 int llapi_layout_mirror_id_get(const struct llapi_layout *layout, uint32_t *id)
1795 struct llapi_layout_comp *comp;
1797 comp = __llapi_layout_cur_comp(layout);
1806 *id = mirror_id_of(comp->llc_id);
1812 * Adds a component to \a layout, the new component will be added to
1813 * the tail of components list and it'll inherit attributes of existing
1814 * ones. The \a layout will change it's current component pointer to
1815 * the newly added component, and it'll be turned into a composite
1816 * layout if it was not before the adding.
1818 * \param[in] layout existing composite or plain layout
1820 * \retval 0 on success
1821 * \retval <0 if error occurs
1823 int llapi_layout_comp_add(struct llapi_layout *layout)
1825 struct llapi_layout_comp *last, *comp, *new;
1827 comp = __llapi_layout_cur_comp(layout);
1831 new = __llapi_comp_alloc(0);
1835 last = list_entry(layout->llot_comp_list.prev, typeof(*last),
1838 if (new->llc_extent.e_end <= last->llc_extent.e_end) {
1839 __llapi_comp_free(new);
1843 new->llc_extent.e_start = last->llc_extent.e_end;
1845 list_add_tail(&new->llc_list, &layout->llot_comp_list);
1846 layout->llot_cur_comp = new;
1847 layout->llot_is_composite = true;
1853 * Deletes current component from the composite layout. The component
1854 * to be deleted must be the tail of components list, and it can't be
1855 * the only component in the layout.
1857 * \param[in] layout composite layout
1859 * \retval 0 on success
1860 * \retval <0 if error occurs
1862 int llapi_layout_comp_del(struct llapi_layout *layout)
1864 struct llapi_layout_comp *comp;
1866 comp = __llapi_layout_cur_comp(layout);
1870 if (!layout->llot_is_composite) {
1875 /* It must be the tail of the list (for PFL, can be relaxed
1876 * once we get mirrored components) */
1877 if (comp->llc_list.next != &layout->llot_comp_list) {
1881 /* It can't be the only one on the list */
1882 if (comp->llc_list.prev == &layout->llot_comp_list) {
1887 layout->llot_cur_comp =
1888 list_entry(comp->llc_list.prev, typeof(*comp), llc_list);
1889 list_del_init(&comp->llc_list);
1890 __llapi_comp_free(comp);
1896 * Move the current component pointer to the component with
1897 * specified component ID.
1899 * \param[in] layout composite layout
1900 * \param[in] id component ID
1902 * \retval =0 : moved successfully
1903 * \retval <0 if error occurs
1905 int llapi_layout_comp_use_id(struct llapi_layout *layout, uint32_t comp_id)
1907 struct llapi_layout_comp *comp;
1909 comp = __llapi_layout_cur_comp(layout);
1911 return -1; /* use previously set errno */
1913 if (!layout->llot_is_composite) {
1918 if (comp_id == LCME_ID_INVAL) {
1923 list_for_each_entry(comp, &layout->llot_comp_list, llc_list) {
1924 if (comp->llc_id == comp_id) {
1925 layout->llot_cur_comp = comp;
1934 * Move the current component pointer to a specified position.
1936 * \param[in] layout composite layout
1937 * \param[in] pos the position to be moved, it can be:
1938 * LLAPI_LAYOUT_COMP_USE_FIRST: use first component
1939 * LLAPI_LAYOUT_COMP_USE_LAST: use last component
1940 * LLAPI_LAYOUT_COMP_USE_NEXT: use component after current
1941 * LLAPI_LAYOUT_COMP_USE_PREV: use component before current
1943 * \retval =0 : moved successfully
1944 * \retval =1 : at last component with NEXT, at first component with PREV
1945 * \retval <0 if error occurs
1947 int llapi_layout_comp_use(struct llapi_layout *layout,
1948 enum llapi_layout_comp_use pos)
1950 struct llapi_layout_comp *comp, *head, *tail;
1952 comp = __llapi_layout_cur_comp(layout);
1956 if (!layout->llot_is_composite) {
1957 if (pos == LLAPI_LAYOUT_COMP_USE_FIRST ||
1958 pos == LLAPI_LAYOUT_COMP_USE_LAST)
1964 head = list_entry(layout->llot_comp_list.next, typeof(*head), llc_list);
1965 tail = list_entry(layout->llot_comp_list.prev, typeof(*tail), llc_list);
1967 case LLAPI_LAYOUT_COMP_USE_FIRST:
1968 layout->llot_cur_comp = head;
1970 case LLAPI_LAYOUT_COMP_USE_NEXT:
1975 layout->llot_cur_comp = list_entry(comp->llc_list.next,
1976 typeof(*comp), llc_list);
1978 case LLAPI_LAYOUT_COMP_USE_LAST:
1979 layout->llot_cur_comp = tail;
1981 case LLAPI_LAYOUT_COMP_USE_PREV:
1986 layout->llot_cur_comp = list_entry(comp->llc_list.prev,
1987 typeof(*comp), llc_list);
1998 * Add layout component(s) to an existing file.
2000 * \param[in] path The path name of the file
2001 * \param[in] layout The layout component(s) to be added
2003 int llapi_layout_file_comp_add(const char *path,
2004 const struct llapi_layout *layout)
2006 int rc, fd, lum_size, tmp_errno = 0;
2007 struct lov_user_md *lum;
2009 if (path == NULL || layout == NULL ||
2010 layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
2015 lum = llapi_layout_to_lum(layout);
2019 if (lum->lmm_magic != LOV_USER_MAGIC_COMP_V1) {
2024 lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
2026 fd = open(path, O_RDWR);
2033 rc = fsetxattr(fd, XATTR_LUSTRE_LOV".add", lum, lum_size, 0);
2048 * Delete component(s) by the specified component id or component flags
2049 * from an existing file.
2051 * \param[in] path path name of the file
2052 * \param[in] id unique component ID
2053 * \param[in] flags flags: LCME_FL_* or;
2054 * negative flags: (LCME_FL_NEG|LCME_FL_*)
2056 int llapi_layout_file_comp_del(const char *path, uint32_t id, uint32_t flags)
2058 int rc, fd, lum_size;
2059 struct llapi_layout *layout;
2060 struct llapi_layout_comp *comp;
2061 struct lov_user_md *lum;
2063 if (path == NULL || id > LCME_ID_MAX || (flags & ~LCME_KNOWN_FLAGS)) {
2068 /* Can only specify ID or flags, not both. */
2069 if (id != 0 && flags != 0) {
2074 layout = llapi_layout_alloc();
2078 llapi_layout_comp_extent_set(layout, 0, LUSTRE_EOF);
2079 comp = __llapi_layout_cur_comp(layout);
2081 llapi_layout_free(layout);
2086 comp->llc_flags = flags;
2088 lum = llapi_layout_to_lum(layout);
2090 llapi_layout_free(layout);
2093 lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
2095 fd = open(path, O_RDWR);
2101 rc = fsetxattr(fd, XATTR_LUSTRE_LOV".del", lum, lum_size, 0);
2103 int tmp_errno = errno;
2112 llapi_layout_free(layout);
2117 * Change flags or other parameters of the component(s) by component ID of an
2118 * existing file. The component to be modified is specified by the
2119 * comp->lcme_id value, which must be an unique component ID. The new
2120 * attributes are passed in by @comp and @valid is used to specify which
2121 * attributes in the component are going to be changed.
2123 int llapi_layout_file_comp_set(const char *path,
2124 const struct llapi_layout *comp,
2132 * Check if the file layout is composite.
2134 * \param[in] layout the file layout to check
2136 * \retval true composite
2137 * \retval false not composite
2139 bool llapi_layout_is_composite(struct llapi_layout *layout)
2141 return layout->llot_is_composite;
2145 * llapi_layout_merge() - Merge a composite layout into another one.
2146 * @dst_layout: Destination composite layout.
2147 * @src_layout: Source composite layout.
2149 * This function copies all of the components from @src_layout and
2150 * appends them to @dst_layout.
2152 * Return: 0 on success or -1 on failure.
2154 int llapi_layout_merge(struct llapi_layout **dst_layout,
2155 const struct llapi_layout *src_layout)
2157 struct llapi_layout *new_layout = *dst_layout;
2158 struct llapi_layout_comp *new = NULL;
2159 struct llapi_layout_comp *comp = NULL;
2162 if (src_layout == NULL ||
2163 list_empty((struct list_head *)&src_layout->llot_comp_list))
2166 if (new_layout == NULL) {
2167 new_layout = __llapi_layout_alloc();
2168 if (new_layout == NULL) {
2174 list_for_each_entry(comp, &src_layout->llot_comp_list, llc_list) {
2175 new = __llapi_comp_alloc(0);
2181 new->llc_pattern = comp->llc_pattern;
2182 new->llc_stripe_size = comp->llc_stripe_size;
2183 new->llc_stripe_count = comp->llc_stripe_count;
2184 new->llc_stripe_offset = comp->llc_stripe_offset;
2186 if (comp->llc_pool_name[0] != '\0')
2187 strncpy(new->llc_pool_name, comp->llc_pool_name,
2188 sizeof(new->llc_pool_name));
2190 for (i = 0; i < comp->llc_objects_count; i++) {
2191 if (__llapi_comp_objects_realloc(new,
2192 stripe_number_roundup(i)) < 0) {
2194 __llapi_comp_free(new);
2197 new->llc_objects[i].l_ost_idx = \
2198 comp->llc_objects[i].l_ost_idx;
2201 new->llc_objects_count = comp->llc_objects_count;
2202 new->llc_extent.e_start = comp->llc_extent.e_start;
2203 new->llc_extent.e_end = comp->llc_extent.e_end;
2204 new->llc_id = comp->llc_id;
2205 new->llc_flags = comp->llc_flags;
2207 list_add_tail(&new->llc_list, &new_layout->llot_comp_list);
2208 new_layout->llot_cur_comp = new;
2210 new_layout->llot_is_composite = true;
2212 *dst_layout = new_layout;
2215 llapi_layout_free(new_layout);
2220 * Find all stale components.
2222 * \param[in] layout component layout list.
2223 * \param[out] comp array of stale component info.
2224 * \param[in] comp_size array size of @comp.
2225 * \param[in] mirror_ids array of mirror id that only components
2226 * belonging to these mirror will be collected.
2227 * \param[in] ids_nr number of mirror ids array.
2229 * \retval number of component info collected on sucess or
2230 * an error code on failure.
2232 int llapi_mirror_find_stale(struct llapi_layout *layout,
2233 struct llapi_resync_comp *comp, size_t comp_size,
2234 __u16 *mirror_ids, int ids_nr)
2239 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
2241 fprintf(stderr, "%s: move to the first layout component: %s.\n",
2242 __func__, strerror(errno));
2250 uint64_t start, end;
2252 rc = llapi_layout_comp_flags_get(layout, &flags);
2254 fprintf(stderr, "llapi_layout_comp_flags_get: %s.\n",
2259 if (!(flags & LCME_FL_STALE))
2262 rc = llapi_layout_mirror_id_get(layout, &mirror_id);
2264 fprintf(stderr, "llapi_layout_mirror_id_get: %s.\n",
2269 /* the caller only wants stale components from specific
2274 for (j = 0; j < ids_nr; j++) {
2275 if (mirror_ids[j] == mirror_id)
2279 /* not in the specified mirror */
2284 rc = llapi_layout_comp_id_get(layout, &id);
2286 fprintf(stderr, "llapi_layout_comp_id_get: %s.\n",
2291 rc = llapi_layout_comp_extent_get(layout, &start, &end);
2293 fprintf(stderr, "llapi_layout_comp_extent_get: %s.\n",
2298 /* pack this component into @comp array */
2299 comp[idx].lrc_id = id;
2300 comp[idx].lrc_mirror_id = mirror_id;
2301 comp[idx].lrc_start = start;
2302 comp[idx].lrc_end = end;
2305 if (idx >= comp_size) {
2306 fprintf(stderr, "%s: resync_comp array too small.\n",
2313 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
2315 fprintf(stderr, "%s: move to the next layout "
2316 "component: %s.\n", __func__, strerror(errno));
2322 return rc < 0 ? rc : idx;
2325 /* locate @layout to a valid component covering file [file_start, file_end) */
2326 static uint32_t llapi_mirror_find(struct llapi_layout *layout,
2327 uint64_t file_start, uint64_t file_end,
2330 uint32_t mirror_id = 0;
2333 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
2339 uint64_t start, end;
2340 uint32_t flags, id, rid;
2342 rc = llapi_layout_comp_flags_get(layout, &flags);
2346 if (flags & LCME_FL_STALE)
2349 rc = llapi_layout_mirror_id_get(layout, &rid);
2353 rc = llapi_layout_comp_id_get(layout, &id);
2357 rc = llapi_layout_comp_extent_get(layout, &start, &end);
2361 if (file_start >= start && file_start < end) {
2364 else if (mirror_id != rid || *endp != start)
2367 file_start = *endp = end;
2368 if (end >= file_end)
2373 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
2381 ssize_t llapi_mirror_resync_one(int fd, struct llapi_layout *layout,
2382 uint32_t dst, uint64_t start, uint64_t end)
2384 uint64_t mirror_end = 0;
2388 if (end == OBD_OBJECT_EOF)
2389 count = OBD_OBJECT_EOF;
2391 count = end - start;
2398 src = llapi_mirror_find(layout, start, end, &mirror_end);
2400 fprintf(stderr, "llapi_mirror_find cannot find "
2401 "component covering %lu.\n", start);
2405 if (mirror_end == OBD_OBJECT_EOF)
2408 to_copy = MIN(count, mirror_end - start);
2410 copied = llapi_mirror_copy(fd, src, dst, start, to_copy);
2412 fprintf(stderr, "llapi_mirror_copy returned %zd.\n",
2418 if (copied < to_copy) /* end of file */
2421 if (count != OBD_OBJECT_EOF)