Whamcloud - gitweb
ae2826e17738c5cebb9c95e8968fd49504133b56
[fs/lustre-release.git] / lustre / utils / liblustreapi_layout.c
1 /*
2  * LGPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
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
11  *
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.
16  *
17  * LGPL HEADER END
18  */
19 /*
20  * lustre/utils/liblustreapi_layout.c
21  *
22  * lustreapi library for layout calls for interacting with the layout of
23  * Lustre files while hiding details of the internal data structures
24  * from the user.
25  *
26  * Copyright (c) 2016, Intel Corporation.
27  *
28  * Author: Ned Bass <bass6@llnl.gov>
29  */
30
31 #include <stdio.h>
32 #include <fcntl.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <errno.h>
36 #include <limits.h>
37 #include <sys/xattr.h>
38
39 #include <libcfs/util/list.h>
40 #include <lustre/lustreapi.h>
41 #include "lustreapi_internal.h"
42
43 /**
44  * Layout component, which contains all attributes of a plain
45  * V1/V3 layout.
46  */
47 struct llapi_layout_comp {
48         uint64_t        llc_pattern;
49         uint64_t        llc_stripe_size;
50         uint64_t        llc_stripe_count;
51         uint64_t        llc_stripe_offset;
52         /* Add 1 so user always gets back a null terminated string. */
53         char            llc_pool_name[LOV_MAXPOOLNAME + 1];
54         /** Number of objects in llc_objects array if was initialized. */
55         uint32_t        llc_objects_count;
56         struct          lov_user_ost_data_v1 *llc_objects;
57         /* fields used only for composite layouts */
58         struct lu_extent        llc_extent;     /* [start, end) of component */
59         uint32_t                llc_id;         /* unique ID of component */
60         uint32_t                llc_flags;      /* LCME_FL_* flags */
61         struct list_head        llc_list;       /* linked to the llapi_layout
62                                                    components list */
63 };
64
65 /**
66  * An Opaque data type abstracting the layout of a Lustre file.
67  */
68 struct llapi_layout {
69         uint32_t        llot_magic; /* LLAPI_LAYOUT_MAGIC */
70         uint32_t        llot_gen;
71         uint32_t        llot_flags;
72         bool            llot_is_composite;
73         uint16_t        llot_mirror_count;
74         /* Cursor pointing to one of the components in llot_comp_list */
75         struct llapi_layout_comp *llot_cur_comp;
76         struct list_head          llot_comp_list;
77 };
78
79 /**
80  * Compute the number of elements in the lmm_objects array of \a lum
81  * with size \a lum_size.
82  *
83  * \param[in] lum       the struct lov_user_md to check
84  * \param[in] lum_size  the number of bytes in \a lum
85  *
86  * \retval              number of elements in array lum->lmm_objects
87  */
88 static int llapi_layout_objects_in_lum(struct lov_user_md *lum, size_t lum_size)
89 {
90         uint32_t magic;
91         size_t base_size;
92
93         if (lum_size < lov_user_md_size(0, LOV_MAGIC_V1))
94                 return 0;
95
96         if (lum->lmm_magic == __swab32(LOV_MAGIC_V1) ||
97             lum->lmm_magic == __swab32(LOV_MAGIC_V3))
98                 magic = __swab32(lum->lmm_magic);
99         else
100                 magic = lum->lmm_magic;
101
102         base_size = lov_user_md_size(0, magic);
103
104         if (lum_size <= base_size)
105                 return 0;
106         else
107                 return (lum_size - base_size) / sizeof(lum->lmm_objects[0]);
108 }
109
110 /**
111  * Byte-swap the fields of struct lov_user_md.
112  *
113  * XXX Rather than duplicating swabbing code here, we should eventually
114  * refactor the needed functions in lustre/ptlrpc/pack_generic.c
115  * into a library that can be shared between kernel and user code.
116  */
117 static void
118 llapi_layout_swab_lov_user_md(struct lov_user_md *lum, int lum_size)
119 {
120         int i, j, ent_count, obj_count;
121         struct lov_comp_md_v1 *comp_v1 = NULL;
122         struct lov_comp_md_entry_v1 *ent;
123         struct lov_user_ost_data *lod;
124
125         if (lum->lmm_magic != __swab32(LOV_MAGIC_V1) &&
126             lum->lmm_magic != __swab32(LOV_MAGIC_V3) &&
127             lum->lmm_magic != __swab32(LOV_MAGIC_COMP_V1))
128                 return;
129
130         if (lum->lmm_magic == __swab32(LOV_MAGIC_COMP_V1))
131                 comp_v1 = (struct lov_comp_md_v1 *)lum;
132
133         if (comp_v1 != NULL) {
134                 __swab32s(&comp_v1->lcm_magic);
135                 __swab32s(&comp_v1->lcm_size);
136                 __swab32s(&comp_v1->lcm_layout_gen);
137                 __swab16s(&comp_v1->lcm_flags);
138                 __swab16s(&comp_v1->lcm_entry_count);
139                 ent_count = comp_v1->lcm_entry_count;
140         } else {
141                 ent_count = 1;
142         }
143
144         for (i = 0; i < ent_count; i++) {
145                 if (comp_v1 != NULL) {
146                         ent = &comp_v1->lcm_entries[i];
147                         __swab32s(&ent->lcme_id);
148                         __swab32s(&ent->lcme_flags);
149                         __swab64s(&ent->lcme_extent.e_start);
150                         __swab64s(&ent->lcme_extent.e_end);
151                         __swab32s(&ent->lcme_offset);
152                         __swab32s(&ent->lcme_size);
153
154                         lum = (struct lov_user_md *)((char *)comp_v1 +
155                                         ent->lcme_offset);
156                         lum_size = ent->lcme_size;
157                 }
158                 obj_count = llapi_layout_objects_in_lum(lum, lum_size);
159
160                 __swab32s(&lum->lmm_magic);
161                 __swab32s(&lum->lmm_pattern);
162                 __swab32s(&lum->lmm_stripe_size);
163                 __swab16s(&lum->lmm_stripe_count);
164                 __swab16s(&lum->lmm_stripe_offset);
165
166                 if (lum->lmm_magic != LOV_MAGIC_V1) {
167                         struct lov_user_md_v3 *v3;
168                         v3 = (struct lov_user_md_v3 *)lum;
169                         lod = v3->lmm_objects;
170                 } else {
171                         lod = lum->lmm_objects;
172                 }
173
174                 for (j = 0; j < obj_count; j++)
175                         __swab32s(&lod[j].l_ost_idx);
176         }
177 }
178
179 /**
180  * (Re-)allocate llc_objects[] to \a num_stripes stripes.
181  *
182  * Copy over existing llc_objects[], if any, to the new llc_objects[].
183  *
184  * \param[in] layout            existing layout to be modified
185  * \param[in] num_stripes       number of stripes in new layout
186  *
187  * \retval      0 if the objects are re-allocated successfully
188  * \retval      -1 on error with errno set
189  */
190 static int __llapi_comp_objects_realloc(struct llapi_layout_comp *comp,
191                                         unsigned int new_stripes)
192 {
193         struct lov_user_ost_data_v1 *new_objects;
194         unsigned int i;
195
196         if (new_stripes > LOV_MAX_STRIPE_COUNT) {
197                 errno = EINVAL;
198                 return -1;
199         }
200
201         if (new_stripes == comp->llc_objects_count)
202                 return 0;
203
204         if (new_stripes != 0 && new_stripes <= comp->llc_objects_count)
205                 return 0;
206
207         new_objects = realloc(comp->llc_objects,
208                               sizeof(*new_objects) * new_stripes);
209         if (new_objects == NULL && new_stripes != 0) {
210                 errno = ENOMEM;
211                 return -1;
212         }
213
214         for (i = comp->llc_objects_count; i < new_stripes; i++)
215                 new_objects[i].l_ost_idx = LLAPI_LAYOUT_IDX_MAX;
216
217         comp->llc_objects = new_objects;
218         comp->llc_objects_count = new_stripes;
219
220         return 0;
221 }
222
223 /**
224  * Allocate storage for a llapi_layout_comp with \a num_stripes stripes.
225  *
226  * \param[in] num_stripes       number of stripes in new layout
227  *
228  * \retval      valid pointer if allocation succeeds
229  * \retval      NULL if allocation fails
230  */
231 static struct llapi_layout_comp *__llapi_comp_alloc(unsigned int num_stripes)
232 {
233         struct llapi_layout_comp *comp;
234
235         if (num_stripes > LOV_MAX_STRIPE_COUNT) {
236                 errno = EINVAL;
237                 return NULL;
238         }
239
240         comp = calloc(1, sizeof(*comp));
241         if (comp == NULL) {
242                 errno = ENOMEM;
243                 return NULL;
244         }
245
246         comp->llc_objects = NULL;
247         comp->llc_objects_count = 0;
248
249         if (__llapi_comp_objects_realloc(comp, num_stripes) < 0) {
250                 free(comp);
251                 return NULL;
252         }
253
254         /* Set defaults. */
255         comp->llc_pattern = LLAPI_LAYOUT_DEFAULT;
256         comp->llc_stripe_size = LLAPI_LAYOUT_DEFAULT;
257         comp->llc_stripe_count = LLAPI_LAYOUT_DEFAULT;
258         comp->llc_stripe_offset = LLAPI_LAYOUT_DEFAULT;
259         comp->llc_pool_name[0] = '\0';
260         comp->llc_extent.e_start = 0;
261         comp->llc_extent.e_end = LUSTRE_EOF;
262         comp->llc_flags = 0;
263         comp->llc_id = 0;
264         INIT_LIST_HEAD(&comp->llc_list);
265
266         return comp;
267 }
268
269 /**
270  * Free memory allocated for \a comp
271  *
272  * \param[in] comp      previously allocated by __llapi_comp_alloc()
273  */
274 static void __llapi_comp_free(struct llapi_layout_comp *comp)
275 {
276         if (comp->llc_objects != NULL)
277                 free(comp->llc_objects);
278         free(comp);
279 }
280
281 /**
282  * Free memory allocated for \a layout.
283  *
284  * \param[in] layout    previously allocated by llapi_layout_alloc()
285  */
286 void llapi_layout_free(struct llapi_layout *layout)
287 {
288         struct llapi_layout_comp *comp, *n;
289
290         if (layout == NULL)
291                 return;
292
293         list_for_each_entry_safe(comp, n, &layout->llot_comp_list, llc_list) {
294                 list_del_init(&comp->llc_list);
295                 __llapi_comp_free(comp);
296         }
297         free(layout);
298 }
299
300 /**
301  * Allocate and initialize a llapi_layout structure.
302  *
303  * \retval      valid llapi_layout pointer on success
304  * \retval      NULL if memory allocation fails
305  */
306 static struct llapi_layout *__llapi_layout_alloc(void)
307 {
308         struct llapi_layout *layout;
309
310         layout = calloc(1, sizeof(*layout));
311         if (layout == NULL) {
312                 errno = ENOMEM;
313                 return NULL;
314         }
315
316         /* Set defaults. */
317         layout->llot_magic = LLAPI_LAYOUT_MAGIC;
318         layout->llot_gen = 0;
319         layout->llot_flags = 0;
320         layout->llot_is_composite = false;
321         layout->llot_mirror_count = 1;
322         layout->llot_cur_comp = NULL;
323         INIT_LIST_HEAD(&layout->llot_comp_list);
324
325         return layout;
326 }
327
328 /**
329  * Allocate and initialize a new plain layout.
330  *
331  * \retval      valid llapi_layout pointer on success
332  * \retval      NULL if memory allocation fails
333  */
334 struct llapi_layout *llapi_layout_alloc(void)
335 {
336         struct llapi_layout_comp *comp;
337         struct llapi_layout *layout;
338
339         layout = __llapi_layout_alloc();
340         if (layout == NULL)
341                 return NULL;
342
343         comp = __llapi_comp_alloc(0);
344         if (comp == NULL) {
345                 free(layout);
346                 return NULL;
347         }
348
349         list_add_tail(&comp->llc_list, &layout->llot_comp_list);
350         layout->llot_cur_comp = comp;
351
352         return layout;
353 }
354
355 /**
356  * Convert the data from a lov_user_md to a newly allocated llapi_layout.
357  * The caller is responsible for freeing the returned pointer.
358  *
359  * \param[in] lum       LOV user metadata structure to copy data from
360  * \param[in] lum_size  size the the lum passed in
361  *
362  * \retval              valid llapi_layout pointer on success
363  * \retval              NULL if memory allocation fails
364  */
365 static struct llapi_layout *
366 llapi_layout_from_lum(const struct lov_user_md *lum, int lum_size)
367 {
368         struct lov_comp_md_v1 *comp_v1 = NULL;
369         struct lov_comp_md_entry_v1 *ent;
370         struct lov_user_md *v1;
371         struct llapi_layout *layout;
372         struct llapi_layout_comp *comp;
373         int i, ent_count = 0, obj_count;
374
375         layout = __llapi_layout_alloc();
376         if (layout == NULL)
377                 return NULL;
378
379         if (lum->lmm_magic == LOV_MAGIC_COMP_V1) {
380                 comp_v1 = (struct lov_comp_md_v1 *)lum;
381                 ent_count = comp_v1->lcm_entry_count;
382                 layout->llot_gen = comp_v1->lcm_layout_gen;
383                 layout->llot_is_composite = true;
384                 layout->llot_mirror_count = comp_v1->lcm_mirror_count + 1;
385                 layout->llot_gen = comp_v1->lcm_layout_gen;
386                 layout->llot_flags = comp_v1->lcm_flags;
387         } else if (lum->lmm_magic == LOV_MAGIC_V1 ||
388                    lum->lmm_magic == LOV_MAGIC_V3) {
389                 ent_count = 1;
390                 layout->llot_is_composite = false;
391         }
392
393         if (ent_count == 0) {
394                 errno = EINVAL;
395                 goto error;
396         }
397
398         v1 = (struct lov_user_md *)lum;
399         for (i = 0; i < ent_count; i++) {
400                 if (comp_v1 != NULL) {
401                         ent = &comp_v1->lcm_entries[i];
402                         v1 = (struct lov_user_md *)((char *)comp_v1 +
403                                 ent->lcme_offset);
404                         lum_size = ent->lcme_size;
405                 } else {
406                         ent = NULL;
407                 }
408
409                 obj_count = llapi_layout_objects_in_lum(v1, lum_size);
410                 comp = __llapi_comp_alloc(obj_count);
411                 if (comp == NULL)
412                         goto error;
413
414                 if (ent != NULL) {
415                         comp->llc_extent.e_start = ent->lcme_extent.e_start;
416                         comp->llc_extent.e_end = ent->lcme_extent.e_end;
417                         comp->llc_id = ent->lcme_id;
418                         comp->llc_flags = ent->lcme_flags;
419                 } else {
420                         comp->llc_extent.e_start = 0;
421                         comp->llc_extent.e_end = LUSTRE_EOF;
422                         comp->llc_id = 0;
423                         comp->llc_flags = 0;
424                 }
425
426                 if (v1->lmm_pattern == LOV_PATTERN_RAID0)
427                         comp->llc_pattern = LLAPI_LAYOUT_RAID0;
428                 else
429                         /* Lustre only supports RAID0 for now. */
430                         comp->llc_pattern = v1->lmm_pattern;
431
432                 if (v1->lmm_stripe_size == 0)
433                         comp->llc_stripe_size = LLAPI_LAYOUT_DEFAULT;
434                 else
435                         comp->llc_stripe_size = v1->lmm_stripe_size;
436
437                 if (v1->lmm_stripe_count == (typeof(v1->lmm_stripe_count))-1)
438                         comp->llc_stripe_count = LLAPI_LAYOUT_WIDE;
439                 else if (v1->lmm_stripe_count == 0)
440                         comp->llc_stripe_count = LLAPI_LAYOUT_DEFAULT;
441                 else
442                         comp->llc_stripe_count = v1->lmm_stripe_count;
443
444                 if (v1->lmm_stripe_offset ==
445                     (typeof(v1->lmm_stripe_offset))-1)
446                         comp->llc_stripe_offset = LLAPI_LAYOUT_DEFAULT;
447                 else
448                         comp->llc_stripe_offset = v1->lmm_stripe_offset;
449
450                 if (v1->lmm_magic != LOV_USER_MAGIC_V1) {
451                         const struct lov_user_md_v3 *lumv3;
452                         lumv3 = (struct lov_user_md_v3 *)v1;
453                         snprintf(comp->llc_pool_name,
454                                  sizeof(comp->llc_pool_name),
455                                  "%s", lumv3->lmm_pool_name);
456                         memcpy(comp->llc_objects, lumv3->lmm_objects,
457                                obj_count * sizeof(lumv3->lmm_objects[0]));
458                 } else {
459                         const struct lov_user_md_v1 *lumv1;
460                         lumv1 = (struct lov_user_md_v1 *)v1;
461                         memcpy(comp->llc_objects, lumv1->lmm_objects,
462                                obj_count * sizeof(lumv1->lmm_objects[0]));
463                 }
464
465                 if (obj_count != 0)
466                         comp->llc_stripe_offset =
467                                 comp->llc_objects[0].l_ost_idx;
468
469                 list_add_tail(&comp->llc_list, &layout->llot_comp_list);
470                 layout->llot_cur_comp = comp;
471         }
472
473         return layout;
474 error:
475         llapi_layout_free(layout);
476         return NULL;
477 }
478
479 /**
480  * Convert the data from a llapi_layout to a newly allocated lov_user_md.
481  * The caller is responsible for freeing the returned pointer.
482  *
483  * \param[in] layout    the layout to copy from
484  *
485  * \retval      valid lov_user_md pointer on success
486  * \retval      NULL if memory allocation fails or the layout is invalid
487  */
488 static struct lov_user_md *
489 llapi_layout_to_lum(const struct llapi_layout *layout)
490 {
491         struct llapi_layout_comp *comp;
492         struct lov_comp_md_v1 *comp_v1 = NULL;
493         struct lov_comp_md_entry_v1 *ent;
494         struct lov_user_md *lum = NULL;
495         size_t lum_size = 0;
496         int ent_idx = 0;
497         uint32_t offset = 0;
498
499         if (layout == NULL ||
500             list_empty((struct list_head *)&layout->llot_comp_list)) {
501                 errno = EINVAL;
502                 return NULL;
503         }
504
505         /* Allocate header of lov_comp_md_v1 if necessary */
506         if (layout->llot_is_composite) {
507                 int comp_cnt = 0;
508
509                 list_for_each_entry(comp, &layout->llot_comp_list, llc_list)
510                         comp_cnt++;
511
512                 lum_size = sizeof(*comp_v1) + comp_cnt * sizeof(*ent);
513                 lum = calloc(lum_size, 1);
514                 if (lum == NULL) {
515                         errno = ENOMEM;
516                         return NULL;
517                 }
518                 comp_v1 = (struct lov_comp_md_v1 *)lum;
519                 comp_v1->lcm_magic = LOV_USER_MAGIC_COMP_V1;
520                 comp_v1->lcm_size = lum_size;
521                 comp_v1->lcm_layout_gen = 0;
522                 comp_v1->lcm_flags = layout->llot_flags;
523                 comp_v1->lcm_entry_count = comp_cnt;
524                 comp_v1->lcm_mirror_count = layout->llot_mirror_count - 1;
525                 offset += lum_size;
526         }
527
528         list_for_each_entry(comp, &layout->llot_comp_list, llc_list) {
529                 struct lov_user_md *blob;
530                 size_t blob_size;
531                 uint32_t magic;
532                 int i, obj_count = 0;
533                 struct lov_user_ost_data *lmm_objects;
534                 uint64_t pattern = comp->llc_pattern;
535
536                 if ((pattern & LLAPI_LAYOUT_SPECIFIC) != 0) {
537                         if (comp->llc_objects_count <
538                             comp->llc_stripe_count) {
539                                 errno = EINVAL;
540                                 goto error;
541                         }
542                         magic = LOV_USER_MAGIC_SPECIFIC;
543                         obj_count = comp->llc_stripe_count;
544                         pattern &= ~LLAPI_LAYOUT_SPECIFIC;
545                 } else if (strlen(comp->llc_pool_name) != 0) {
546                         magic = LOV_USER_MAGIC_V3;
547                 } else {
548                         magic = LOV_USER_MAGIC_V1;
549                 }
550                 /* All stripes must be specified when the pattern contains
551                  * LLAPI_LAYOUT_SPECIFIC */
552                 for (i = 0; i < obj_count; i++) {
553                         if (comp->llc_objects[i].l_ost_idx ==
554                             LLAPI_LAYOUT_IDX_MAX) {
555                                 errno = EINVAL;
556                                 goto error;
557                         }
558                 }
559
560                 blob_size = lov_user_md_size(obj_count, magic);
561                 blob = realloc(lum, lum_size + blob_size);
562                 if (blob == NULL) {
563                         errno = ENOMEM;
564                         goto error;
565                 } else {
566                         lum = blob;
567                         comp_v1 = (struct lov_comp_md_v1 *)lum;
568                         blob = (struct lov_user_md *)((char *)lum + lum_size);
569                         lum_size += blob_size;
570                 }
571
572                 blob->lmm_magic = magic;
573                 if (pattern == LLAPI_LAYOUT_DEFAULT)
574                         blob->lmm_pattern = LOV_PATTERN_RAID0;
575                 else if (pattern == LLAPI_LAYOUT_MDT)
576                         blob->lmm_pattern = LOV_PATTERN_MDT;
577                 else
578                         blob->lmm_pattern = pattern;
579
580                 if (comp->llc_stripe_size == LLAPI_LAYOUT_DEFAULT)
581                         blob->lmm_stripe_size = 0;
582                 else
583                         blob->lmm_stripe_size = comp->llc_stripe_size;
584
585                 if (comp->llc_stripe_count == LLAPI_LAYOUT_DEFAULT)
586                         blob->lmm_stripe_count = 0;
587                 else if (comp->llc_stripe_count == LLAPI_LAYOUT_WIDE)
588                         blob->lmm_stripe_count = LOV_ALL_STRIPES;
589                 else
590                         blob->lmm_stripe_count = comp->llc_stripe_count;
591
592                 if (comp->llc_stripe_offset == LLAPI_LAYOUT_DEFAULT)
593                         blob->lmm_stripe_offset = -1;
594                 else
595                         blob->lmm_stripe_offset = comp->llc_stripe_offset;
596
597                 if (magic == LOV_USER_MAGIC_V3 ||
598                     magic == LOV_USER_MAGIC_SPECIFIC) {
599                         struct lov_user_md_v3 *lumv3 =
600                                 (struct lov_user_md_v3 *)blob;
601
602                         if (comp->llc_pool_name[0] != '\0') {
603                                 strncpy(lumv3->lmm_pool_name,
604                                         comp->llc_pool_name,
605                                         sizeof(lumv3->lmm_pool_name));
606                         } else {
607                                 memset(lumv3->lmm_pool_name, 0,
608                                        sizeof(lumv3->lmm_pool_name));
609                         }
610                         lmm_objects = lumv3->lmm_objects;
611                 } else {
612                         lmm_objects = blob->lmm_objects;
613                 }
614
615                 for (i = 0; i < obj_count; i++)
616                         lmm_objects[i].l_ost_idx =
617                                 comp->llc_objects[i].l_ost_idx;
618
619                 if (layout->llot_is_composite) {
620                         ent = &comp_v1->lcm_entries[ent_idx];
621                         ent->lcme_id = comp->llc_id;
622                         ent->lcme_flags = comp->llc_flags;
623                         ent->lcme_extent.e_start = comp->llc_extent.e_start;
624                         ent->lcme_extent.e_end = comp->llc_extent.e_end;
625                         ent->lcme_size = blob_size;
626                         ent->lcme_offset = offset;
627                         offset += blob_size;
628                         comp_v1->lcm_size += blob_size;
629                         ent_idx++;
630                 } else {
631                         break;
632                 }
633         }
634
635         return lum;
636 error:
637         free(lum);
638         return NULL;
639 }
640
641 /**
642  * Get the parent directory of a path.
643  *
644  * \param[in] path      path to get parent of
645  * \param[out] buf      buffer in which to store parent path
646  * \param[in] size      size in bytes of buffer \a buf
647  */
648 static void get_parent_dir(const char *path, char *buf, size_t size)
649 {
650         char *p;
651
652         strncpy(buf, path, size);
653         p = strrchr(buf, '/');
654
655         if (p != NULL) {
656                 *p = '\0';
657         } else if (size >= 2) {
658                 strncpy(buf, ".", 2);
659                 buf[size - 1] = '\0';
660         }
661 }
662
663 /**
664  * Substitute unspecified attribute values in \a layout with values
665  * from fs global settings. (lov.stripesize, lov.stripecount,
666  * lov.stripeoffset)
667  *
668  * \param[in] layout    layout to inherit values from
669  * \param[in] path      file path of the filesystem
670  */
671 static void inherit_sys_attributes(struct llapi_layout *layout,
672                                    const char *path)
673 {
674         struct llapi_layout_comp *comp;
675         unsigned int ssize, scount, soffset;
676         int rc;
677
678         rc = sattr_cache_get_defaults(NULL, path, &scount, &ssize, &soffset);
679         if (rc)
680                 return;
681
682         list_for_each_entry(comp, &layout->llot_comp_list, llc_list) {
683                 if (comp->llc_pattern == LLAPI_LAYOUT_DEFAULT)
684                         comp->llc_pattern = LLAPI_LAYOUT_RAID0;
685                 if (comp->llc_stripe_size == LLAPI_LAYOUT_DEFAULT)
686                         comp->llc_stripe_size = ssize;
687                 if (comp->llc_stripe_count == LLAPI_LAYOUT_DEFAULT)
688                         comp->llc_stripe_count = scount;
689                 if (comp->llc_stripe_offset == LLAPI_LAYOUT_DEFAULT)
690                         comp->llc_stripe_offset = soffset;
691         }
692 }
693
694 /**
695  * Get the current component of \a layout.
696  *
697  * \param[in] layout    layout to get current component
698  *
699  * \retval      valid llapi_layout_comp pointer on success
700  * \retval      NULL on error
701  */
702 static struct llapi_layout_comp *
703 __llapi_layout_cur_comp(const struct llapi_layout *layout)
704 {
705         struct llapi_layout_comp *comp;
706
707         if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
708                 errno = EINVAL;
709                 return NULL;
710         }
711         if (layout->llot_cur_comp == NULL) {
712                 errno = EINVAL;
713                 return NULL;
714         }
715         /* Verify data consistency */
716         list_for_each_entry(comp, &layout->llot_comp_list, llc_list)
717                 if (comp == layout->llot_cur_comp)
718                         return comp;
719         errno = EFAULT;
720         return NULL;
721 }
722
723 /**
724  * Test if any attributes of \a layout are specified.
725  *
726  * \param[in] layout    the layout to check
727  *
728  * \retval true         any attributes are specified
729  * \retval false        all attributes are unspecified
730  */
731 static bool is_any_specified(const struct llapi_layout *layout)
732 {
733         struct llapi_layout_comp *comp;
734
735         comp = __llapi_layout_cur_comp(layout);
736         if (comp == NULL)
737                 return false;
738
739         if (layout->llot_is_composite || layout->llot_mirror_count != 1)
740                 return true;
741
742         return comp->llc_pattern != LLAPI_LAYOUT_DEFAULT ||
743                comp->llc_stripe_size != LLAPI_LAYOUT_DEFAULT ||
744                comp->llc_stripe_count != LLAPI_LAYOUT_DEFAULT ||
745                comp->llc_stripe_offset != LLAPI_LAYOUT_DEFAULT ||
746                strlen(comp->llc_pool_name);
747 }
748
749 /**
750  * Check if the given \a lum_size is large enough to hold the required
751  * fields in \a lum.
752  *
753  * \param[in] lum       the struct lov_user_md to check
754  * \param[in] lum_size  the number of bytes in \a lum
755  *
756  * \retval true         the \a lum_size is too small
757  * \retval false        the \a lum_size is large enough
758  */
759 static bool llapi_layout_lum_truncated(struct lov_user_md *lum, size_t lum_size)
760 {
761         uint32_t magic;
762
763         if (lum_size < sizeof(lum->lmm_magic))
764                 return true;
765
766         if (lum->lmm_magic == LOV_MAGIC_V1 ||
767             lum->lmm_magic == __swab32(LOV_MAGIC_V1))
768                 magic = LOV_MAGIC_V1;
769         else if (lum->lmm_magic == LOV_MAGIC_V3 ||
770                  lum->lmm_magic == __swab32(LOV_MAGIC_V3))
771                 magic = LOV_MAGIC_V3;
772         else if (lum->lmm_magic == LOV_MAGIC_COMP_V1 ||
773                  lum->lmm_magic == __swab32(LOV_MAGIC_COMP_V1))
774                 magic = LOV_MAGIC_COMP_V1;
775         else
776                 return true;
777
778         if (magic == LOV_MAGIC_V1 || magic == LOV_MAGIC_V3)
779                 return lum_size < lov_user_md_size(0, magic);
780         else
781                 return lum_size < sizeof(struct lov_comp_md_v1);
782 }
783
784 /* Verify if the objects count in lum is consistent with the
785  * stripe count in lum. It applies to regular file only. */
786 static bool llapi_layout_lum_valid(struct lov_user_md *lum, int lum_size)
787 {
788         struct lov_comp_md_v1 *comp_v1 = NULL;
789         int i, ent_count, obj_count;
790
791         if (lum->lmm_magic == LOV_MAGIC_COMP_V1) {
792                 comp_v1 = (struct lov_comp_md_v1 *)lum;
793                 ent_count = comp_v1->lcm_entry_count;
794         } else if (lum->lmm_magic == LOV_MAGIC_V1 ||
795                    lum->lmm_magic == LOV_MAGIC_V3) {
796                 ent_count = 1;
797         } else {
798                 return false;
799         }
800
801         for (i = 0; i < ent_count; i++) {
802                 if (comp_v1) {
803                         lum = (struct lov_user_md *)((char *)comp_v1 +
804                                 comp_v1->lcm_entries[i].lcme_offset);
805                         lum_size = comp_v1->lcm_entries[i].lcme_size;
806                 }
807                 obj_count = llapi_layout_objects_in_lum(lum, lum_size);
808
809                 if (comp_v1) {
810                         if (!(comp_v1->lcm_entries[i].lcme_flags &
811                                  LCME_FL_INIT) && obj_count != 0)
812                                 return false;
813                 } else if (obj_count != lum->lmm_stripe_count) {
814                         return false;
815                 }
816         }
817         return true;
818 }
819
820 /**
821  * Get the striping layout for the file referenced by file descriptor \a fd.
822  *
823  * If the filesystem does not support the "lustre." xattr namespace, the
824  * file must be on a non-Lustre filesystem, so set errno to ENOTTY per
825  * convention.  If the file has no "lustre.lov" data, the file will
826  * inherit default values, so return a default layout.
827  *
828  * If the kernel gives us back less than the expected amount of data,
829  * we fail with errno set to EINTR.
830  *
831  * \param[in] fd        open file descriptor
832  * \param[in] flags     open file descriptor
833  *
834  * \retval      valid llapi_layout pointer on success
835  * \retval      NULL if an error occurs
836  */
837 struct llapi_layout *llapi_layout_get_by_fd(int fd, uint32_t flags)
838 {
839         size_t lum_len;
840         struct lov_user_md *lum;
841         struct llapi_layout *layout = NULL;
842         ssize_t bytes_read;
843         struct stat st;
844
845         lum_len = XATTR_SIZE_MAX;
846         lum = malloc(lum_len);
847         if (lum == NULL)
848                 return NULL;
849
850         bytes_read = fgetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_len);
851         if (bytes_read < 0) {
852                 if (errno == EOPNOTSUPP)
853                         errno = ENOTTY;
854                 else if (errno == ENODATA)
855                         layout = llapi_layout_alloc();
856                 goto out;
857         }
858
859         /* Return an error if we got back a partial layout. */
860         if (llapi_layout_lum_truncated(lum, bytes_read)) {
861                 errno = EINTR;
862                 goto out;
863         }
864
865         llapi_layout_swab_lov_user_md(lum, bytes_read);
866
867         /* Directories may have a positive non-zero lum->lmm_stripe_count
868          * yet have an empty lum->lmm_objects array. For non-directories the
869          * amount of data returned from the kernel must be consistent
870          * with the stripe count. */
871         if (fstat(fd, &st) < 0)
872                 goto out;
873
874         if (!S_ISDIR(st.st_mode) && !llapi_layout_lum_valid(lum, bytes_read)) {
875                 errno = EINTR;
876                 goto out;
877         }
878
879         layout = llapi_layout_from_lum(lum, bytes_read);
880 out:
881         free(lum);
882         return layout;
883 }
884
885 /**
886  * Get the expected striping layout for a file at \a path.
887  *
888  * Substitute expected inherited attribute values for unspecified
889  * attributes.  Unspecified attributes may belong to directories and
890  * never-written-to files, and indicate that default values will be
891  * assigned when files are created or first written to.  A default value
892  * is inherited from the parent directory if the attribute is specified
893  * there, otherwise it is inherited from the filesystem root.
894  * Unspecified attributes normally have the value LLAPI_LAYOUT_DEFAULT.
895  *
896  * The complete \a path need not refer to an existing file or directory,
897  * but some leading portion of it must reside within a lustre filesystem.
898  * A use case for this interface would be to obtain the literal striping
899  * values that would be assigned to a new file in a given directory.
900  *
901  * \param[in] path      path for which to get the expected layout
902  *
903  * \retval      valid llapi_layout pointer on success
904  * \retval      NULL if an error occurs
905  */
906 static struct llapi_layout *llapi_layout_expected(const char *path)
907 {
908         struct llapi_layout     *path_layout = NULL;
909         char                    donor_path[PATH_MAX];
910         struct stat st;
911         int fd;
912         int rc;
913
914         fd = open(path, O_RDONLY);
915         if (fd < 0 && errno != ENOENT)
916                 return NULL;
917
918         if (fd >= 0) {
919                 int tmp;
920
921                 path_layout = llapi_layout_get_by_fd(fd, 0);
922                 tmp = errno;
923                 close(fd);
924                 errno = tmp;
925         }
926
927         if (path_layout == NULL) {
928                 if (errno != ENODATA && errno != ENOENT)
929                         return NULL;
930
931                 path_layout = llapi_layout_alloc();
932                 if (path_layout == NULL)
933                         return NULL;
934         }
935
936         if (is_any_specified(path_layout)) {
937                 inherit_sys_attributes(path_layout, path);
938                 return path_layout;
939         }
940
941         llapi_layout_free(path_layout);
942
943         rc = stat(path, &st);
944         if (rc < 0 && errno != ENOENT)
945                 return NULL;
946
947         /* If path is a not a directory or doesn't exist, inherit layout
948          * from parent directory. */
949         if ((rc == 0 && !S_ISDIR(st.st_mode)) ||
950             (rc < 0 && errno == ENOENT)) {
951                 get_parent_dir(path, donor_path, sizeof(donor_path));
952                 path_layout = llapi_layout_get_by_path(donor_path, 0);
953                 if (path_layout != NULL) {
954                         if (is_any_specified(path_layout)) {
955                                 inherit_sys_attributes(path_layout, donor_path);
956                                 return path_layout;
957                         }
958                         llapi_layout_free(path_layout);
959                 }
960         }
961
962         /* Inherit layout from the filesystem root. */
963         rc = llapi_search_mounts(path, 0, donor_path, NULL);
964         if (rc < 0)
965                 return NULL;
966         path_layout = llapi_layout_get_by_path(donor_path, 0);
967         if (path_layout == NULL)
968                 return NULL;
969
970         inherit_sys_attributes(path_layout, donor_path);
971         return path_layout;
972 }
973
974 /**
975  * Get the striping layout for the file at \a path.
976  *
977  * If \a flags contains LAYOUT_GET_EXPECTED, substitute
978  * expected inherited attribute values for unspecified attributes. See
979  * llapi_layout_expected().
980  *
981  * \param[in] path      path for which to get the layout
982  * \param[in] flags     flags to control how layout is retrieved
983  *
984  * \retval      valid llapi_layout pointer on success
985  * \retval      NULL if an error occurs
986  */
987 struct llapi_layout *llapi_layout_get_by_path(const char *path, uint32_t flags)
988 {
989         struct llapi_layout *layout = NULL;
990         int fd;
991         int tmp;
992
993         if (flags & LAYOUT_GET_EXPECTED)
994                 return llapi_layout_expected(path);
995
996         fd = open(path, O_RDONLY);
997         if (fd < 0)
998                 return layout;
999
1000         layout = llapi_layout_get_by_fd(fd, flags);
1001         tmp = errno;
1002         close(fd);
1003         errno = tmp;
1004
1005         return layout;
1006 }
1007
1008 /**
1009  * Get the layout for the file with FID \a fidstr in filesystem \a lustre_dir.
1010  *
1011  * \param[in] lustre_dir        path within Lustre filesystem containing \a fid
1012  * \param[in] fid               Lustre identifier of file to get layout for
1013  *
1014  * \retval      valid llapi_layout pointer on success
1015  * \retval      NULL if an error occurs
1016  */
1017 struct llapi_layout *llapi_layout_get_by_fid(const char *lustre_dir,
1018                                              const lustre_fid *fid,
1019                                              uint32_t flags)
1020 {
1021         int fd;
1022         int tmp;
1023         int saved_msg_level = llapi_msg_get_level();
1024         struct llapi_layout *layout = NULL;
1025
1026         /* Prevent llapi internal routines from writing to console
1027          * while executing this function, then restore previous message
1028          * level. */
1029         llapi_msg_set_level(LLAPI_MSG_OFF);
1030         fd = llapi_open_by_fid(lustre_dir, fid, O_RDONLY);
1031         llapi_msg_set_level(saved_msg_level);
1032
1033         if (fd < 0)
1034                 return NULL;
1035
1036         layout = llapi_layout_get_by_fd(fd, flags);
1037         tmp = errno;
1038         close(fd);
1039         errno = tmp;
1040
1041         return layout;
1042 }
1043
1044 /**
1045  * Get the stripe count of \a layout.
1046  *
1047  * \param[in] layout    layout to get stripe count from
1048  * \param[out] count    integer to store stripe count in
1049  *
1050  * \retval      0 on success
1051  * \retval      -1 if arguments are invalid
1052  */
1053 int llapi_layout_stripe_count_get(const struct llapi_layout *layout,
1054                                   uint64_t *count)
1055 {
1056         struct llapi_layout_comp *comp;
1057
1058         comp = __llapi_layout_cur_comp(layout);
1059         if (comp == NULL)
1060                 return -1;
1061
1062         if (count == NULL) {
1063                 errno = EINVAL;
1064                 return -1;
1065         }
1066
1067         *count = comp->llc_stripe_count;
1068
1069         return 0;
1070 }
1071
1072 /*
1073  * The llapi_layout API functions have these extra validity checks since
1074  * they use intuitively named macros to denote special behavior, whereas
1075  * the old API uses 0 and -1.
1076  */
1077
1078 static bool llapi_layout_stripe_count_is_valid(int64_t stripe_count)
1079 {
1080         return stripe_count == LLAPI_LAYOUT_DEFAULT ||
1081                 stripe_count == LLAPI_LAYOUT_WIDE ||
1082                 (stripe_count != 0 && stripe_count != -1 &&
1083                  llapi_stripe_count_is_valid(stripe_count));
1084 }
1085
1086 static bool llapi_layout_stripe_size_is_valid(uint64_t stripe_size)
1087 {
1088         return stripe_size == LLAPI_LAYOUT_DEFAULT ||
1089                 (stripe_size != 0 &&
1090                  llapi_stripe_size_is_aligned(stripe_size) &&
1091                  !llapi_stripe_size_is_too_big(stripe_size));
1092 }
1093
1094 static bool llapi_layout_stripe_index_is_valid(int64_t stripe_index)
1095 {
1096         return stripe_index == LLAPI_LAYOUT_DEFAULT ||
1097                 (stripe_index >= 0 &&
1098                 llapi_stripe_index_is_valid(stripe_index));
1099 }
1100
1101 /**
1102  * Set the stripe count of \a layout.
1103  *
1104  * \param[in] layout    layout to set stripe count in
1105  * \param[in] count     value to be set
1106  *
1107  * \retval      0 on success
1108  * \retval      -1 if arguments are invalid
1109  */
1110 int llapi_layout_stripe_count_set(struct llapi_layout *layout,
1111                                   uint64_t count)
1112 {
1113         struct llapi_layout_comp *comp;
1114
1115         comp = __llapi_layout_cur_comp(layout);
1116         if (comp == NULL)
1117                 return -1;
1118
1119         if (!llapi_layout_stripe_count_is_valid(count)) {
1120                 errno = EINVAL;
1121                 return -1;
1122         }
1123
1124         comp->llc_stripe_count = count;
1125
1126         return 0;
1127 }
1128
1129 /**
1130  * Get the stripe size of \a layout.
1131  *
1132  * \param[in] layout    layout to get stripe size from
1133  * \param[out] size     integer to store stripe size in
1134  *
1135  * \retval      0 on success
1136  * \retval      -1 if arguments are invalid
1137  */
1138 int llapi_layout_stripe_size_get(const struct llapi_layout *layout,
1139                                  uint64_t *size)
1140 {
1141         struct llapi_layout_comp *comp;
1142
1143         comp = __llapi_layout_cur_comp(layout);
1144         if (comp == NULL)
1145                 return -1;
1146
1147         if (size == NULL) {
1148                 errno = EINVAL;
1149                 return -1;
1150         }
1151
1152         *size = comp->llc_stripe_size;
1153
1154         return 0;
1155 }
1156
1157 /**
1158  * Set the stripe size of \a layout.
1159  *
1160  * \param[in] layout    layout to set stripe size in
1161  * \param[in] size      value to be set
1162  *
1163  * \retval      0 on success
1164  * \retval      -1 if arguments are invalid
1165  */
1166 int llapi_layout_stripe_size_set(struct llapi_layout *layout,
1167                                  uint64_t size)
1168 {
1169         struct llapi_layout_comp *comp;
1170
1171         comp = __llapi_layout_cur_comp(layout);
1172         if (comp == NULL)
1173                 return -1;
1174
1175         if (!llapi_layout_stripe_size_is_valid(size)) {
1176                 errno = EINVAL;
1177                 return -1;
1178         }
1179
1180         comp->llc_stripe_size = size;
1181
1182         return 0;
1183 }
1184
1185 /**
1186  * Get the RAID pattern of \a layout.
1187  *
1188  * \param[in] layout    layout to get pattern from
1189  * \param[out] pattern  integer to store pattern in
1190  *
1191  * \retval      0 on success
1192  * \retval      -1 if arguments are invalid
1193  */
1194 int llapi_layout_pattern_get(const struct llapi_layout *layout,
1195                              uint64_t *pattern)
1196 {
1197         struct llapi_layout_comp *comp;
1198
1199         comp = __llapi_layout_cur_comp(layout);
1200         if (comp == NULL)
1201                 return -1;
1202
1203         if (pattern == NULL) {
1204                 errno = EINVAL;
1205                 return -1;
1206         }
1207
1208         *pattern = comp->llc_pattern;
1209
1210         return 0;
1211 }
1212
1213 /**
1214  * Set the pattern of \a layout.
1215  *
1216  * \param[in] layout    layout to set pattern in
1217  * \param[in] pattern   value to be set
1218  *
1219  * \retval      0 on success
1220  * \retval      -1 if arguments are invalid or RAID pattern
1221  *              is unsupported
1222  */
1223 int llapi_layout_pattern_set(struct llapi_layout *layout, uint64_t pattern)
1224 {
1225         struct llapi_layout_comp *comp;
1226
1227         comp = __llapi_layout_cur_comp(layout);
1228         if (comp == NULL)
1229                 return -1;
1230
1231         if (pattern != LLAPI_LAYOUT_DEFAULT &&
1232             pattern != LLAPI_LAYOUT_RAID0 && pattern != LLAPI_LAYOUT_MDT) {
1233                 errno = EOPNOTSUPP;
1234                 return -1;
1235         }
1236
1237         comp->llc_pattern = pattern |
1238                             (comp->llc_pattern & LLAPI_LAYOUT_SPECIFIC);
1239
1240         return 0;
1241 }
1242
1243 static inline int stripe_number_roundup(int stripe_number)
1244 {
1245         unsigned int round_up = (stripe_number + 8) & ~7;
1246         return round_up > LOV_MAX_STRIPE_COUNT ?
1247                 LOV_MAX_STRIPE_COUNT : round_up;
1248 }
1249
1250 /**
1251  * Set the OST index of stripe number \a stripe_number to \a ost_index.
1252  *
1253  * If only the starting stripe's OST index is specified, then this can use
1254  * the normal LOV_MAGIC_{V1,V3} layout type.  If multiple OST indices are
1255  * given, then allocate an array to hold the list of indices and ensure that
1256  * the LOV_USER_MAGIC_SPECIFIC layout is used when creating the file.
1257  *
1258  * \param[in] layout            layout to set OST index in
1259  * \param[in] stripe_number     stripe number to set index for
1260  * \param[in] ost_index         the index to set
1261  *
1262  * \retval      0 on success
1263  * \retval      -1 if arguments are invalid or an unsupported stripe number
1264  *              was specified, error returned in errno
1265  */
1266 int llapi_layout_ost_index_set(struct llapi_layout *layout, int stripe_number,
1267                                uint64_t ost_index)
1268 {
1269         struct llapi_layout_comp *comp;
1270
1271         comp = __llapi_layout_cur_comp(layout);
1272         if (comp == NULL)
1273                 return -1;
1274
1275         if (!llapi_layout_stripe_index_is_valid(ost_index)) {
1276                 errno = EINVAL;
1277                 return -1;
1278         }
1279
1280         if (stripe_number == 0 && ost_index == LLAPI_LAYOUT_DEFAULT) {
1281                 comp->llc_stripe_offset = ost_index;
1282                 comp->llc_pattern &= ~LLAPI_LAYOUT_SPECIFIC;
1283                 __llapi_comp_objects_realloc(comp, 0);
1284         } else if (stripe_number >= 0 &&
1285                    stripe_number < LOV_MAX_STRIPE_COUNT) {
1286                 if (ost_index >= LLAPI_LAYOUT_IDX_MAX) {
1287                         errno = EINVAL;
1288                         return -1;
1289                 }
1290
1291                 /* Preallocate a few more stripes to avoid realloc() overhead.*/
1292                 if (__llapi_comp_objects_realloc(comp,
1293                                 stripe_number_roundup(stripe_number)) < 0)
1294                         return -1;
1295
1296                 comp->llc_objects[stripe_number].l_ost_idx = ost_index;
1297
1298                 if (stripe_number == 0)
1299                         comp->llc_stripe_offset = ost_index;
1300                 else
1301                         comp->llc_pattern |= LLAPI_LAYOUT_SPECIFIC;
1302
1303                 if (comp->llc_stripe_count == LLAPI_LAYOUT_DEFAULT ||
1304                     comp->llc_stripe_count <= stripe_number)
1305                         comp->llc_stripe_count = stripe_number + 1;
1306         } else {
1307                 errno = EINVAL;
1308                 return -1;
1309         }
1310
1311         return 0;
1312 }
1313
1314 /**
1315  * Get the OST index associated with stripe \a stripe_number.
1316  *
1317  * Stripes are indexed starting from zero.
1318  *
1319  * \param[in] layout            layout to get index from
1320  * \param[in] stripe_number     stripe number to get index for
1321  * \param[out] index            integer to store index in
1322  *
1323  * \retval      0 on success
1324  * \retval      -1 if arguments are invalid
1325  */
1326 int llapi_layout_ost_index_get(const struct llapi_layout *layout,
1327                                uint64_t stripe_number, uint64_t *index)
1328 {
1329         struct llapi_layout_comp *comp;
1330
1331         comp = __llapi_layout_cur_comp(layout);
1332         if (comp == NULL)
1333                 return -1;
1334
1335         if (index == NULL) {
1336                 errno = EINVAL;
1337                 return -1;
1338         }
1339
1340         if (stripe_number >= comp->llc_stripe_count ||
1341             stripe_number >= comp->llc_objects_count) {
1342                 errno = EINVAL;
1343                 return -1;
1344         }
1345
1346         if (comp->llc_stripe_offset == LLAPI_LAYOUT_DEFAULT)
1347                 *index = LLAPI_LAYOUT_DEFAULT;
1348         else
1349                 *index = comp->llc_objects[stripe_number].l_ost_idx;
1350
1351         return 0;
1352 }
1353
1354 /**
1355  *
1356  * Get the pool name of layout \a layout.
1357  *
1358  * \param[in] layout    layout to get pool name from
1359  * \param[out] dest     buffer to store pool name in
1360  * \param[in] n         size in bytes of buffer \a dest
1361  *
1362  * \retval      0 on success
1363  * \retval      -1 if arguments are invalid
1364  */
1365 int llapi_layout_pool_name_get(const struct llapi_layout *layout, char *dest,
1366                                size_t n)
1367 {
1368         struct llapi_layout_comp *comp;
1369
1370         comp = __llapi_layout_cur_comp(layout);
1371         if (comp == NULL)
1372                 return -1;
1373
1374         if (dest == NULL) {
1375                 errno = EINVAL;
1376                 return -1;
1377         }
1378
1379         strncpy(dest, comp->llc_pool_name, n);
1380
1381         return 0;
1382 }
1383
1384 /**
1385  * Set the name of the pool of layout \a layout.
1386  *
1387  * \param[in] layout    layout to set pool name in
1388  * \param[in] pool_name pool name to set
1389  *
1390  * \retval      0 on success
1391  * \retval      -1 if arguments are invalid or pool name is too long
1392  */
1393 int llapi_layout_pool_name_set(struct llapi_layout *layout,
1394                                const char *pool_name)
1395 {
1396         struct llapi_layout_comp *comp;
1397         char *ptr;
1398
1399         comp = __llapi_layout_cur_comp(layout);
1400         if (comp == NULL)
1401                 return -1;
1402
1403         if (pool_name == NULL) {
1404                 errno = EINVAL;
1405                 return -1;
1406         }
1407
1408         /* Strip off any 'fsname.' portion. */
1409         ptr = strchr(pool_name, '.');
1410         if (ptr != NULL)
1411                 pool_name = ptr + 1;
1412
1413         if (strlen(pool_name) > LOV_MAXPOOLNAME) {
1414                 errno = EINVAL;
1415                 return -1;
1416         }
1417
1418         strncpy(comp->llc_pool_name, pool_name, sizeof(comp->llc_pool_name));
1419
1420         return 0;
1421 }
1422
1423 /**
1424  * Open and possibly create a file with a given \a layout.
1425  *
1426  * If \a layout is NULL this function acts as a simple wrapper for
1427  * open().  By convention, ENOTTY is returned in errno if \a path
1428  * refers to a non-Lustre file.
1429  *
1430  * \param[in] path              name of the file to open
1431  * \param[in] open_flags        open() flags
1432  * \param[in] mode              permissions to create new file with
1433  * \param[in] layout            layout to create new file with
1434  *
1435  * \retval              non-negative file descriptor on successful open
1436  * \retval              -1 if an error occurred
1437  */
1438 int llapi_layout_file_open(const char *path, int open_flags, mode_t mode,
1439                            const struct llapi_layout *layout)
1440 {
1441         int fd;
1442         int rc;
1443         int tmp;
1444         struct lov_user_md *lum;
1445         size_t lum_size;
1446
1447         if (path == NULL ||
1448             (layout != NULL && layout->llot_magic != LLAPI_LAYOUT_MAGIC)) {
1449                 errno = EINVAL;
1450                 return -1;
1451         }
1452
1453         /* Object creation must be postponed until after layout attributes
1454          * have been applied. */
1455         if (layout != NULL && (open_flags & O_CREAT))
1456                 open_flags |= O_LOV_DELAY_CREATE;
1457
1458         fd = open(path, open_flags, mode);
1459
1460         if (layout == NULL || fd < 0)
1461                 return fd;
1462
1463         lum = llapi_layout_to_lum(layout);
1464
1465         if (lum == NULL) {
1466                 tmp = errno;
1467                 close(fd);
1468                 errno = tmp;
1469                 return -1;
1470         }
1471
1472         if (lum->lmm_magic == LOV_USER_MAGIC_COMP_V1)
1473                 lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
1474         else if (lum->lmm_magic == LOV_USER_MAGIC_SPECIFIC)
1475                 lum_size = lov_user_md_size(lum->lmm_stripe_count,
1476                                             lum->lmm_magic);
1477         else
1478                 lum_size = lov_user_md_size(0, lum->lmm_magic);
1479
1480         rc = fsetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_size, 0);
1481         if (rc < 0) {
1482                 tmp = errno;
1483                 close(fd);
1484                 errno = tmp;
1485                 fd = -1;
1486         }
1487
1488         free(lum);
1489         errno = errno == EOPNOTSUPP ? ENOTTY : errno;
1490
1491         return fd;
1492 }
1493
1494 /**
1495  * Create a file with a given \a layout.
1496  *
1497  * Force O_CREAT and O_EXCL flags on so caller is assured that file was
1498  * created with the given \a layout on successful function return.
1499  *
1500  * \param[in] path              name of the file to open
1501  * \param[in] open_flags        open() flags
1502  * \param[in] mode              permissions to create new file with
1503  * \param[in] layout            layout to create new file with
1504  *
1505  * \retval              non-negative file descriptor on successful open
1506  * \retval              -1 if an error occurred
1507  */
1508 int llapi_layout_file_create(const char *path, int open_flags, int mode,
1509                              const struct llapi_layout *layout)
1510 {
1511         return llapi_layout_file_open(path, open_flags|O_CREAT|O_EXCL, mode,
1512                                       layout);
1513 }
1514
1515 int llapi_layout_flags_get(struct llapi_layout *layout, uint32_t *flags)
1516 {
1517         if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1518                 errno = EINVAL;
1519                 return -1;
1520         }
1521
1522         *flags = layout->llot_flags;
1523         return 0;
1524 }
1525
1526 /**
1527  * Set flags to the header of a component layout.
1528  */
1529 int llapi_layout_flags_set(struct llapi_layout *layout, uint32_t flags)
1530 {
1531         if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1532                 errno = EINVAL;
1533                 return -1;
1534         }
1535
1536         layout->llot_flags = flags;
1537         return 0;
1538 }
1539
1540 /**
1541  * llapi_layout_mirror_count_is_valid() - Check the validity of mirror count.
1542  * @count: Mirror count value to be checked.
1543  *
1544  * This function checks the validity of mirror count.
1545  *
1546  * Return: true on success or false on failure.
1547  */
1548 static bool llapi_layout_mirror_count_is_valid(uint16_t count)
1549 {
1550         return count >= 0 && count <= LUSTRE_MIRROR_COUNT_MAX;
1551 }
1552
1553 /**
1554  * llapi_layout_mirror_count_get() - Get mirror count from the header of
1555  *                                   a layout.
1556  * @layout: Layout to get mirror count from.
1557  * @count:  Returned mirror count value.
1558  *
1559  * This function gets mirror count from the header of a layout.
1560  *
1561  * Return: 0 on success or -1 on failure.
1562  */
1563 int llapi_layout_mirror_count_get(struct llapi_layout *layout,
1564                                   uint16_t *count)
1565 {
1566         if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1567                 errno = EINVAL;
1568                 return -1;
1569         }
1570
1571         *count = layout->llot_mirror_count;
1572         return 0;
1573 }
1574
1575 /**
1576  * llapi_layout_mirror_count_set() - Set mirror count to the header of a layout.
1577  * @layout: Layout to set mirror count in.
1578  * @count:  Mirror count value to be set.
1579  *
1580  * This function sets mirror count to the header of a layout.
1581  *
1582  * Return: 0 on success or -1 on failure.
1583  */
1584 int llapi_layout_mirror_count_set(struct llapi_layout *layout,
1585                                   uint16_t count)
1586 {
1587         if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1588                 errno = EINVAL;
1589                 return -1;
1590         }
1591
1592         if (!llapi_layout_mirror_count_is_valid(count)) {
1593                 errno = EINVAL;
1594                 return -1;
1595         }
1596
1597         layout->llot_mirror_count = count;
1598         return 0;
1599 }
1600
1601 /**
1602  * Fetch the start and end offset of the current layout component.
1603  *
1604  * \param[in] layout    the layout component
1605  * \param[out] start    extent start, inclusive
1606  * \param[out] end      extent end, exclusive
1607  *
1608  * \retval      0 on success
1609  * \retval      <0 if error occurs
1610  */
1611 int llapi_layout_comp_extent_get(const struct llapi_layout *layout,
1612                                  uint64_t *start, uint64_t *end)
1613 {
1614         struct llapi_layout_comp *comp;
1615
1616         comp = __llapi_layout_cur_comp(layout);
1617         if (comp == NULL)
1618                 return -1;
1619
1620         if (start == NULL || end == NULL) {
1621                 errno = EINVAL;
1622                 return -1;
1623         }
1624
1625         *start = comp->llc_extent.e_start;
1626         *end = comp->llc_extent.e_end;
1627
1628         return 0;
1629 }
1630
1631 /**
1632  * Set the layout extent of a layout.
1633  *
1634  * \param[in] layout    the layout to be set
1635  * \param[in] start     extent start, inclusive
1636  * \param[in] end       extent end, exclusive
1637  *
1638  * \retval      0 on success
1639  * \retval      <0 if error occurs
1640  */
1641 int llapi_layout_comp_extent_set(struct llapi_layout *layout,
1642                                  uint64_t start, uint64_t end)
1643 {
1644         struct llapi_layout_comp *prev, *next, *comp;
1645
1646         comp = __llapi_layout_cur_comp(layout);
1647         if (comp == NULL)
1648                 return -1;
1649
1650         if (start >= end) {
1651                 errno = EINVAL;
1652                 return -1;
1653         }
1654
1655         /*
1656          * We need to make sure the extent to be set is valid: the new
1657          * extent must be adjacent with the prev & next component.
1658          */
1659         if (comp->llc_list.prev != &layout->llot_comp_list) {
1660                 prev = list_entry(comp->llc_list.prev, typeof(*prev),
1661                                   llc_list);
1662                 if (start != prev->llc_extent.e_end) {
1663                         errno = EINVAL;
1664                         return -1;
1665                 }
1666         }
1667
1668         if (comp->llc_list.next != &layout->llot_comp_list) {
1669                 next = list_entry(comp->llc_list.next, typeof(*next),
1670                                   llc_list);
1671                 if (end != next->llc_extent.e_start) {
1672                         errno = EINVAL;
1673                         return -1;
1674                 }
1675         }
1676
1677         comp->llc_extent.e_start = start;
1678         comp->llc_extent.e_end = end;
1679         layout->llot_is_composite = true;
1680
1681         return 0;
1682 }
1683
1684 /**
1685  * Gets the attribute flags of the current component.
1686  *
1687  * \param[in] layout    the layout component
1688  * \param[out] flags    stored the returned component flags
1689  *
1690  * \retval      0 on success
1691  * \retval      <0 if error occurs
1692  */
1693 int llapi_layout_comp_flags_get(const struct llapi_layout *layout,
1694                                 uint32_t *flags)
1695 {
1696         struct llapi_layout_comp *comp;
1697
1698         comp = __llapi_layout_cur_comp(layout);
1699         if (comp == NULL)
1700                 return -1;
1701
1702         if (flags == NULL) {
1703                 errno = EINVAL;
1704                 return -1;
1705         }
1706
1707         *flags = comp->llc_flags;
1708
1709         return 0;
1710 }
1711
1712 /**
1713  * Sets the specified flags of the current component leaving other flags as-is.
1714  *
1715  * \param[in] layout    the layout component
1716  * \param[in] flags     component flags to be set
1717  *
1718  * \retval      0 on success
1719  * \retval      <0 if error occurs
1720  */
1721 int llapi_layout_comp_flags_set(struct llapi_layout *layout, uint32_t flags)
1722 {
1723         struct llapi_layout_comp *comp;
1724
1725         comp = __llapi_layout_cur_comp(layout);
1726         if (comp == NULL)
1727                 return -1;
1728
1729         comp->llc_flags |= flags;
1730
1731         return 0;
1732 }
1733
1734 /**
1735  * Clears the flags specified in the flags leaving other flags as-is.
1736  *
1737  * \param[in] layout    the layout component
1738  * \param[in] flags     component flags to be cleared
1739  *
1740  * \retval      0 on success
1741  * \retval      <0 if error occurs
1742  */
1743 int llapi_layout_comp_flags_clear(struct llapi_layout *layout,
1744                                   uint32_t flags)
1745 {
1746         struct llapi_layout_comp *comp;
1747
1748         comp = __llapi_layout_cur_comp(layout);
1749         if (comp == NULL)
1750                 return -1;
1751
1752         comp->llc_flags &= ~flags;
1753
1754         return 0;
1755 }
1756
1757 /**
1758  * Fetches the file-unique component ID of the current layout component.
1759  *
1760  * \param[in] layout    the layout component
1761  * \param[out] id       stored the returned component ID
1762  *
1763  * \retval      0 on success
1764  * \retval      <0 if error occurs
1765  */
1766 int llapi_layout_comp_id_get(const struct llapi_layout *layout, uint32_t *id)
1767 {
1768         struct llapi_layout_comp *comp;
1769
1770         comp = __llapi_layout_cur_comp(layout);
1771         if (comp == NULL)
1772                 return -1;
1773
1774         if (id == NULL) {
1775                 errno = EINVAL;
1776                 return -1;
1777         }
1778         *id = comp->llc_id;
1779
1780         return 0;
1781 }
1782
1783 /**
1784  * Return the mirror id of the current layout component.
1785  *
1786  * \param[in] layout    the layout component
1787  * \param[out] id       stored the returned mirror ID
1788  *
1789  * \retval      0 on success
1790  * \retval      <0 if error occurs
1791  */
1792 int llapi_layout_mirror_id_get(const struct llapi_layout *layout, uint32_t *id)
1793 {
1794         struct llapi_layout_comp *comp;
1795
1796         comp = __llapi_layout_cur_comp(layout);
1797         if (comp == NULL)
1798                 return -1;
1799
1800         if (id == NULL) {
1801                 errno = EINVAL;
1802                 return -1;
1803         }
1804
1805         *id = mirror_id_of(comp->llc_id);
1806
1807         return 0;
1808 }
1809
1810 /**
1811  * Adds a component to \a layout, the new component will be added to
1812  * the tail of components list and it'll inherit attributes of existing
1813  * ones. The \a layout will change it's current component pointer to
1814  * the newly added component, and it'll be turned into a composite
1815  * layout if it was not before the adding.
1816  *
1817  * \param[in] layout    existing composite or plain layout
1818  *
1819  * \retval      0 on success
1820  * \retval      <0 if error occurs
1821  */
1822 int llapi_layout_comp_add(struct llapi_layout *layout)
1823 {
1824         struct llapi_layout_comp *last, *comp, *new;
1825
1826         comp = __llapi_layout_cur_comp(layout);
1827         if (comp == NULL)
1828                 return -1;
1829
1830         new = __llapi_comp_alloc(0);
1831         if (new == NULL)
1832                 return -1;
1833
1834         last = list_entry(layout->llot_comp_list.prev, typeof(*last),
1835                           llc_list);
1836
1837         if (new->llc_extent.e_end <= last->llc_extent.e_end) {
1838                 __llapi_comp_free(new);
1839                 errno = EINVAL;
1840                 return -1;
1841         }
1842         new->llc_extent.e_start = last->llc_extent.e_end;
1843
1844         list_add_tail(&new->llc_list, &layout->llot_comp_list);
1845         layout->llot_cur_comp = new;
1846         layout->llot_is_composite = true;
1847
1848         return 0;
1849 }
1850
1851 /**
1852  * Deletes current component from the composite layout. The component
1853  * to be deleted must be the tail of components list, and it can't be
1854  * the only component in the layout.
1855  *
1856  * \param[in] layout    composite layout
1857  *
1858  * \retval      0 on success
1859  * \retval      <0 if error occurs
1860  */
1861 int llapi_layout_comp_del(struct llapi_layout *layout)
1862 {
1863         struct llapi_layout_comp *comp;
1864
1865         comp = __llapi_layout_cur_comp(layout);
1866         if (comp == NULL)
1867                 return -1;
1868
1869         if (!layout->llot_is_composite) {
1870                 errno = EINVAL;
1871                 return -1;
1872         }
1873
1874         /* It must be the tail of the list (for PFL, can be relaxed
1875          * once we get mirrored components) */
1876         if (comp->llc_list.next != &layout->llot_comp_list) {
1877                 errno = EINVAL;
1878                 return -1;
1879         }
1880         /* It can't be the only one on the list */
1881         if (comp->llc_list.prev == &layout->llot_comp_list) {
1882                 errno = EINVAL;
1883                 return -1;
1884         }
1885
1886         layout->llot_cur_comp =
1887                 list_entry(comp->llc_list.prev, typeof(*comp), llc_list);
1888         list_del_init(&comp->llc_list);
1889         __llapi_comp_free(comp);
1890
1891         return 0;
1892 }
1893
1894 /**
1895  * Move the current component pointer to the component with
1896  * specified component ID.
1897  *
1898  * \param[in] layout    composite layout
1899  * \param[in] id        component ID
1900  *
1901  * \retval      =0 : moved successfully
1902  * \retval      <0 if error occurs
1903  */
1904 int llapi_layout_comp_use_id(struct llapi_layout *layout, uint32_t comp_id)
1905 {
1906         struct llapi_layout_comp *comp;
1907
1908         comp = __llapi_layout_cur_comp(layout);
1909         if (comp == NULL)
1910                 return -1; /* use previously set errno */
1911
1912         if (!layout->llot_is_composite) {
1913                 errno = EINVAL;
1914                 return -1;
1915         }
1916
1917         if (comp_id == LCME_ID_INVAL) {
1918                 errno = EINVAL;
1919                 return -1;
1920         }
1921
1922         list_for_each_entry(comp, &layout->llot_comp_list, llc_list) {
1923                 if (comp->llc_id == comp_id) {
1924                         layout->llot_cur_comp = comp;
1925                         return 0;
1926                 }
1927         }
1928         errno = ENOENT;
1929         return -1;
1930 }
1931
1932 /**
1933  * Move the current component pointer to a specified position.
1934  *
1935  * \param[in] layout    composite layout
1936  * \param[in] pos       the position to be moved, it can be:
1937  *                      LLAPI_LAYOUT_COMP_USE_FIRST: use first component
1938  *                      LLAPI_LAYOUT_COMP_USE_LAST: use last component
1939  *                      LLAPI_LAYOUT_COMP_USE_NEXT: use component after current
1940  *                      LLAPI_LAYOUT_COMP_USE_PREV: use component before current
1941  *
1942  * \retval      =0 : moved successfully
1943  * \retval      =1 : at last component with NEXT, at first component with PREV
1944  * \retval      <0 if error occurs
1945  */
1946 int llapi_layout_comp_use(struct llapi_layout *layout,
1947                           enum llapi_layout_comp_use pos)
1948 {
1949         struct llapi_layout_comp *comp, *head, *tail;
1950
1951         comp = __llapi_layout_cur_comp(layout);
1952         if (comp == NULL)
1953                 return -1;
1954
1955         if (!layout->llot_is_composite) {
1956                 if (pos == LLAPI_LAYOUT_COMP_USE_FIRST ||
1957                     pos == LLAPI_LAYOUT_COMP_USE_LAST)
1958                         return 0;
1959                 errno = ENOENT;
1960                 return 1;
1961         }
1962
1963         head = list_entry(layout->llot_comp_list.next, typeof(*head), llc_list);
1964         tail = list_entry(layout->llot_comp_list.prev, typeof(*tail), llc_list);
1965         switch (pos) {
1966         case LLAPI_LAYOUT_COMP_USE_FIRST:
1967                 layout->llot_cur_comp = head;
1968                 break;
1969         case LLAPI_LAYOUT_COMP_USE_NEXT:
1970                 if (comp == tail) {
1971                         errno = ENOENT;
1972                         return 1;
1973                 }
1974                 layout->llot_cur_comp = list_entry(comp->llc_list.next,
1975                                                    typeof(*comp), llc_list);
1976                 break;
1977         case LLAPI_LAYOUT_COMP_USE_LAST:
1978                 layout->llot_cur_comp = tail;
1979                 break;
1980         case LLAPI_LAYOUT_COMP_USE_PREV:
1981                 if (comp == head) {
1982                         errno = ENOENT;
1983                         return 1;
1984                 }
1985                 layout->llot_cur_comp = list_entry(comp->llc_list.prev,
1986                                                    typeof(*comp), llc_list);
1987                 break;
1988         default:
1989                 errno = EINVAL;
1990                 return -1;
1991         }
1992
1993         return 0;
1994 }
1995
1996 /**
1997  * Add layout component(s) to an existing file.
1998  *
1999  * \param[in] path      The path name of the file
2000  * \param[in] layout    The layout component(s) to be added
2001  */
2002 int llapi_layout_file_comp_add(const char *path,
2003                                const struct llapi_layout *layout)
2004 {
2005         int rc, fd, lum_size, tmp_errno = 0;
2006         struct lov_user_md *lum;
2007
2008         if (path == NULL || layout == NULL ||
2009             layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
2010                 errno = EINVAL;
2011                 return -1;
2012         }
2013
2014         lum = llapi_layout_to_lum(layout);
2015         if (lum == NULL)
2016                 return -1;
2017
2018         if (lum->lmm_magic != LOV_USER_MAGIC_COMP_V1) {
2019                 free(lum);
2020                 errno = EINVAL;
2021                 return -1;
2022         }
2023         lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
2024
2025         fd = open(path, O_RDWR);
2026         if (fd < 0) {
2027                 tmp_errno = errno;
2028                 rc = -1;
2029                 goto out;
2030         }
2031
2032         rc = fsetxattr(fd, XATTR_LUSTRE_LOV".add", lum, lum_size, 0);
2033         if (rc < 0) {
2034                 tmp_errno = errno;
2035                 close(fd);
2036                 rc = -1;
2037                 goto out;
2038         }
2039         close(fd);
2040 out:
2041         free(lum);
2042         errno = tmp_errno;
2043         return rc;
2044 }
2045
2046 /**
2047  * Delete component(s) by the specified component id or component flags
2048  * from an existing file.
2049  *
2050  * \param[in] path      path name of the file
2051  * \param[in] id        unique component ID
2052  * \param[in] flags     flags: LCME_FL_* or;
2053  *                      negative flags: (LCME_FL_NEG|LCME_FL_*)
2054  */
2055 int llapi_layout_file_comp_del(const char *path, uint32_t id, uint32_t flags)
2056 {
2057         int rc, fd, lum_size;
2058         struct llapi_layout *layout;
2059         struct llapi_layout_comp *comp;
2060         struct lov_user_md *lum;
2061
2062         if (path == NULL || id > LCME_ID_MAX || (flags & ~LCME_KNOWN_FLAGS)) {
2063                 errno = EINVAL;
2064                 return -1;
2065         }
2066
2067         /* Can only specify ID or flags, not both. */
2068         if (id != 0 && flags != 0) {
2069                 errno = EINVAL;
2070                 return -1;
2071         }
2072
2073         layout = llapi_layout_alloc();
2074         if (layout == NULL)
2075                 return -1;
2076
2077         llapi_layout_comp_extent_set(layout, 0, LUSTRE_EOF);
2078         comp = __llapi_layout_cur_comp(layout);
2079         if (comp == NULL) {
2080                 llapi_layout_free(layout);
2081                 return -1;
2082         }
2083
2084         comp->llc_id = id;
2085         comp->llc_flags = flags;
2086
2087         lum = llapi_layout_to_lum(layout);
2088         if (lum == NULL) {
2089                 llapi_layout_free(layout);
2090                 return -1;
2091         }
2092         lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
2093
2094         fd = open(path, O_RDWR);
2095         if (fd < 0) {
2096                 rc = -1;
2097                 goto out;
2098         }
2099
2100         rc = fsetxattr(fd, XATTR_LUSTRE_LOV".del", lum, lum_size, 0);
2101         if (rc < 0) {
2102                 int tmp_errno = errno;
2103                 close(fd);
2104                 errno = tmp_errno;
2105                 rc = -1;
2106                 goto out;
2107         }
2108         close(fd);
2109 out:
2110         free(lum);
2111         llapi_layout_free(layout);
2112         return rc;
2113 }
2114
2115 /**
2116  * Change flags or other parameters of the component(s) by component ID of an
2117  * existing file. The component to be modified is specified by the
2118  * comp->lcme_id value, which must be an unique component ID. The new
2119  * attributes are passed in by @comp and @valid is used to specify which
2120  * attributes in the component are going to be changed.
2121  */
2122 int llapi_layout_file_comp_set(const char *path,
2123                                const struct llapi_layout *comp,
2124                                uint32_t valid)
2125 {
2126         errno = EOPNOTSUPP;
2127         return -1;
2128 }
2129
2130 /**
2131  * Check if the file layout is composite.
2132  *
2133  * \param[in] layout    the file layout to check
2134  *
2135  * \retval true         composite
2136  * \retval false        not composite
2137  */
2138 bool llapi_layout_is_composite(struct llapi_layout *layout)
2139 {
2140         return layout->llot_is_composite;
2141 }
2142
2143 /**
2144  * llapi_layout_merge() - Merge a composite layout into another one.
2145  * @dst_layout: Destination composite layout.
2146  * @src_layout: Source composite layout.
2147  *
2148  * This function copies all of the components from @src_layout and
2149  * appends them to @dst_layout.
2150  *
2151  * Return: 0 on success or -1 on failure.
2152  */
2153 int llapi_layout_merge(struct llapi_layout **dst_layout,
2154                        const struct llapi_layout *src_layout)
2155 {
2156         struct llapi_layout *new_layout = *dst_layout;
2157         struct llapi_layout_comp *new = NULL;
2158         struct llapi_layout_comp *comp = NULL;
2159         int i = 0;
2160
2161         if (src_layout == NULL ||
2162             list_empty((struct list_head *)&src_layout->llot_comp_list))
2163                 return 0;
2164
2165         if (new_layout == NULL) {
2166                 new_layout = __llapi_layout_alloc();
2167                 if (new_layout == NULL) {
2168                         errno = ENOMEM;
2169                         return -1;
2170                 }
2171         }
2172
2173         list_for_each_entry(comp, &src_layout->llot_comp_list, llc_list) {
2174                 new = __llapi_comp_alloc(0);
2175                 if (new == NULL) {
2176                         errno = ENOMEM;
2177                         goto error;
2178                 }
2179
2180                 new->llc_pattern = comp->llc_pattern;
2181                 new->llc_stripe_size = comp->llc_stripe_size;
2182                 new->llc_stripe_count = comp->llc_stripe_count;
2183                 new->llc_stripe_offset = comp->llc_stripe_offset;
2184
2185                 if (comp->llc_pool_name[0] != '\0')
2186                         strncpy(new->llc_pool_name, comp->llc_pool_name,
2187                                 sizeof(new->llc_pool_name));
2188
2189                 for (i = 0; i < comp->llc_objects_count; i++) {
2190                         if (__llapi_comp_objects_realloc(new,
2191                             stripe_number_roundup(i)) < 0) {
2192                                 errno = EINVAL;
2193                                 __llapi_comp_free(new);
2194                                 goto error;
2195                         }
2196                         new->llc_objects[i].l_ost_idx = \
2197                                 comp->llc_objects[i].l_ost_idx;
2198                 }
2199
2200                 new->llc_objects_count = comp->llc_objects_count;
2201                 new->llc_extent.e_start = comp->llc_extent.e_start;
2202                 new->llc_extent.e_end = comp->llc_extent.e_end;
2203                 new->llc_id = comp->llc_id;
2204                 new->llc_flags = comp->llc_flags;
2205
2206                 list_add_tail(&new->llc_list, &new_layout->llot_comp_list);
2207                 new_layout->llot_cur_comp = new;
2208         }
2209         new_layout->llot_is_composite = true;
2210
2211         *dst_layout = new_layout;
2212         return 0;
2213 error:
2214         llapi_layout_free(new_layout);
2215         return -1;
2216 }