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, 2017, Intel Corporation.
28 * Author: Ned Bass <bass6@llnl.gov>
38 #include <sys/xattr.h>
39 #include <sys/param.h>
41 #include <libcfs/util/list.h>
42 #include <lustre/lustreapi.h>
43 #include "lustreapi_internal.h"
46 * Layout component, which contains all attributes of a plain
49 struct llapi_layout_comp {
51 uint64_t llc_stripe_size;
52 uint64_t llc_stripe_count;
53 uint64_t llc_stripe_offset;
54 /* Add 1 so user always gets back a null terminated string. */
55 char llc_pool_name[LOV_MAXPOOLNAME + 1];
56 /** Number of objects in llc_objects array if was initialized. */
57 uint32_t llc_objects_count;
58 struct lov_user_ost_data_v1 *llc_objects;
59 /* fields used only for composite layouts */
60 struct lu_extent llc_extent; /* [start, end) of component */
61 uint32_t llc_id; /* unique ID of component */
62 uint32_t llc_flags; /* LCME_FL_* flags */
63 struct list_head llc_list; /* linked to the llapi_layout
68 * An Opaque data type abstracting the layout of a Lustre file.
71 uint32_t llot_magic; /* LLAPI_LAYOUT_MAGIC */
74 bool llot_is_composite;
75 uint16_t llot_mirror_count;
76 /* Cursor pointing to one of the components in llot_comp_list */
77 struct llapi_layout_comp *llot_cur_comp;
78 struct list_head llot_comp_list;
82 * Compute the number of elements in the lmm_objects array of \a lum
83 * with size \a lum_size.
85 * \param[in] lum the struct lov_user_md to check
86 * \param[in] lum_size the number of bytes in \a lum
88 * \retval number of elements in array lum->lmm_objects
90 static int llapi_layout_objects_in_lum(struct lov_user_md *lum, size_t lum_size)
95 if (lum_size < lov_user_md_size(0, LOV_MAGIC_V1))
98 if (lum->lmm_magic == __swab32(LOV_MAGIC_V1) ||
99 lum->lmm_magic == __swab32(LOV_MAGIC_V3))
100 magic = __swab32(lum->lmm_magic);
102 magic = lum->lmm_magic;
104 base_size = lov_user_md_size(0, magic);
106 if (lum_size <= base_size)
109 return (lum_size - base_size) / sizeof(lum->lmm_objects[0]);
113 * Byte-swap the fields of struct lov_user_md.
115 * XXX Rather than duplicating swabbing code here, we should eventually
116 * refactor the needed functions in lustre/ptlrpc/pack_generic.c
117 * into a library that can be shared between kernel and user code.
120 llapi_layout_swab_lov_user_md(struct lov_user_md *lum, int lum_size)
122 int i, j, ent_count, obj_count;
123 struct lov_comp_md_v1 *comp_v1 = NULL;
124 struct lov_comp_md_entry_v1 *ent;
125 struct lov_user_ost_data *lod;
127 if (lum->lmm_magic != __swab32(LOV_MAGIC_V1) &&
128 lum->lmm_magic != __swab32(LOV_MAGIC_V3) &&
129 lum->lmm_magic != __swab32(LOV_MAGIC_COMP_V1))
132 if (lum->lmm_magic == __swab32(LOV_MAGIC_COMP_V1))
133 comp_v1 = (struct lov_comp_md_v1 *)lum;
135 if (comp_v1 != NULL) {
136 __swab32s(&comp_v1->lcm_magic);
137 __swab32s(&comp_v1->lcm_size);
138 __swab32s(&comp_v1->lcm_layout_gen);
139 __swab16s(&comp_v1->lcm_flags);
140 __swab16s(&comp_v1->lcm_entry_count);
141 ent_count = comp_v1->lcm_entry_count;
146 for (i = 0; i < ent_count; i++) {
147 if (comp_v1 != NULL) {
148 ent = &comp_v1->lcm_entries[i];
149 __swab32s(&ent->lcme_id);
150 __swab32s(&ent->lcme_flags);
151 __swab64s(&ent->lcme_extent.e_start);
152 __swab64s(&ent->lcme_extent.e_end);
153 __swab32s(&ent->lcme_offset);
154 __swab32s(&ent->lcme_size);
156 lum = (struct lov_user_md *)((char *)comp_v1 +
158 lum_size = ent->lcme_size;
160 obj_count = llapi_layout_objects_in_lum(lum, lum_size);
162 __swab32s(&lum->lmm_magic);
163 __swab32s(&lum->lmm_pattern);
164 __swab32s(&lum->lmm_stripe_size);
165 __swab16s(&lum->lmm_stripe_count);
166 __swab16s(&lum->lmm_stripe_offset);
168 if (lum->lmm_magic != LOV_MAGIC_V1) {
169 struct lov_user_md_v3 *v3;
170 v3 = (struct lov_user_md_v3 *)lum;
171 lod = v3->lmm_objects;
173 lod = lum->lmm_objects;
176 for (j = 0; j < obj_count; j++)
177 __swab32s(&lod[j].l_ost_idx);
182 * (Re-)allocate llc_objects[] to \a num_stripes stripes.
184 * Copy over existing llc_objects[], if any, to the new llc_objects[].
186 * \param[in] layout existing layout to be modified
187 * \param[in] num_stripes number of stripes in new layout
189 * \retval 0 if the objects are re-allocated successfully
190 * \retval -1 on error with errno set
192 static int __llapi_comp_objects_realloc(struct llapi_layout_comp *comp,
193 unsigned int new_stripes)
195 struct lov_user_ost_data_v1 *new_objects;
198 if (new_stripes > LOV_MAX_STRIPE_COUNT) {
203 if (new_stripes == comp->llc_objects_count)
206 if (new_stripes != 0 && new_stripes <= comp->llc_objects_count)
209 new_objects = realloc(comp->llc_objects,
210 sizeof(*new_objects) * new_stripes);
211 if (new_objects == NULL && new_stripes != 0) {
216 for (i = comp->llc_objects_count; i < new_stripes; i++)
217 new_objects[i].l_ost_idx = LLAPI_LAYOUT_IDX_MAX;
219 comp->llc_objects = new_objects;
220 comp->llc_objects_count = new_stripes;
226 * Allocate storage for a llapi_layout_comp with \a num_stripes stripes.
228 * \param[in] num_stripes number of stripes in new layout
230 * \retval valid pointer if allocation succeeds
231 * \retval NULL if allocation fails
233 static struct llapi_layout_comp *__llapi_comp_alloc(unsigned int num_stripes)
235 struct llapi_layout_comp *comp;
237 if (num_stripes > LOV_MAX_STRIPE_COUNT) {
242 comp = calloc(1, sizeof(*comp));
248 comp->llc_objects = NULL;
249 comp->llc_objects_count = 0;
251 if (__llapi_comp_objects_realloc(comp, num_stripes) < 0) {
257 comp->llc_pattern = LLAPI_LAYOUT_DEFAULT;
258 comp->llc_stripe_size = LLAPI_LAYOUT_DEFAULT;
259 comp->llc_stripe_count = LLAPI_LAYOUT_DEFAULT;
260 comp->llc_stripe_offset = LLAPI_LAYOUT_DEFAULT;
261 comp->llc_pool_name[0] = '\0';
262 comp->llc_extent.e_start = 0;
263 comp->llc_extent.e_end = LUSTRE_EOF;
266 INIT_LIST_HEAD(&comp->llc_list);
272 * Free memory allocated for \a comp
274 * \param[in] comp previously allocated by __llapi_comp_alloc()
276 static void __llapi_comp_free(struct llapi_layout_comp *comp)
278 if (comp->llc_objects != NULL)
279 free(comp->llc_objects);
284 * Free memory allocated for \a layout.
286 * \param[in] layout previously allocated by llapi_layout_alloc()
288 void llapi_layout_free(struct llapi_layout *layout)
290 struct llapi_layout_comp *comp, *n;
295 list_for_each_entry_safe(comp, n, &layout->llot_comp_list, llc_list) {
296 list_del_init(&comp->llc_list);
297 __llapi_comp_free(comp);
303 * Allocate and initialize a llapi_layout structure.
305 * \retval valid llapi_layout pointer on success
306 * \retval NULL if memory allocation fails
308 static struct llapi_layout *__llapi_layout_alloc(void)
310 struct llapi_layout *layout;
312 layout = calloc(1, sizeof(*layout));
313 if (layout == NULL) {
319 layout->llot_magic = LLAPI_LAYOUT_MAGIC;
320 layout->llot_gen = 0;
321 layout->llot_flags = 0;
322 layout->llot_is_composite = false;
323 layout->llot_mirror_count = 1;
324 layout->llot_cur_comp = NULL;
325 INIT_LIST_HEAD(&layout->llot_comp_list);
331 * Allocate and initialize a new plain layout.
333 * \retval valid llapi_layout pointer on success
334 * \retval NULL if memory allocation fails
336 struct llapi_layout *llapi_layout_alloc(void)
338 struct llapi_layout_comp *comp;
339 struct llapi_layout *layout;
341 layout = __llapi_layout_alloc();
345 comp = __llapi_comp_alloc(0);
351 list_add_tail(&comp->llc_list, &layout->llot_comp_list);
352 layout->llot_cur_comp = comp;
358 * Convert the data from a lov_user_md to a newly allocated llapi_layout.
359 * The caller is responsible for freeing the returned pointer.
361 * \param[in] lum LOV user metadata structure to copy data from
362 * \param[in] lum_size size the the lum passed in
364 * \retval valid llapi_layout pointer on success
365 * \retval NULL if memory allocation fails
367 static struct llapi_layout *
368 llapi_layout_from_lum(const struct lov_user_md *lum, int lum_size)
370 struct lov_comp_md_v1 *comp_v1 = NULL;
371 struct lov_comp_md_entry_v1 *ent;
372 struct lov_user_md *v1;
373 struct llapi_layout *layout;
374 struct llapi_layout_comp *comp;
375 int i, ent_count = 0, obj_count;
377 layout = __llapi_layout_alloc();
381 if (lum->lmm_magic == LOV_MAGIC_COMP_V1) {
382 comp_v1 = (struct lov_comp_md_v1 *)lum;
383 ent_count = comp_v1->lcm_entry_count;
384 layout->llot_gen = comp_v1->lcm_layout_gen;
385 layout->llot_is_composite = true;
386 layout->llot_mirror_count = comp_v1->lcm_mirror_count + 1;
387 layout->llot_gen = comp_v1->lcm_layout_gen;
388 layout->llot_flags = comp_v1->lcm_flags;
389 } else if (lum->lmm_magic == LOV_MAGIC_V1 ||
390 lum->lmm_magic == LOV_MAGIC_V3) {
392 layout->llot_is_composite = false;
395 if (ent_count == 0) {
400 v1 = (struct lov_user_md *)lum;
401 for (i = 0; i < ent_count; i++) {
402 if (comp_v1 != NULL) {
403 ent = &comp_v1->lcm_entries[i];
404 v1 = (struct lov_user_md *)((char *)comp_v1 +
406 lum_size = ent->lcme_size;
411 obj_count = llapi_layout_objects_in_lum(v1, lum_size);
412 comp = __llapi_comp_alloc(obj_count);
417 comp->llc_extent.e_start = ent->lcme_extent.e_start;
418 comp->llc_extent.e_end = ent->lcme_extent.e_end;
419 comp->llc_id = ent->lcme_id;
420 comp->llc_flags = ent->lcme_flags;
422 comp->llc_extent.e_start = 0;
423 comp->llc_extent.e_end = LUSTRE_EOF;
428 if (v1->lmm_pattern == LOV_PATTERN_RAID0)
429 comp->llc_pattern = LLAPI_LAYOUT_RAID0;
431 /* Lustre only supports RAID0 for now. */
432 comp->llc_pattern = v1->lmm_pattern;
434 if (v1->lmm_stripe_size == 0)
435 comp->llc_stripe_size = LLAPI_LAYOUT_DEFAULT;
437 comp->llc_stripe_size = v1->lmm_stripe_size;
439 if (v1->lmm_stripe_count == (typeof(v1->lmm_stripe_count))-1)
440 comp->llc_stripe_count = LLAPI_LAYOUT_WIDE;
441 else if (v1->lmm_stripe_count == 0)
442 comp->llc_stripe_count = LLAPI_LAYOUT_DEFAULT;
444 comp->llc_stripe_count = v1->lmm_stripe_count;
446 if (v1->lmm_stripe_offset ==
447 (typeof(v1->lmm_stripe_offset))-1)
448 comp->llc_stripe_offset = LLAPI_LAYOUT_DEFAULT;
450 comp->llc_stripe_offset = v1->lmm_stripe_offset;
452 if (v1->lmm_magic != LOV_USER_MAGIC_V1) {
453 const struct lov_user_md_v3 *lumv3;
454 lumv3 = (struct lov_user_md_v3 *)v1;
455 snprintf(comp->llc_pool_name,
456 sizeof(comp->llc_pool_name),
457 "%s", lumv3->lmm_pool_name);
458 memcpy(comp->llc_objects, lumv3->lmm_objects,
459 obj_count * sizeof(lumv3->lmm_objects[0]));
461 const struct lov_user_md_v1 *lumv1;
462 lumv1 = (struct lov_user_md_v1 *)v1;
463 memcpy(comp->llc_objects, lumv1->lmm_objects,
464 obj_count * sizeof(lumv1->lmm_objects[0]));
468 comp->llc_stripe_offset =
469 comp->llc_objects[0].l_ost_idx;
471 list_add_tail(&comp->llc_list, &layout->llot_comp_list);
472 layout->llot_cur_comp = comp;
477 llapi_layout_free(layout);
482 * Convert the data from a llapi_layout to a newly allocated lov_user_md.
483 * The caller is responsible for freeing the returned pointer.
485 * \param[in] layout the layout to copy from
487 * \retval valid lov_user_md pointer on success
488 * \retval NULL if memory allocation fails or the layout is invalid
490 static struct lov_user_md *
491 llapi_layout_to_lum(const struct llapi_layout *layout)
493 struct llapi_layout_comp *comp;
494 struct lov_comp_md_v1 *comp_v1 = NULL;
495 struct lov_comp_md_entry_v1 *ent;
496 struct lov_user_md *lum = NULL;
501 if (layout == NULL ||
502 list_empty((struct list_head *)&layout->llot_comp_list)) {
507 /* Allocate header of lov_comp_md_v1 if necessary */
508 if (layout->llot_is_composite) {
511 list_for_each_entry(comp, &layout->llot_comp_list, llc_list)
514 lum_size = sizeof(*comp_v1) + comp_cnt * sizeof(*ent);
515 lum = calloc(lum_size, 1);
520 comp_v1 = (struct lov_comp_md_v1 *)lum;
521 comp_v1->lcm_magic = LOV_USER_MAGIC_COMP_V1;
522 comp_v1->lcm_size = lum_size;
523 comp_v1->lcm_layout_gen = 0;
524 comp_v1->lcm_flags = layout->llot_flags;
525 comp_v1->lcm_entry_count = comp_cnt;
526 comp_v1->lcm_mirror_count = layout->llot_mirror_count - 1;
530 list_for_each_entry(comp, &layout->llot_comp_list, llc_list) {
531 struct lov_user_md *blob;
534 int i, obj_count = 0;
535 struct lov_user_ost_data *lmm_objects;
536 uint64_t pattern = comp->llc_pattern;
538 if ((pattern & LLAPI_LAYOUT_SPECIFIC) != 0) {
539 if (comp->llc_objects_count <
540 comp->llc_stripe_count) {
544 magic = LOV_USER_MAGIC_SPECIFIC;
545 obj_count = comp->llc_stripe_count;
546 pattern &= ~LLAPI_LAYOUT_SPECIFIC;
547 } else if (strlen(comp->llc_pool_name) != 0) {
548 magic = LOV_USER_MAGIC_V3;
550 magic = LOV_USER_MAGIC_V1;
552 /* All stripes must be specified when the pattern contains
553 * LLAPI_LAYOUT_SPECIFIC */
554 for (i = 0; i < obj_count; i++) {
555 if (comp->llc_objects[i].l_ost_idx ==
556 LLAPI_LAYOUT_IDX_MAX) {
562 blob_size = lov_user_md_size(obj_count, magic);
563 blob = realloc(lum, lum_size + blob_size);
569 comp_v1 = (struct lov_comp_md_v1 *)lum;
570 blob = (struct lov_user_md *)((char *)lum + lum_size);
571 lum_size += blob_size;
574 blob->lmm_magic = magic;
575 if (pattern == LLAPI_LAYOUT_DEFAULT)
576 blob->lmm_pattern = LOV_PATTERN_RAID0;
577 else if (pattern == LLAPI_LAYOUT_MDT)
578 blob->lmm_pattern = LOV_PATTERN_MDT;
580 blob->lmm_pattern = pattern;
582 if (comp->llc_stripe_size == LLAPI_LAYOUT_DEFAULT)
583 blob->lmm_stripe_size = 0;
585 blob->lmm_stripe_size = comp->llc_stripe_size;
587 if (comp->llc_stripe_count == LLAPI_LAYOUT_DEFAULT)
588 blob->lmm_stripe_count = 0;
589 else if (comp->llc_stripe_count == LLAPI_LAYOUT_WIDE)
590 blob->lmm_stripe_count = LOV_ALL_STRIPES;
592 blob->lmm_stripe_count = comp->llc_stripe_count;
594 if (comp->llc_stripe_offset == LLAPI_LAYOUT_DEFAULT)
595 blob->lmm_stripe_offset = -1;
597 blob->lmm_stripe_offset = comp->llc_stripe_offset;
599 if (magic == LOV_USER_MAGIC_V3 ||
600 magic == LOV_USER_MAGIC_SPECIFIC) {
601 struct lov_user_md_v3 *lumv3 =
602 (struct lov_user_md_v3 *)blob;
604 if (comp->llc_pool_name[0] != '\0') {
605 strncpy(lumv3->lmm_pool_name,
607 sizeof(lumv3->lmm_pool_name));
609 memset(lumv3->lmm_pool_name, 0,
610 sizeof(lumv3->lmm_pool_name));
612 lmm_objects = lumv3->lmm_objects;
614 lmm_objects = blob->lmm_objects;
617 for (i = 0; i < obj_count; i++)
618 lmm_objects[i].l_ost_idx =
619 comp->llc_objects[i].l_ost_idx;
621 if (layout->llot_is_composite) {
622 ent = &comp_v1->lcm_entries[ent_idx];
623 ent->lcme_id = comp->llc_id;
624 ent->lcme_flags = comp->llc_flags;
625 ent->lcme_extent.e_start = comp->llc_extent.e_start;
626 ent->lcme_extent.e_end = comp->llc_extent.e_end;
627 ent->lcme_size = blob_size;
628 ent->lcme_offset = offset;
630 comp_v1->lcm_size += blob_size;
644 * Get the parent directory of a path.
646 * \param[in] path path to get parent of
647 * \param[out] buf buffer in which to store parent path
648 * \param[in] size size in bytes of buffer \a buf
650 static void get_parent_dir(const char *path, char *buf, size_t size)
654 strncpy(buf, path, size);
655 p = strrchr(buf, '/');
659 } else if (size >= 2) {
660 strncpy(buf, ".", 2);
661 buf[size - 1] = '\0';
666 * Substitute unspecified attribute values in \a layout with values
667 * from fs global settings. (lov.stripesize, lov.stripecount,
670 * \param[in] layout layout to inherit values from
671 * \param[in] path file path of the filesystem
673 static void inherit_sys_attributes(struct llapi_layout *layout,
676 struct llapi_layout_comp *comp;
677 unsigned int ssize, scount, soffset;
680 rc = sattr_cache_get_defaults(NULL, path, &scount, &ssize, &soffset);
684 list_for_each_entry(comp, &layout->llot_comp_list, llc_list) {
685 if (comp->llc_pattern == LLAPI_LAYOUT_DEFAULT)
686 comp->llc_pattern = LLAPI_LAYOUT_RAID0;
687 if (comp->llc_stripe_size == LLAPI_LAYOUT_DEFAULT)
688 comp->llc_stripe_size = ssize;
689 if (comp->llc_stripe_count == LLAPI_LAYOUT_DEFAULT)
690 comp->llc_stripe_count = scount;
691 if (comp->llc_stripe_offset == LLAPI_LAYOUT_DEFAULT)
692 comp->llc_stripe_offset = soffset;
697 * Get the current component of \a layout.
699 * \param[in] layout layout to get current component
701 * \retval valid llapi_layout_comp pointer on success
702 * \retval NULL on error
704 static struct llapi_layout_comp *
705 __llapi_layout_cur_comp(const struct llapi_layout *layout)
707 struct llapi_layout_comp *comp;
709 if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
713 if (layout->llot_cur_comp == NULL) {
717 /* Verify data consistency */
718 list_for_each_entry(comp, &layout->llot_comp_list, llc_list)
719 if (comp == layout->llot_cur_comp)
726 * Test if any attributes of \a layout are specified.
728 * \param[in] layout the layout to check
730 * \retval true any attributes are specified
731 * \retval false all attributes are unspecified
733 static bool is_any_specified(const struct llapi_layout *layout)
735 struct llapi_layout_comp *comp;
737 comp = __llapi_layout_cur_comp(layout);
741 if (layout->llot_is_composite || layout->llot_mirror_count != 1)
744 return comp->llc_pattern != LLAPI_LAYOUT_DEFAULT ||
745 comp->llc_stripe_size != LLAPI_LAYOUT_DEFAULT ||
746 comp->llc_stripe_count != LLAPI_LAYOUT_DEFAULT ||
747 comp->llc_stripe_offset != LLAPI_LAYOUT_DEFAULT ||
748 strlen(comp->llc_pool_name);
752 * Check if the given \a lum_size is large enough to hold the required
755 * \param[in] lum the struct lov_user_md to check
756 * \param[in] lum_size the number of bytes in \a lum
758 * \retval true the \a lum_size is too small
759 * \retval false the \a lum_size is large enough
761 static bool llapi_layout_lum_truncated(struct lov_user_md *lum, size_t lum_size)
765 if (lum_size < sizeof(lum->lmm_magic))
768 if (lum->lmm_magic == LOV_MAGIC_V1 ||
769 lum->lmm_magic == __swab32(LOV_MAGIC_V1))
770 magic = LOV_MAGIC_V1;
771 else if (lum->lmm_magic == LOV_MAGIC_V3 ||
772 lum->lmm_magic == __swab32(LOV_MAGIC_V3))
773 magic = LOV_MAGIC_V3;
774 else if (lum->lmm_magic == LOV_MAGIC_COMP_V1 ||
775 lum->lmm_magic == __swab32(LOV_MAGIC_COMP_V1))
776 magic = LOV_MAGIC_COMP_V1;
780 if (magic == LOV_MAGIC_V1 || magic == LOV_MAGIC_V3)
781 return lum_size < lov_user_md_size(0, magic);
783 return lum_size < sizeof(struct lov_comp_md_v1);
786 /* Verify if the objects count in lum is consistent with the
787 * stripe count in lum. It applies to regular file only. */
788 static bool llapi_layout_lum_valid(struct lov_user_md *lum, int lum_size)
790 struct lov_comp_md_v1 *comp_v1 = NULL;
791 int i, ent_count, obj_count;
793 if (lum->lmm_magic == LOV_MAGIC_COMP_V1) {
794 comp_v1 = (struct lov_comp_md_v1 *)lum;
795 ent_count = comp_v1->lcm_entry_count;
796 } else if (lum->lmm_magic == LOV_MAGIC_V1 ||
797 lum->lmm_magic == LOV_MAGIC_V3) {
803 for (i = 0; i < ent_count; i++) {
805 lum = (struct lov_user_md *)((char *)comp_v1 +
806 comp_v1->lcm_entries[i].lcme_offset);
807 lum_size = comp_v1->lcm_entries[i].lcme_size;
809 obj_count = llapi_layout_objects_in_lum(lum, lum_size);
812 if (!(comp_v1->lcm_entries[i].lcme_flags &
813 LCME_FL_INIT) && obj_count != 0)
815 } else if (obj_count != lum->lmm_stripe_count) {
823 * Get the striping layout for the file referenced by file descriptor \a fd.
825 * If the filesystem does not support the "lustre." xattr namespace, the
826 * file must be on a non-Lustre filesystem, so set errno to ENOTTY per
827 * convention. If the file has no "lustre.lov" data, the file will
828 * inherit default values, so return a default layout.
830 * If the kernel gives us back less than the expected amount of data,
831 * we fail with errno set to EINTR.
833 * \param[in] fd open file descriptor
834 * \param[in] flags open file descriptor
836 * \retval valid llapi_layout pointer on success
837 * \retval NULL if an error occurs
839 struct llapi_layout *llapi_layout_get_by_fd(int fd, uint32_t flags)
842 struct lov_user_md *lum;
843 struct llapi_layout *layout = NULL;
847 lum_len = XATTR_SIZE_MAX;
848 lum = malloc(lum_len);
852 bytes_read = fgetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_len);
853 if (bytes_read < 0) {
854 if (errno == EOPNOTSUPP)
856 else if (errno == ENODATA)
857 layout = llapi_layout_alloc();
861 /* Return an error if we got back a partial layout. */
862 if (llapi_layout_lum_truncated(lum, bytes_read)) {
867 llapi_layout_swab_lov_user_md(lum, bytes_read);
869 /* Directories may have a positive non-zero lum->lmm_stripe_count
870 * yet have an empty lum->lmm_objects array. For non-directories the
871 * amount of data returned from the kernel must be consistent
872 * with the stripe count. */
873 if (fstat(fd, &st) < 0)
876 if (!S_ISDIR(st.st_mode) && !llapi_layout_lum_valid(lum, bytes_read)) {
881 layout = llapi_layout_from_lum(lum, bytes_read);
888 * Get the expected striping layout for a file at \a path.
890 * Substitute expected inherited attribute values for unspecified
891 * attributes. Unspecified attributes may belong to directories and
892 * never-written-to files, and indicate that default values will be
893 * assigned when files are created or first written to. A default value
894 * is inherited from the parent directory if the attribute is specified
895 * there, otherwise it is inherited from the filesystem root.
896 * Unspecified attributes normally have the value LLAPI_LAYOUT_DEFAULT.
898 * The complete \a path need not refer to an existing file or directory,
899 * but some leading portion of it must reside within a lustre filesystem.
900 * A use case for this interface would be to obtain the literal striping
901 * values that would be assigned to a new file in a given directory.
903 * \param[in] path path for which to get the expected layout
905 * \retval valid llapi_layout pointer on success
906 * \retval NULL if an error occurs
908 static struct llapi_layout *llapi_layout_expected(const char *path)
910 struct llapi_layout *path_layout = NULL;
911 char donor_path[PATH_MAX];
916 fd = open(path, O_RDONLY);
917 if (fd < 0 && errno != ENOENT)
923 path_layout = llapi_layout_get_by_fd(fd, 0);
929 if (path_layout == NULL) {
930 if (errno != ENODATA && errno != ENOENT)
933 path_layout = llapi_layout_alloc();
934 if (path_layout == NULL)
938 if (is_any_specified(path_layout)) {
939 inherit_sys_attributes(path_layout, path);
943 llapi_layout_free(path_layout);
945 rc = stat(path, &st);
946 if (rc < 0 && errno != ENOENT)
949 /* If path is a not a directory or doesn't exist, inherit layout
950 * from parent directory. */
951 if ((rc == 0 && !S_ISDIR(st.st_mode)) ||
952 (rc < 0 && errno == ENOENT)) {
953 get_parent_dir(path, donor_path, sizeof(donor_path));
954 path_layout = llapi_layout_get_by_path(donor_path, 0);
955 if (path_layout != NULL) {
956 if (is_any_specified(path_layout)) {
957 inherit_sys_attributes(path_layout, donor_path);
960 llapi_layout_free(path_layout);
964 /* Inherit layout from the filesystem root. */
965 rc = llapi_search_mounts(path, 0, donor_path, NULL);
968 path_layout = llapi_layout_get_by_path(donor_path, 0);
969 if (path_layout == NULL)
972 inherit_sys_attributes(path_layout, donor_path);
977 * Get the striping layout for the file at \a path.
979 * If \a flags contains LAYOUT_GET_EXPECTED, substitute
980 * expected inherited attribute values for unspecified attributes. See
981 * llapi_layout_expected().
983 * \param[in] path path for which to get the layout
984 * \param[in] flags flags to control how layout is retrieved
986 * \retval valid llapi_layout pointer on success
987 * \retval NULL if an error occurs
989 struct llapi_layout *llapi_layout_get_by_path(const char *path, uint32_t flags)
991 struct llapi_layout *layout = NULL;
995 if (flags & LAYOUT_GET_EXPECTED)
996 return llapi_layout_expected(path);
998 fd = open(path, O_RDONLY);
1002 layout = llapi_layout_get_by_fd(fd, flags);
1011 * Get the layout for the file with FID \a fidstr in filesystem \a lustre_dir.
1013 * \param[in] lustre_dir path within Lustre filesystem containing \a fid
1014 * \param[in] fid Lustre identifier of file to get layout for
1016 * \retval valid llapi_layout pointer on success
1017 * \retval NULL if an error occurs
1019 struct llapi_layout *llapi_layout_get_by_fid(const char *lustre_dir,
1020 const struct lu_fid *fid,
1025 int saved_msg_level = llapi_msg_get_level();
1026 struct llapi_layout *layout = NULL;
1028 /* Prevent llapi internal routines from writing to console
1029 * while executing this function, then restore previous message
1031 llapi_msg_set_level(LLAPI_MSG_OFF);
1032 fd = llapi_open_by_fid(lustre_dir, fid, O_RDONLY);
1033 llapi_msg_set_level(saved_msg_level);
1038 layout = llapi_layout_get_by_fd(fd, flags);
1047 * Get the stripe count of \a layout.
1049 * \param[in] layout layout to get stripe count from
1050 * \param[out] count integer to store stripe count in
1052 * \retval 0 on success
1053 * \retval -1 if arguments are invalid
1055 int llapi_layout_stripe_count_get(const struct llapi_layout *layout,
1058 struct llapi_layout_comp *comp;
1060 comp = __llapi_layout_cur_comp(layout);
1064 if (count == NULL) {
1069 *count = comp->llc_stripe_count;
1075 * The llapi_layout API functions have these extra validity checks since
1076 * they use intuitively named macros to denote special behavior, whereas
1077 * the old API uses 0 and -1.
1080 static bool llapi_layout_stripe_count_is_valid(int64_t stripe_count)
1082 return stripe_count == LLAPI_LAYOUT_DEFAULT ||
1083 stripe_count == LLAPI_LAYOUT_WIDE ||
1084 (stripe_count != 0 && stripe_count != -1 &&
1085 llapi_stripe_count_is_valid(stripe_count));
1088 static bool llapi_layout_stripe_size_is_valid(uint64_t stripe_size)
1090 return stripe_size == LLAPI_LAYOUT_DEFAULT ||
1091 (stripe_size != 0 &&
1092 llapi_stripe_size_is_aligned(stripe_size) &&
1093 !llapi_stripe_size_is_too_big(stripe_size));
1096 static bool llapi_layout_stripe_index_is_valid(int64_t stripe_index)
1098 return stripe_index == LLAPI_LAYOUT_DEFAULT ||
1099 (stripe_index >= 0 &&
1100 llapi_stripe_index_is_valid(stripe_index));
1104 * Set the stripe count of \a layout.
1106 * \param[in] layout layout to set stripe count in
1107 * \param[in] count value to be set
1109 * \retval 0 on success
1110 * \retval -1 if arguments are invalid
1112 int llapi_layout_stripe_count_set(struct llapi_layout *layout,
1115 struct llapi_layout_comp *comp;
1117 comp = __llapi_layout_cur_comp(layout);
1121 if (!llapi_layout_stripe_count_is_valid(count)) {
1126 comp->llc_stripe_count = count;
1132 * Get the stripe size of \a layout.
1134 * \param[in] layout layout to get stripe size from
1135 * \param[out] size integer to store stripe size in
1137 * \retval 0 on success
1138 * \retval -1 if arguments are invalid
1140 int llapi_layout_stripe_size_get(const struct llapi_layout *layout,
1143 struct llapi_layout_comp *comp;
1145 comp = __llapi_layout_cur_comp(layout);
1154 *size = comp->llc_stripe_size;
1160 * Set the stripe size of \a layout.
1162 * \param[in] layout layout to set stripe size in
1163 * \param[in] size value to be set
1165 * \retval 0 on success
1166 * \retval -1 if arguments are invalid
1168 int llapi_layout_stripe_size_set(struct llapi_layout *layout,
1171 struct llapi_layout_comp *comp;
1173 comp = __llapi_layout_cur_comp(layout);
1177 if (!llapi_layout_stripe_size_is_valid(size)) {
1182 comp->llc_stripe_size = size;
1188 * Get the RAID pattern of \a layout.
1190 * \param[in] layout layout to get pattern from
1191 * \param[out] pattern integer to store pattern in
1193 * \retval 0 on success
1194 * \retval -1 if arguments are invalid
1196 int llapi_layout_pattern_get(const struct llapi_layout *layout,
1199 struct llapi_layout_comp *comp;
1201 comp = __llapi_layout_cur_comp(layout);
1205 if (pattern == NULL) {
1210 *pattern = comp->llc_pattern;
1216 * Set the pattern of \a layout.
1218 * \param[in] layout layout to set pattern in
1219 * \param[in] pattern value to be set
1221 * \retval 0 on success
1222 * \retval -1 if arguments are invalid or RAID pattern
1225 int llapi_layout_pattern_set(struct llapi_layout *layout, uint64_t pattern)
1227 struct llapi_layout_comp *comp;
1229 comp = __llapi_layout_cur_comp(layout);
1233 if (pattern != LLAPI_LAYOUT_DEFAULT &&
1234 pattern != LLAPI_LAYOUT_RAID0 && pattern != LLAPI_LAYOUT_MDT) {
1239 comp->llc_pattern = pattern |
1240 (comp->llc_pattern & LLAPI_LAYOUT_SPECIFIC);
1245 static inline int stripe_number_roundup(int stripe_number)
1247 unsigned int round_up = (stripe_number + 8) & ~7;
1248 return round_up > LOV_MAX_STRIPE_COUNT ?
1249 LOV_MAX_STRIPE_COUNT : round_up;
1253 * Set the OST index of stripe number \a stripe_number to \a ost_index.
1255 * If only the starting stripe's OST index is specified, then this can use
1256 * the normal LOV_MAGIC_{V1,V3} layout type. If multiple OST indices are
1257 * given, then allocate an array to hold the list of indices and ensure that
1258 * the LOV_USER_MAGIC_SPECIFIC layout is used when creating the file.
1260 * \param[in] layout layout to set OST index in
1261 * \param[in] stripe_number stripe number to set index for
1262 * \param[in] ost_index the index to set
1264 * \retval 0 on success
1265 * \retval -1 if arguments are invalid or an unsupported stripe number
1266 * was specified, error returned in errno
1268 int llapi_layout_ost_index_set(struct llapi_layout *layout, int stripe_number,
1271 struct llapi_layout_comp *comp;
1273 comp = __llapi_layout_cur_comp(layout);
1277 if (!llapi_layout_stripe_index_is_valid(ost_index)) {
1282 if (stripe_number == 0 && ost_index == LLAPI_LAYOUT_DEFAULT) {
1283 comp->llc_stripe_offset = ost_index;
1284 comp->llc_pattern &= ~LLAPI_LAYOUT_SPECIFIC;
1285 __llapi_comp_objects_realloc(comp, 0);
1286 } else if (stripe_number >= 0 &&
1287 stripe_number < LOV_MAX_STRIPE_COUNT) {
1288 if (ost_index >= LLAPI_LAYOUT_IDX_MAX) {
1293 /* Preallocate a few more stripes to avoid realloc() overhead.*/
1294 if (__llapi_comp_objects_realloc(comp,
1295 stripe_number_roundup(stripe_number)) < 0)
1298 comp->llc_objects[stripe_number].l_ost_idx = ost_index;
1300 if (stripe_number == 0)
1301 comp->llc_stripe_offset = ost_index;
1303 comp->llc_pattern |= LLAPI_LAYOUT_SPECIFIC;
1305 if (comp->llc_stripe_count == LLAPI_LAYOUT_DEFAULT ||
1306 comp->llc_stripe_count <= stripe_number)
1307 comp->llc_stripe_count = stripe_number + 1;
1317 * Get the OST index associated with stripe \a stripe_number.
1319 * Stripes are indexed starting from zero.
1321 * \param[in] layout layout to get index from
1322 * \param[in] stripe_number stripe number to get index for
1323 * \param[out] index integer to store index in
1325 * \retval 0 on success
1326 * \retval -1 if arguments are invalid
1328 int llapi_layout_ost_index_get(const struct llapi_layout *layout,
1329 uint64_t stripe_number, uint64_t *index)
1331 struct llapi_layout_comp *comp;
1333 comp = __llapi_layout_cur_comp(layout);
1337 if (index == NULL) {
1342 if (stripe_number >= comp->llc_stripe_count ||
1343 stripe_number >= comp->llc_objects_count) {
1348 if (comp->llc_stripe_offset == LLAPI_LAYOUT_DEFAULT)
1349 *index = LLAPI_LAYOUT_DEFAULT;
1351 *index = comp->llc_objects[stripe_number].l_ost_idx;
1358 * Get the pool name of layout \a layout.
1360 * \param[in] layout layout to get pool name from
1361 * \param[out] dest buffer to store pool name in
1362 * \param[in] n size in bytes of buffer \a dest
1364 * \retval 0 on success
1365 * \retval -1 if arguments are invalid
1367 int llapi_layout_pool_name_get(const struct llapi_layout *layout, char *dest,
1370 struct llapi_layout_comp *comp;
1372 comp = __llapi_layout_cur_comp(layout);
1381 strncpy(dest, comp->llc_pool_name, n);
1387 * Set the name of the pool of layout \a layout.
1389 * \param[in] layout layout to set pool name in
1390 * \param[in] pool_name pool name to set
1392 * \retval 0 on success
1393 * \retval -1 if arguments are invalid or pool name is too long
1395 int llapi_layout_pool_name_set(struct llapi_layout *layout,
1396 const char *pool_name)
1398 struct llapi_layout_comp *comp;
1401 comp = __llapi_layout_cur_comp(layout);
1405 if (pool_name == NULL) {
1410 /* Strip off any 'fsname.' portion. */
1411 ptr = strchr(pool_name, '.');
1413 pool_name = ptr + 1;
1415 if (strlen(pool_name) > LOV_MAXPOOLNAME) {
1420 strncpy(comp->llc_pool_name, pool_name, sizeof(comp->llc_pool_name));
1426 * Open and possibly create a file with a given \a layout.
1428 * If \a layout is NULL this function acts as a simple wrapper for
1429 * open(). By convention, ENOTTY is returned in errno if \a path
1430 * refers to a non-Lustre file.
1432 * \param[in] path name of the file to open
1433 * \param[in] open_flags open() flags
1434 * \param[in] mode permissions to create file, filtered by umask
1435 * \param[in] layout layout to create new file with
1437 * \retval non-negative file descriptor on successful open
1438 * \retval -1 if an error occurred
1440 int llapi_layout_file_open(const char *path, int open_flags, mode_t mode,
1441 const struct llapi_layout *layout)
1446 struct lov_user_md *lum;
1450 (layout != NULL && layout->llot_magic != LLAPI_LAYOUT_MAGIC)) {
1455 /* Object creation must be postponed until after layout attributes
1456 * have been applied. */
1457 if (layout != NULL && (open_flags & O_CREAT))
1458 open_flags |= O_LOV_DELAY_CREATE;
1460 fd = open(path, open_flags, mode);
1462 if (layout == NULL || fd < 0)
1465 lum = llapi_layout_to_lum(layout);
1474 if (lum->lmm_magic == LOV_USER_MAGIC_COMP_V1)
1475 lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
1476 else if (lum->lmm_magic == LOV_USER_MAGIC_SPECIFIC)
1477 lum_size = lov_user_md_size(lum->lmm_stripe_count,
1480 lum_size = lov_user_md_size(0, lum->lmm_magic);
1482 rc = fsetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_size, 0);
1491 errno = errno == EOPNOTSUPP ? ENOTTY : errno;
1497 * Create a file with a given \a layout.
1499 * Force O_CREAT and O_EXCL flags on so caller is assured that file was
1500 * created with the given \a layout on successful function return.
1502 * \param[in] path name of the file to open
1503 * \param[in] open_flags open() flags
1504 * \param[in] mode permissions to create new file with
1505 * \param[in] layout layout to create new file with
1507 * \retval non-negative file descriptor on successful open
1508 * \retval -1 if an error occurred
1510 int llapi_layout_file_create(const char *path, int open_flags, int mode,
1511 const struct llapi_layout *layout)
1513 return llapi_layout_file_open(path, open_flags|O_CREAT|O_EXCL, mode,
1517 int llapi_layout_flags_get(struct llapi_layout *layout, uint32_t *flags)
1519 if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1524 *flags = layout->llot_flags;
1529 * Set flags to the header of a component layout.
1531 int llapi_layout_flags_set(struct llapi_layout *layout, uint32_t flags)
1533 if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1538 layout->llot_flags = flags;
1542 const char *llapi_layout_flags_string(uint32_t flags)
1544 switch (flags & LCM_FL_FLR_MASK) {
1547 case LCM_FL_WRITE_PENDING:
1549 case LCM_FL_SYNC_PENDING:
1556 const __u16 llapi_layout_string_flags(char *string)
1558 if (strncmp(string, "ro", strlen(string)) == 0)
1559 return LCM_FL_RDONLY;
1560 if (strncmp(string, "wp", strlen(string)) == 0)
1561 return LCM_FL_WRITE_PENDING;
1562 if (strncmp(string, "sp", strlen(string)) == 0)
1563 return LCM_FL_SYNC_PENDING;
1569 * llapi_layout_mirror_count_is_valid() - Check the validity of mirror count.
1570 * @count: Mirror count value to be checked.
1572 * This function checks the validity of mirror count.
1574 * Return: true on success or false on failure.
1576 static bool llapi_layout_mirror_count_is_valid(uint16_t count)
1578 return count >= 0 && count <= LUSTRE_MIRROR_COUNT_MAX;
1582 * llapi_layout_mirror_count_get() - Get mirror count from the header of
1584 * @layout: Layout to get mirror count from.
1585 * @count: Returned mirror count value.
1587 * This function gets mirror count from the header of a layout.
1589 * Return: 0 on success or -1 on failure.
1591 int llapi_layout_mirror_count_get(struct llapi_layout *layout,
1594 if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1599 *count = layout->llot_mirror_count;
1604 * llapi_layout_mirror_count_set() - Set mirror count to the header of a layout.
1605 * @layout: Layout to set mirror count in.
1606 * @count: Mirror count value to be set.
1608 * This function sets mirror count to the header of a layout.
1610 * Return: 0 on success or -1 on failure.
1612 int llapi_layout_mirror_count_set(struct llapi_layout *layout,
1615 if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1620 if (!llapi_layout_mirror_count_is_valid(count)) {
1625 layout->llot_mirror_count = count;
1630 * Fetch the start and end offset of the current layout component.
1632 * \param[in] layout the layout component
1633 * \param[out] start extent start, inclusive
1634 * \param[out] end extent end, exclusive
1636 * \retval 0 on success
1637 * \retval <0 if error occurs
1639 int llapi_layout_comp_extent_get(const struct llapi_layout *layout,
1640 uint64_t *start, uint64_t *end)
1642 struct llapi_layout_comp *comp;
1644 comp = __llapi_layout_cur_comp(layout);
1648 if (start == NULL || end == NULL) {
1653 *start = comp->llc_extent.e_start;
1654 *end = comp->llc_extent.e_end;
1660 * Set the layout extent of a layout.
1662 * \param[in] layout the layout to be set
1663 * \param[in] start extent start, inclusive
1664 * \param[in] end extent end, exclusive
1666 * \retval 0 on success
1667 * \retval <0 if error occurs
1669 int llapi_layout_comp_extent_set(struct llapi_layout *layout,
1670 uint64_t start, uint64_t end)
1672 struct llapi_layout_comp *prev, *next, *comp;
1674 comp = __llapi_layout_cur_comp(layout);
1684 * We need to make sure the extent to be set is valid: the new
1685 * extent must be adjacent with the prev & next component.
1687 if (comp->llc_list.prev != &layout->llot_comp_list) {
1688 prev = list_entry(comp->llc_list.prev, typeof(*prev),
1690 if (start != 0 && start != prev->llc_extent.e_end) {
1696 if (comp->llc_list.next != &layout->llot_comp_list) {
1697 next = list_entry(comp->llc_list.next, typeof(*next),
1699 if (next->llc_extent.e_start != 0 &&
1700 end != next->llc_extent.e_start) {
1706 comp->llc_extent.e_start = start;
1707 comp->llc_extent.e_end = end;
1708 layout->llot_is_composite = true;
1714 * Gets the attribute flags of the current component.
1716 * \param[in] layout the layout component
1717 * \param[out] flags stored the returned component flags
1719 * \retval 0 on success
1720 * \retval <0 if error occurs
1722 int llapi_layout_comp_flags_get(const struct llapi_layout *layout,
1725 struct llapi_layout_comp *comp;
1727 comp = __llapi_layout_cur_comp(layout);
1731 if (flags == NULL) {
1736 *flags = comp->llc_flags;
1742 * Sets the specified flags of the current component leaving other flags as-is.
1744 * \param[in] layout the layout component
1745 * \param[in] flags component flags to be set
1747 * \retval 0 on success
1748 * \retval <0 if error occurs
1750 int llapi_layout_comp_flags_set(struct llapi_layout *layout, uint32_t flags)
1752 struct llapi_layout_comp *comp;
1754 comp = __llapi_layout_cur_comp(layout);
1758 comp->llc_flags |= flags;
1764 * Clears the flags specified in the flags leaving other flags as-is.
1766 * \param[in] layout the layout component
1767 * \param[in] flags component flags to be cleared
1769 * \retval 0 on success
1770 * \retval <0 if error occurs
1772 int llapi_layout_comp_flags_clear(struct llapi_layout *layout,
1775 struct llapi_layout_comp *comp;
1777 comp = __llapi_layout_cur_comp(layout);
1781 comp->llc_flags &= ~flags;
1787 * Fetches the file-unique component ID of the current layout component.
1789 * \param[in] layout the layout component
1790 * \param[out] id stored the returned component ID
1792 * \retval 0 on success
1793 * \retval <0 if error occurs
1795 int llapi_layout_comp_id_get(const struct llapi_layout *layout, uint32_t *id)
1797 struct llapi_layout_comp *comp;
1799 comp = __llapi_layout_cur_comp(layout);
1813 * Return the mirror id of the current layout component.
1815 * \param[in] layout the layout component
1816 * \param[out] id stored the returned mirror ID
1818 * \retval 0 on success
1819 * \retval <0 if error occurs
1821 int llapi_layout_mirror_id_get(const struct llapi_layout *layout, uint32_t *id)
1823 struct llapi_layout_comp *comp;
1825 comp = __llapi_layout_cur_comp(layout);
1834 *id = mirror_id_of(comp->llc_id);
1840 * Adds a component to \a layout, the new component will be added to
1841 * the tail of components list and it'll inherit attributes of existing
1842 * ones. The \a layout will change it's current component pointer to
1843 * the newly added component, and it'll be turned into a composite
1844 * layout if it was not before the adding.
1846 * \param[in] layout existing composite or plain layout
1848 * \retval 0 on success
1849 * \retval <0 if error occurs
1851 int llapi_layout_comp_add(struct llapi_layout *layout)
1853 struct llapi_layout_comp *last, *comp, *new;
1855 comp = __llapi_layout_cur_comp(layout);
1859 new = __llapi_comp_alloc(0);
1863 last = list_entry(layout->llot_comp_list.prev, typeof(*last),
1866 if (new->llc_extent.e_end <= last->llc_extent.e_end) {
1867 __llapi_comp_free(new);
1871 new->llc_extent.e_start = last->llc_extent.e_end;
1873 list_add_tail(&new->llc_list, &layout->llot_comp_list);
1874 layout->llot_cur_comp = new;
1875 layout->llot_is_composite = true;
1880 * Adds a first component of a mirror to \a layout.
1881 * The \a layout will change it's current component pointer to
1882 * the newly added component, and it'll be turned into a composite
1883 * layout if it was not before the adding.
1885 * \param[in] layout existing composite or plain layout
1887 * \retval 0 on success
1888 * \retval <0 if error occurs
1890 int llapi_layout_add_first_comp(struct llapi_layout *layout)
1892 struct llapi_layout_comp *comp, *new;
1894 comp = __llapi_layout_cur_comp(layout);
1898 new = __llapi_comp_alloc(0);
1902 new->llc_extent.e_start = 0;
1904 list_add_tail(&new->llc_list, &layout->llot_comp_list);
1905 layout->llot_cur_comp = new;
1906 layout->llot_is_composite = true;
1912 * Deletes current component from the composite layout. The component
1913 * to be deleted must be the tail of components list, and it can't be
1914 * the only component in the layout.
1916 * \param[in] layout composite layout
1918 * \retval 0 on success
1919 * \retval <0 if error occurs
1921 int llapi_layout_comp_del(struct llapi_layout *layout)
1923 struct llapi_layout_comp *comp;
1925 comp = __llapi_layout_cur_comp(layout);
1929 if (!layout->llot_is_composite) {
1934 /* It must be the tail of the list (for PFL, can be relaxed
1935 * once we get mirrored components) */
1936 if (comp->llc_list.next != &layout->llot_comp_list) {
1940 /* It can't be the only one on the list */
1941 if (comp->llc_list.prev == &layout->llot_comp_list) {
1946 layout->llot_cur_comp =
1947 list_entry(comp->llc_list.prev, typeof(*comp), llc_list);
1948 list_del_init(&comp->llc_list);
1949 __llapi_comp_free(comp);
1955 * Move the current component pointer to the component with
1956 * specified component ID.
1958 * \param[in] layout composite layout
1959 * \param[in] id component ID
1961 * \retval =0 : moved successfully
1962 * \retval <0 if error occurs
1964 int llapi_layout_comp_use_id(struct llapi_layout *layout, uint32_t comp_id)
1966 struct llapi_layout_comp *comp;
1968 comp = __llapi_layout_cur_comp(layout);
1970 return -1; /* use previously set errno */
1972 if (!layout->llot_is_composite) {
1977 if (comp_id == LCME_ID_INVAL) {
1982 list_for_each_entry(comp, &layout->llot_comp_list, llc_list) {
1983 if (comp->llc_id == comp_id) {
1984 layout->llot_cur_comp = comp;
1993 * Move the current component pointer to a specified position.
1995 * \param[in] layout composite layout
1996 * \param[in] pos the position to be moved, it can be:
1997 * LLAPI_LAYOUT_COMP_USE_FIRST: use first component
1998 * LLAPI_LAYOUT_COMP_USE_LAST: use last component
1999 * LLAPI_LAYOUT_COMP_USE_NEXT: use component after current
2000 * LLAPI_LAYOUT_COMP_USE_PREV: use component before current
2002 * \retval =0 : moved successfully
2003 * \retval =1 : at last component with NEXT, at first component with PREV
2004 * \retval <0 if error occurs
2006 int llapi_layout_comp_use(struct llapi_layout *layout,
2007 enum llapi_layout_comp_use pos)
2009 struct llapi_layout_comp *comp, *head, *tail;
2011 comp = __llapi_layout_cur_comp(layout);
2015 if (!layout->llot_is_composite) {
2016 if (pos == LLAPI_LAYOUT_COMP_USE_FIRST ||
2017 pos == LLAPI_LAYOUT_COMP_USE_LAST)
2023 head = list_entry(layout->llot_comp_list.next, typeof(*head), llc_list);
2024 tail = list_entry(layout->llot_comp_list.prev, typeof(*tail), llc_list);
2026 case LLAPI_LAYOUT_COMP_USE_FIRST:
2027 layout->llot_cur_comp = head;
2029 case LLAPI_LAYOUT_COMP_USE_NEXT:
2034 layout->llot_cur_comp = list_entry(comp->llc_list.next,
2035 typeof(*comp), llc_list);
2037 case LLAPI_LAYOUT_COMP_USE_LAST:
2038 layout->llot_cur_comp = tail;
2040 case LLAPI_LAYOUT_COMP_USE_PREV:
2045 layout->llot_cur_comp = list_entry(comp->llc_list.prev,
2046 typeof(*comp), llc_list);
2057 * Add layout component(s) to an existing file.
2059 * \param[in] path The path name of the file
2060 * \param[in] layout The layout component(s) to be added
2062 int llapi_layout_file_comp_add(const char *path,
2063 const struct llapi_layout *layout)
2065 int rc, fd, lum_size, tmp_errno = 0;
2066 struct lov_user_md *lum;
2068 if (path == NULL || layout == NULL ||
2069 layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
2074 lum = llapi_layout_to_lum(layout);
2078 if (lum->lmm_magic != LOV_USER_MAGIC_COMP_V1) {
2083 lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
2085 fd = open(path, O_RDWR);
2092 rc = fsetxattr(fd, XATTR_LUSTRE_LOV".add", lum, lum_size, 0);
2107 * Delete component(s) by the specified component id or component flags
2108 * from an existing file.
2110 * \param[in] path path name of the file
2111 * \param[in] id unique component ID
2112 * \param[in] flags flags: LCME_FL_* or;
2113 * negative flags: (LCME_FL_NEG|LCME_FL_*)
2115 int llapi_layout_file_comp_del(const char *path, uint32_t id, uint32_t flags)
2117 int rc, fd, lum_size;
2118 struct llapi_layout *layout;
2119 struct llapi_layout_comp *comp;
2120 struct lov_user_md *lum;
2122 if (path == NULL || id > LCME_ID_MAX || (flags & ~LCME_KNOWN_FLAGS)) {
2127 /* Can only specify ID or flags, not both. */
2128 if (id != 0 && flags != 0) {
2133 layout = llapi_layout_alloc();
2137 llapi_layout_comp_extent_set(layout, 0, LUSTRE_EOF);
2138 comp = __llapi_layout_cur_comp(layout);
2140 llapi_layout_free(layout);
2145 comp->llc_flags = flags;
2147 lum = llapi_layout_to_lum(layout);
2149 llapi_layout_free(layout);
2152 lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
2154 fd = open(path, O_RDWR);
2160 rc = fsetxattr(fd, XATTR_LUSTRE_LOV".del", lum, lum_size, 0);
2162 int tmp_errno = errno;
2171 llapi_layout_free(layout);
2176 * Change flags or other parameters of the component(s) by component ID of an
2177 * existing file. The component to be modified is specified by the
2178 * comp->lcme_id value, which must be an unique component ID. The new
2179 * attributes are passed in by @comp and @valid is used to specify which
2180 * attributes in the component are going to be changed.
2182 * \param[in] path path name of the file
2183 * \param[in] ids An array of component IDs
2184 * \param[in] flags flags: LCME_FL_* or;
2185 * negative flags: (LCME_FL_NEG|LCME_FL_*)
2186 * \param[in] count Number of elements in ids and flags array
2188 int llapi_layout_file_comp_set(const char *path, uint32_t *ids, uint32_t *flags,
2191 int rc = -1, fd = -1, i;
2193 struct llapi_layout *layout;
2194 struct llapi_layout_comp *comp;
2195 struct lov_user_md *lum = NULL;
2205 for (i = 0; i < count; i++) {
2206 if (!ids[i] || !flags[i]) {
2211 if (ids[i] > LCME_ID_MAX || (flags[i] & ~LCME_KNOWN_FLAGS)) {
2216 /* do not allow to set or clear INIT flag */
2217 if (flags[i] & LCME_FL_INIT) {
2223 layout = __llapi_layout_alloc();
2227 layout->llot_is_composite = true;
2228 for (i = 0; i < count; i++) {
2229 comp = __llapi_comp_alloc(0);
2233 comp->llc_id = ids[i];
2234 comp->llc_flags = flags[i];
2236 list_add_tail(&comp->llc_list, &layout->llot_comp_list);
2237 layout->llot_cur_comp = comp;
2240 lum = llapi_layout_to_lum(layout);
2244 lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
2246 fd = open(path, O_RDWR);
2250 /* flush cached pages from clients */
2251 rc = llapi_file_flush(fd);
2258 rc = fsetxattr(fd, XATTR_LUSTRE_LOV".set.flags", lum, lum_size, 0);
2266 int tmp_errno = errno;
2273 llapi_layout_free(layout);
2278 * Check if the file layout is composite.
2280 * \param[in] layout the file layout to check
2282 * \retval true composite
2283 * \retval false not composite
2285 bool llapi_layout_is_composite(struct llapi_layout *layout)
2287 return layout->llot_is_composite;
2291 * Iterate every components in the @layout and call callback function @cb.
2293 * \param[in] layout component layout list.
2294 * \param[in] cb callback for each component
2295 * \param[in] cbdata callback data
2297 * \retval < 0 error happens during the iteration
2298 * \retval LLAPI_LAYOUT_ITER_CONT finished the iteration w/o error
2299 * \retval LLAPI_LAYOUT_ITER_STOP got something, stop the iteration
2301 int llapi_layout_comp_iterate(struct llapi_layout *layout,
2302 llapi_layout_iter_cb cb, void *cbdata)
2306 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
2311 * make sure on success llapi_layout_comp_use() API returns 0 with
2317 rc = cb(layout, cbdata);
2318 if (rc != LLAPI_LAYOUT_ITER_CONT)
2321 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
2324 else if (rc == 1) /* reached the last comp */
2325 return LLAPI_LAYOUT_ITER_CONT;
2332 * llapi_layout_merge() - Merge a composite layout into another one.
2333 * @dst_layout: Destination composite layout.
2334 * @src_layout: Source composite layout.
2336 * This function copies all of the components from @src_layout and
2337 * appends them to @dst_layout.
2339 * Return: 0 on success or -1 on failure.
2341 int llapi_layout_merge(struct llapi_layout **dst_layout,
2342 const struct llapi_layout *src_layout)
2344 struct llapi_layout *new_layout = *dst_layout;
2345 struct llapi_layout_comp *new = NULL;
2346 struct llapi_layout_comp *comp = NULL;
2349 if (src_layout == NULL ||
2350 list_empty((struct list_head *)&src_layout->llot_comp_list))
2353 if (new_layout == NULL) {
2354 new_layout = __llapi_layout_alloc();
2355 if (new_layout == NULL) {
2361 list_for_each_entry(comp, &src_layout->llot_comp_list, llc_list) {
2362 new = __llapi_comp_alloc(0);
2368 new->llc_pattern = comp->llc_pattern;
2369 new->llc_stripe_size = comp->llc_stripe_size;
2370 new->llc_stripe_count = comp->llc_stripe_count;
2371 new->llc_stripe_offset = comp->llc_stripe_offset;
2373 if (comp->llc_pool_name[0] != '\0')
2374 strncpy(new->llc_pool_name, comp->llc_pool_name,
2375 sizeof(new->llc_pool_name));
2377 for (i = 0; i < comp->llc_objects_count; i++) {
2378 if (__llapi_comp_objects_realloc(new,
2379 stripe_number_roundup(i)) < 0) {
2381 __llapi_comp_free(new);
2384 new->llc_objects[i].l_ost_idx = \
2385 comp->llc_objects[i].l_ost_idx;
2388 new->llc_objects_count = comp->llc_objects_count;
2389 new->llc_extent.e_start = comp->llc_extent.e_start;
2390 new->llc_extent.e_end = comp->llc_extent.e_end;
2391 new->llc_id = comp->llc_id;
2392 new->llc_flags = comp->llc_flags;
2394 list_add_tail(&new->llc_list, &new_layout->llot_comp_list);
2395 new_layout->llot_cur_comp = new;
2397 new_layout->llot_is_composite = true;
2399 *dst_layout = new_layout;
2402 llapi_layout_free(new_layout);
2407 * Find all stale components.
2409 * \param[in] layout component layout list.
2410 * \param[out] comp array of stale component info.
2411 * \param[in] comp_size array size of @comp.
2412 * \param[in] mirror_ids array of mirror id that only components
2413 * belonging to these mirror will be collected.
2414 * \param[in] ids_nr number of mirror ids array.
2416 * \retval number of component info collected on sucess or
2417 * an error code on failure.
2419 int llapi_mirror_find_stale(struct llapi_layout *layout,
2420 struct llapi_resync_comp *comp, size_t comp_size,
2421 __u16 *mirror_ids, int ids_nr)
2426 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
2434 uint64_t start, end;
2436 rc = llapi_layout_comp_flags_get(layout, &flags);
2440 if (!(flags & LCME_FL_STALE))
2443 rc = llapi_layout_mirror_id_get(layout, &mirror_id);
2447 /* the caller only wants stale components from specific
2452 for (j = 0; j < ids_nr; j++) {
2453 if (mirror_ids[j] == mirror_id)
2457 /* not in the specified mirror */
2462 rc = llapi_layout_comp_id_get(layout, &id);
2466 rc = llapi_layout_comp_extent_get(layout, &start, &end);
2470 /* pack this component into @comp array */
2471 comp[idx].lrc_id = id;
2472 comp[idx].lrc_mirror_id = mirror_id;
2473 comp[idx].lrc_start = start;
2474 comp[idx].lrc_end = end;
2477 if (idx >= comp_size) {
2483 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
2490 return rc < 0 ? rc : idx;
2493 /* locate @layout to a valid component covering file [file_start, file_end) */
2494 uint32_t llapi_mirror_find(struct llapi_layout *layout,
2495 uint64_t file_start, uint64_t file_end,
2498 uint32_t mirror_id = 0;
2501 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
2507 uint64_t start, end;
2508 uint32_t flags, id, rid;
2510 rc = llapi_layout_comp_flags_get(layout, &flags);
2514 if (flags & LCME_FL_STALE)
2517 rc = llapi_layout_mirror_id_get(layout, &rid);
2521 rc = llapi_layout_comp_id_get(layout, &id);
2525 rc = llapi_layout_comp_extent_get(layout, &start, &end);
2529 if (file_start >= start && file_start < end) {
2532 else if (mirror_id != rid || *endp != start)
2535 file_start = *endp = end;
2536 if (end >= file_end)
2541 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
2549 int llapi_mirror_resync_many(int fd, struct llapi_layout *layout,
2550 struct llapi_resync_comp *comp_array,
2551 int comp_size, uint64_t start, uint64_t end)
2554 size_t page_size = sysconf(_SC_PAGESIZE);
2555 const size_t buflen = 4 << 20; /* 4M */
2557 uint64_t pos = start;
2561 rc = posix_memalign(&buf, page_size, buflen);
2565 if (end == OBD_OBJECT_EOF)
2566 count = OBD_OBJECT_EOF;
2568 count = end - start;
2572 uint64_t mirror_end = 0;
2577 src = llapi_mirror_find(layout, pos, end, &mirror_end);
2581 if (mirror_end == OBD_OBJECT_EOF) {
2584 to_read = MIN(count, mirror_end - pos);
2585 to_read = (to_read + page_size - 1) & ~(page_size - 1);
2587 to_read = MIN(buflen, to_read);
2589 bytes_read = llapi_mirror_read(fd, src, buf, to_read, pos);
2590 if (bytes_read == 0) {
2594 if (bytes_read < 0) {
2599 /* round up to page align to make direct IO happy. */
2600 to_write = (bytes_read + page_size - 1) & ~(page_size - 1);
2602 for (i = 0; i < comp_size; i++) {
2605 /* skip non-overlapped component */
2606 if (pos > comp_array[i].lrc_end ||
2607 pos + to_write < comp_array[i].lrc_start)
2610 written = llapi_mirror_write(fd,
2611 comp_array[i].lrc_mirror_id, buf,
2615 * this component is not written successfully,
2616 * mark it using its lrc_synced, it is supposed
2617 * to be false before getting here.
2619 * And before this function returns, all
2620 * elements of comp_array will reverse their
2621 * lrc_synced flag to reflect their true
2624 comp_array[i].lrc_synced = true;
2627 assert(written == to_write);
2631 count -= bytes_read;
2637 for (i = 0; i < comp_size; i++)
2638 comp_array[i].lrc_synced = false;
2642 for (i = 0; i < comp_size; i++) {
2643 comp_array[i].lrc_synced = !comp_array[i].lrc_synced;
2644 if (comp_array[i].lrc_synced && pos & (page_size - 1)) {
2645 rc = llapi_mirror_truncate(fd,
2646 comp_array[i].lrc_mirror_id, pos);
2648 comp_array[i].lrc_synced = false;
2652 /* partially successful is successful */