Whamcloud - gitweb
LU-10420 flr: split a mirror from mirrored file
[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, 2017, 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 <assert.h>
38 #include <sys/xattr.h>
39 #include <sys/param.h>
40
41 #include <libcfs/util/list.h>
42 #include <lustre/lustreapi.h>
43 #include "lustreapi_internal.h"
44
45 /**
46  * Layout component, which contains all attributes of a plain
47  * V1/V3 layout.
48  */
49 struct llapi_layout_comp {
50         uint64_t        llc_pattern;
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
64                                                    components list */
65 };
66
67 /**
68  * An Opaque data type abstracting the layout of a Lustre file.
69  */
70 struct llapi_layout {
71         uint32_t        llot_magic; /* LLAPI_LAYOUT_MAGIC */
72         uint32_t        llot_gen;
73         uint32_t        llot_flags;
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;
79 };
80
81 /**
82  * Compute the number of elements in the lmm_objects array of \a lum
83  * with size \a lum_size.
84  *
85  * \param[in] lum       the struct lov_user_md to check
86  * \param[in] lum_size  the number of bytes in \a lum
87  *
88  * \retval              number of elements in array lum->lmm_objects
89  */
90 static int llapi_layout_objects_in_lum(struct lov_user_md *lum, size_t lum_size)
91 {
92         uint32_t magic;
93         size_t base_size;
94
95         if (lum_size < lov_user_md_size(0, LOV_MAGIC_V1))
96                 return 0;
97
98         if (lum->lmm_magic == __swab32(LOV_MAGIC_V1) ||
99             lum->lmm_magic == __swab32(LOV_MAGIC_V3))
100                 magic = __swab32(lum->lmm_magic);
101         else
102                 magic = lum->lmm_magic;
103
104         base_size = lov_user_md_size(0, magic);
105
106         if (lum_size <= base_size)
107                 return 0;
108         else
109                 return (lum_size - base_size) / sizeof(lum->lmm_objects[0]);
110 }
111
112 /**
113  * Byte-swap the fields of struct lov_user_md.
114  *
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.
118  */
119 static void
120 llapi_layout_swab_lov_user_md(struct lov_user_md *lum, int lum_size)
121 {
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;
126
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))
130                 return;
131
132         if (lum->lmm_magic == __swab32(LOV_MAGIC_COMP_V1))
133                 comp_v1 = (struct lov_comp_md_v1 *)lum;
134
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;
142         } else {
143                 ent_count = 1;
144         }
145
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);
155
156                         lum = (struct lov_user_md *)((char *)comp_v1 +
157                                         ent->lcme_offset);
158                         lum_size = ent->lcme_size;
159                 }
160                 obj_count = llapi_layout_objects_in_lum(lum, lum_size);
161
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);
167
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;
172                 } else {
173                         lod = lum->lmm_objects;
174                 }
175
176                 for (j = 0; j < obj_count; j++)
177                         __swab32s(&lod[j].l_ost_idx);
178         }
179 }
180
181 /**
182  * (Re-)allocate llc_objects[] to \a num_stripes stripes.
183  *
184  * Copy over existing llc_objects[], if any, to the new llc_objects[].
185  *
186  * \param[in] layout            existing layout to be modified
187  * \param[in] num_stripes       number of stripes in new layout
188  *
189  * \retval      0 if the objects are re-allocated successfully
190  * \retval      -1 on error with errno set
191  */
192 static int __llapi_comp_objects_realloc(struct llapi_layout_comp *comp,
193                                         unsigned int new_stripes)
194 {
195         struct lov_user_ost_data_v1 *new_objects;
196         unsigned int i;
197
198         if (new_stripes > LOV_MAX_STRIPE_COUNT) {
199                 errno = EINVAL;
200                 return -1;
201         }
202
203         if (new_stripes == comp->llc_objects_count)
204                 return 0;
205
206         if (new_stripes != 0 && new_stripes <= comp->llc_objects_count)
207                 return 0;
208
209         new_objects = realloc(comp->llc_objects,
210                               sizeof(*new_objects) * new_stripes);
211         if (new_objects == NULL && new_stripes != 0) {
212                 errno = ENOMEM;
213                 return -1;
214         }
215
216         for (i = comp->llc_objects_count; i < new_stripes; i++)
217                 new_objects[i].l_ost_idx = LLAPI_LAYOUT_IDX_MAX;
218
219         comp->llc_objects = new_objects;
220         comp->llc_objects_count = new_stripes;
221
222         return 0;
223 }
224
225 /**
226  * Allocate storage for a llapi_layout_comp with \a num_stripes stripes.
227  *
228  * \param[in] num_stripes       number of stripes in new layout
229  *
230  * \retval      valid pointer if allocation succeeds
231  * \retval      NULL if allocation fails
232  */
233 static struct llapi_layout_comp *__llapi_comp_alloc(unsigned int num_stripes)
234 {
235         struct llapi_layout_comp *comp;
236
237         if (num_stripes > LOV_MAX_STRIPE_COUNT) {
238                 errno = EINVAL;
239                 return NULL;
240         }
241
242         comp = calloc(1, sizeof(*comp));
243         if (comp == NULL) {
244                 errno = ENOMEM;
245                 return NULL;
246         }
247
248         comp->llc_objects = NULL;
249         comp->llc_objects_count = 0;
250
251         if (__llapi_comp_objects_realloc(comp, num_stripes) < 0) {
252                 free(comp);
253                 return NULL;
254         }
255
256         /* Set defaults. */
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;
264         comp->llc_flags = 0;
265         comp->llc_id = 0;
266         INIT_LIST_HEAD(&comp->llc_list);
267
268         return comp;
269 }
270
271 /**
272  * Free memory allocated for \a comp
273  *
274  * \param[in] comp      previously allocated by __llapi_comp_alloc()
275  */
276 static void __llapi_comp_free(struct llapi_layout_comp *comp)
277 {
278         if (comp->llc_objects != NULL)
279                 free(comp->llc_objects);
280         free(comp);
281 }
282
283 /**
284  * Free memory allocated for \a layout.
285  *
286  * \param[in] layout    previously allocated by llapi_layout_alloc()
287  */
288 void llapi_layout_free(struct llapi_layout *layout)
289 {
290         struct llapi_layout_comp *comp, *n;
291
292         if (layout == NULL)
293                 return;
294
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);
298         }
299         free(layout);
300 }
301
302 /**
303  * Allocate and initialize a llapi_layout structure.
304  *
305  * \retval      valid llapi_layout pointer on success
306  * \retval      NULL if memory allocation fails
307  */
308 static struct llapi_layout *__llapi_layout_alloc(void)
309 {
310         struct llapi_layout *layout;
311
312         layout = calloc(1, sizeof(*layout));
313         if (layout == NULL) {
314                 errno = ENOMEM;
315                 return NULL;
316         }
317
318         /* Set defaults. */
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);
326
327         return layout;
328 }
329
330 /**
331  * Allocate and initialize a new plain layout.
332  *
333  * \retval      valid llapi_layout pointer on success
334  * \retval      NULL if memory allocation fails
335  */
336 struct llapi_layout *llapi_layout_alloc(void)
337 {
338         struct llapi_layout_comp *comp;
339         struct llapi_layout *layout;
340
341         layout = __llapi_layout_alloc();
342         if (layout == NULL)
343                 return NULL;
344
345         comp = __llapi_comp_alloc(0);
346         if (comp == NULL) {
347                 free(layout);
348                 return NULL;
349         }
350
351         list_add_tail(&comp->llc_list, &layout->llot_comp_list);
352         layout->llot_cur_comp = comp;
353
354         return layout;
355 }
356
357 /**
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.
360  *
361  * \param[in] lum       LOV user metadata structure to copy data from
362  * \param[in] lum_size  size the the lum passed in
363  *
364  * \retval              valid llapi_layout pointer on success
365  * \retval              NULL if memory allocation fails
366  */
367 static struct llapi_layout *
368 llapi_layout_from_lum(const struct lov_user_md *lum, int lum_size)
369 {
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;
376
377         layout = __llapi_layout_alloc();
378         if (layout == NULL)
379                 return NULL;
380
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) {
391                 ent_count = 1;
392                 layout->llot_is_composite = false;
393         }
394
395         if (ent_count == 0) {
396                 errno = EINVAL;
397                 goto error;
398         }
399
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 +
405                                 ent->lcme_offset);
406                         lum_size = ent->lcme_size;
407                 } else {
408                         ent = NULL;
409                 }
410
411                 obj_count = llapi_layout_objects_in_lum(v1, lum_size);
412                 comp = __llapi_comp_alloc(obj_count);
413                 if (comp == NULL)
414                         goto error;
415
416                 if (ent != NULL) {
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;
421                 } else {
422                         comp->llc_extent.e_start = 0;
423                         comp->llc_extent.e_end = LUSTRE_EOF;
424                         comp->llc_id = 0;
425                         comp->llc_flags = 0;
426                 }
427
428                 if (v1->lmm_pattern == LOV_PATTERN_RAID0)
429                         comp->llc_pattern = LLAPI_LAYOUT_RAID0;
430                 else
431                         /* Lustre only supports RAID0 for now. */
432                         comp->llc_pattern = v1->lmm_pattern;
433
434                 if (v1->lmm_stripe_size == 0)
435                         comp->llc_stripe_size = LLAPI_LAYOUT_DEFAULT;
436                 else
437                         comp->llc_stripe_size = v1->lmm_stripe_size;
438
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;
443                 else
444                         comp->llc_stripe_count = v1->lmm_stripe_count;
445
446                 if (v1->lmm_stripe_offset ==
447                     (typeof(v1->lmm_stripe_offset))-1)
448                         comp->llc_stripe_offset = LLAPI_LAYOUT_DEFAULT;
449                 else
450                         comp->llc_stripe_offset = v1->lmm_stripe_offset;
451
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]));
460                 } else {
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]));
465                 }
466
467                 if (obj_count != 0)
468                         comp->llc_stripe_offset =
469                                 comp->llc_objects[0].l_ost_idx;
470
471                 list_add_tail(&comp->llc_list, &layout->llot_comp_list);
472                 layout->llot_cur_comp = comp;
473         }
474
475         return layout;
476 error:
477         llapi_layout_free(layout);
478         return NULL;
479 }
480
481 /**
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.
484  *
485  * \param[in] layout    the layout to copy from
486  *
487  * \retval      valid lov_user_md pointer on success
488  * \retval      NULL if memory allocation fails or the layout is invalid
489  */
490 static struct lov_user_md *
491 llapi_layout_to_lum(const struct llapi_layout *layout)
492 {
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;
497         size_t lum_size = 0;
498         int ent_idx = 0;
499         uint32_t offset = 0;
500
501         if (layout == NULL ||
502             list_empty((struct list_head *)&layout->llot_comp_list)) {
503                 errno = EINVAL;
504                 return NULL;
505         }
506
507         /* Allocate header of lov_comp_md_v1 if necessary */
508         if (layout->llot_is_composite) {
509                 int comp_cnt = 0;
510
511                 list_for_each_entry(comp, &layout->llot_comp_list, llc_list)
512                         comp_cnt++;
513
514                 lum_size = sizeof(*comp_v1) + comp_cnt * sizeof(*ent);
515                 lum = calloc(lum_size, 1);
516                 if (lum == NULL) {
517                         errno = ENOMEM;
518                         return NULL;
519                 }
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;
527                 offset += lum_size;
528         }
529
530         list_for_each_entry(comp, &layout->llot_comp_list, llc_list) {
531                 struct lov_user_md *blob;
532                 size_t blob_size;
533                 uint32_t magic;
534                 int i, obj_count = 0;
535                 struct lov_user_ost_data *lmm_objects;
536                 uint64_t pattern = comp->llc_pattern;
537
538                 if ((pattern & LLAPI_LAYOUT_SPECIFIC) != 0) {
539                         if (comp->llc_objects_count <
540                             comp->llc_stripe_count) {
541                                 errno = EINVAL;
542                                 goto error;
543                         }
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;
549                 } else {
550                         magic = LOV_USER_MAGIC_V1;
551                 }
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) {
557                                 errno = EINVAL;
558                                 goto error;
559                         }
560                 }
561
562                 blob_size = lov_user_md_size(obj_count, magic);
563                 blob = realloc(lum, lum_size + blob_size);
564                 if (blob == NULL) {
565                         errno = ENOMEM;
566                         goto error;
567                 } else {
568                         lum = blob;
569                         comp_v1 = (struct lov_comp_md_v1 *)lum;
570                         blob = (struct lov_user_md *)((char *)lum + lum_size);
571                         lum_size += blob_size;
572                 }
573
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;
579                 else
580                         blob->lmm_pattern = pattern;
581
582                 if (comp->llc_stripe_size == LLAPI_LAYOUT_DEFAULT)
583                         blob->lmm_stripe_size = 0;
584                 else
585                         blob->lmm_stripe_size = comp->llc_stripe_size;
586
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;
591                 else
592                         blob->lmm_stripe_count = comp->llc_stripe_count;
593
594                 if (comp->llc_stripe_offset == LLAPI_LAYOUT_DEFAULT)
595                         blob->lmm_stripe_offset = -1;
596                 else
597                         blob->lmm_stripe_offset = comp->llc_stripe_offset;
598
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;
603
604                         if (comp->llc_pool_name[0] != '\0') {
605                                 strncpy(lumv3->lmm_pool_name,
606                                         comp->llc_pool_name,
607                                         sizeof(lumv3->lmm_pool_name));
608                         } else {
609                                 memset(lumv3->lmm_pool_name, 0,
610                                        sizeof(lumv3->lmm_pool_name));
611                         }
612                         lmm_objects = lumv3->lmm_objects;
613                 } else {
614                         lmm_objects = blob->lmm_objects;
615                 }
616
617                 for (i = 0; i < obj_count; i++)
618                         lmm_objects[i].l_ost_idx =
619                                 comp->llc_objects[i].l_ost_idx;
620
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;
629                         offset += blob_size;
630                         comp_v1->lcm_size += blob_size;
631                         ent_idx++;
632                 } else {
633                         break;
634                 }
635         }
636
637         return lum;
638 error:
639         free(lum);
640         return NULL;
641 }
642
643 /**
644  * Get the parent directory of a path.
645  *
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
649  */
650 static void get_parent_dir(const char *path, char *buf, size_t size)
651 {
652         char *p;
653
654         strncpy(buf, path, size);
655         p = strrchr(buf, '/');
656
657         if (p != NULL) {
658                 *p = '\0';
659         } else if (size >= 2) {
660                 strncpy(buf, ".", 2);
661                 buf[size - 1] = '\0';
662         }
663 }
664
665 /**
666  * Substitute unspecified attribute values in \a layout with values
667  * from fs global settings. (lov.stripesize, lov.stripecount,
668  * lov.stripeoffset)
669  *
670  * \param[in] layout    layout to inherit values from
671  * \param[in] path      file path of the filesystem
672  */
673 static void inherit_sys_attributes(struct llapi_layout *layout,
674                                    const char *path)
675 {
676         struct llapi_layout_comp *comp;
677         unsigned int ssize, scount, soffset;
678         int rc;
679
680         rc = sattr_cache_get_defaults(NULL, path, &scount, &ssize, &soffset);
681         if (rc)
682                 return;
683
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;
693         }
694 }
695
696 /**
697  * Get the current component of \a layout.
698  *
699  * \param[in] layout    layout to get current component
700  *
701  * \retval      valid llapi_layout_comp pointer on success
702  * \retval      NULL on error
703  */
704 static struct llapi_layout_comp *
705 __llapi_layout_cur_comp(const struct llapi_layout *layout)
706 {
707         struct llapi_layout_comp *comp;
708
709         if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
710                 errno = EINVAL;
711                 return NULL;
712         }
713         if (layout->llot_cur_comp == NULL) {
714                 errno = EINVAL;
715                 return NULL;
716         }
717         /* Verify data consistency */
718         list_for_each_entry(comp, &layout->llot_comp_list, llc_list)
719                 if (comp == layout->llot_cur_comp)
720                         return comp;
721         errno = EFAULT;
722         return NULL;
723 }
724
725 /**
726  * Test if any attributes of \a layout are specified.
727  *
728  * \param[in] layout    the layout to check
729  *
730  * \retval true         any attributes are specified
731  * \retval false        all attributes are unspecified
732  */
733 static bool is_any_specified(const struct llapi_layout *layout)
734 {
735         struct llapi_layout_comp *comp;
736
737         comp = __llapi_layout_cur_comp(layout);
738         if (comp == NULL)
739                 return false;
740
741         if (layout->llot_is_composite || layout->llot_mirror_count != 1)
742                 return true;
743
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);
749 }
750
751 /**
752  * Check if the given \a lum_size is large enough to hold the required
753  * fields in \a lum.
754  *
755  * \param[in] lum       the struct lov_user_md to check
756  * \param[in] lum_size  the number of bytes in \a lum
757  *
758  * \retval true         the \a lum_size is too small
759  * \retval false        the \a lum_size is large enough
760  */
761 static bool llapi_layout_lum_truncated(struct lov_user_md *lum, size_t lum_size)
762 {
763         uint32_t magic;
764
765         if (lum_size < sizeof(lum->lmm_magic))
766                 return true;
767
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;
777         else
778                 return true;
779
780         if (magic == LOV_MAGIC_V1 || magic == LOV_MAGIC_V3)
781                 return lum_size < lov_user_md_size(0, magic);
782         else
783                 return lum_size < sizeof(struct lov_comp_md_v1);
784 }
785
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)
789 {
790         struct lov_comp_md_v1 *comp_v1 = NULL;
791         int i, ent_count, obj_count;
792
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) {
798                 ent_count = 1;
799         } else {
800                 return false;
801         }
802
803         for (i = 0; i < ent_count; i++) {
804                 if (comp_v1) {
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;
808                 }
809                 obj_count = llapi_layout_objects_in_lum(lum, lum_size);
810
811                 if (comp_v1) {
812                         if (!(comp_v1->lcm_entries[i].lcme_flags &
813                                  LCME_FL_INIT) && obj_count != 0)
814                                 return false;
815                 } else if (obj_count != lum->lmm_stripe_count) {
816                         return false;
817                 }
818         }
819         return true;
820 }
821
822 /**
823  * Get the striping layout for the file referenced by file descriptor \a fd.
824  *
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.
829  *
830  * If the kernel gives us back less than the expected amount of data,
831  * we fail with errno set to EINTR.
832  *
833  * \param[in] fd        open file descriptor
834  * \param[in] flags     open file descriptor
835  *
836  * \retval      valid llapi_layout pointer on success
837  * \retval      NULL if an error occurs
838  */
839 struct llapi_layout *llapi_layout_get_by_fd(int fd, uint32_t flags)
840 {
841         size_t lum_len;
842         struct lov_user_md *lum;
843         struct llapi_layout *layout = NULL;
844         ssize_t bytes_read;
845         struct stat st;
846
847         lum_len = XATTR_SIZE_MAX;
848         lum = malloc(lum_len);
849         if (lum == NULL)
850                 return NULL;
851
852         bytes_read = fgetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_len);
853         if (bytes_read < 0) {
854                 if (errno == EOPNOTSUPP)
855                         errno = ENOTTY;
856                 else if (errno == ENODATA)
857                         layout = llapi_layout_alloc();
858                 goto out;
859         }
860
861         /* Return an error if we got back a partial layout. */
862         if (llapi_layout_lum_truncated(lum, bytes_read)) {
863                 errno = EINTR;
864                 goto out;
865         }
866
867         llapi_layout_swab_lov_user_md(lum, bytes_read);
868
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)
874                 goto out;
875
876         if (!S_ISDIR(st.st_mode) && !llapi_layout_lum_valid(lum, bytes_read)) {
877                 errno = EINTR;
878                 goto out;
879         }
880
881         layout = llapi_layout_from_lum(lum, bytes_read);
882 out:
883         free(lum);
884         return layout;
885 }
886
887 /**
888  * Get the expected striping layout for a file at \a path.
889  *
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.
897  *
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.
902  *
903  * \param[in] path      path for which to get the expected layout
904  *
905  * \retval      valid llapi_layout pointer on success
906  * \retval      NULL if an error occurs
907  */
908 static struct llapi_layout *llapi_layout_expected(const char *path)
909 {
910         struct llapi_layout     *path_layout = NULL;
911         char                    donor_path[PATH_MAX];
912         struct stat st;
913         int fd;
914         int rc;
915
916         fd = open(path, O_RDONLY);
917         if (fd < 0 && errno != ENOENT)
918                 return NULL;
919
920         if (fd >= 0) {
921                 int tmp;
922
923                 path_layout = llapi_layout_get_by_fd(fd, 0);
924                 tmp = errno;
925                 close(fd);
926                 errno = tmp;
927         }
928
929         if (path_layout == NULL) {
930                 if (errno != ENODATA && errno != ENOENT)
931                         return NULL;
932
933                 path_layout = llapi_layout_alloc();
934                 if (path_layout == NULL)
935                         return NULL;
936         }
937
938         if (is_any_specified(path_layout)) {
939                 inherit_sys_attributes(path_layout, path);
940                 return path_layout;
941         }
942
943         llapi_layout_free(path_layout);
944
945         rc = stat(path, &st);
946         if (rc < 0 && errno != ENOENT)
947                 return NULL;
948
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);
958                                 return path_layout;
959                         }
960                         llapi_layout_free(path_layout);
961                 }
962         }
963
964         /* Inherit layout from the filesystem root. */
965         rc = llapi_search_mounts(path, 0, donor_path, NULL);
966         if (rc < 0)
967                 return NULL;
968         path_layout = llapi_layout_get_by_path(donor_path, 0);
969         if (path_layout == NULL)
970                 return NULL;
971
972         inherit_sys_attributes(path_layout, donor_path);
973         return path_layout;
974 }
975
976 /**
977  * Get the striping layout for the file at \a path.
978  *
979  * If \a flags contains LAYOUT_GET_EXPECTED, substitute
980  * expected inherited attribute values for unspecified attributes. See
981  * llapi_layout_expected().
982  *
983  * \param[in] path      path for which to get the layout
984  * \param[in] flags     flags to control how layout is retrieved
985  *
986  * \retval      valid llapi_layout pointer on success
987  * \retval      NULL if an error occurs
988  */
989 struct llapi_layout *llapi_layout_get_by_path(const char *path, uint32_t flags)
990 {
991         struct llapi_layout *layout = NULL;
992         int fd;
993         int tmp;
994
995         if (flags & LAYOUT_GET_EXPECTED)
996                 return llapi_layout_expected(path);
997
998         fd = open(path, O_RDONLY);
999         if (fd < 0)
1000                 return layout;
1001
1002         layout = llapi_layout_get_by_fd(fd, flags);
1003         tmp = errno;
1004         close(fd);
1005         errno = tmp;
1006
1007         return layout;
1008 }
1009
1010 /**
1011  * Get the layout for the file with FID \a fidstr in filesystem \a lustre_dir.
1012  *
1013  * \param[in] lustre_dir        path within Lustre filesystem containing \a fid
1014  * \param[in] fid               Lustre identifier of file to get layout for
1015  *
1016  * \retval      valid llapi_layout pointer on success
1017  * \retval      NULL if an error occurs
1018  */
1019 struct llapi_layout *llapi_layout_get_by_fid(const char *lustre_dir,
1020                                              const struct lu_fid *fid,
1021                                              uint32_t flags)
1022 {
1023         int fd;
1024         int tmp;
1025         int saved_msg_level = llapi_msg_get_level();
1026         struct llapi_layout *layout = NULL;
1027
1028         /* Prevent llapi internal routines from writing to console
1029          * while executing this function, then restore previous message
1030          * level. */
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);
1034
1035         if (fd < 0)
1036                 return NULL;
1037
1038         layout = llapi_layout_get_by_fd(fd, flags);
1039         tmp = errno;
1040         close(fd);
1041         errno = tmp;
1042
1043         return layout;
1044 }
1045
1046 /**
1047  * Get the stripe count of \a layout.
1048  *
1049  * \param[in] layout    layout to get stripe count from
1050  * \param[out] count    integer to store stripe count in
1051  *
1052  * \retval      0 on success
1053  * \retval      -1 if arguments are invalid
1054  */
1055 int llapi_layout_stripe_count_get(const struct llapi_layout *layout,
1056                                   uint64_t *count)
1057 {
1058         struct llapi_layout_comp *comp;
1059
1060         comp = __llapi_layout_cur_comp(layout);
1061         if (comp == NULL)
1062                 return -1;
1063
1064         if (count == NULL) {
1065                 errno = EINVAL;
1066                 return -1;
1067         }
1068
1069         *count = comp->llc_stripe_count;
1070
1071         return 0;
1072 }
1073
1074 /*
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.
1078  */
1079
1080 static bool llapi_layout_stripe_count_is_valid(int64_t stripe_count)
1081 {
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));
1086 }
1087
1088 static bool llapi_layout_stripe_size_is_valid(uint64_t stripe_size)
1089 {
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));
1094 }
1095
1096 static bool llapi_layout_stripe_index_is_valid(int64_t stripe_index)
1097 {
1098         return stripe_index == LLAPI_LAYOUT_DEFAULT ||
1099                 (stripe_index >= 0 &&
1100                 llapi_stripe_index_is_valid(stripe_index));
1101 }
1102
1103 /**
1104  * Set the stripe count of \a layout.
1105  *
1106  * \param[in] layout    layout to set stripe count in
1107  * \param[in] count     value to be set
1108  *
1109  * \retval      0 on success
1110  * \retval      -1 if arguments are invalid
1111  */
1112 int llapi_layout_stripe_count_set(struct llapi_layout *layout,
1113                                   uint64_t count)
1114 {
1115         struct llapi_layout_comp *comp;
1116
1117         comp = __llapi_layout_cur_comp(layout);
1118         if (comp == NULL)
1119                 return -1;
1120
1121         if (!llapi_layout_stripe_count_is_valid(count)) {
1122                 errno = EINVAL;
1123                 return -1;
1124         }
1125
1126         comp->llc_stripe_count = count;
1127
1128         return 0;
1129 }
1130
1131 /**
1132  * Get the stripe size of \a layout.
1133  *
1134  * \param[in] layout    layout to get stripe size from
1135  * \param[out] size     integer to store stripe size in
1136  *
1137  * \retval      0 on success
1138  * \retval      -1 if arguments are invalid
1139  */
1140 int llapi_layout_stripe_size_get(const struct llapi_layout *layout,
1141                                  uint64_t *size)
1142 {
1143         struct llapi_layout_comp *comp;
1144
1145         comp = __llapi_layout_cur_comp(layout);
1146         if (comp == NULL)
1147                 return -1;
1148
1149         if (size == NULL) {
1150                 errno = EINVAL;
1151                 return -1;
1152         }
1153
1154         *size = comp->llc_stripe_size;
1155
1156         return 0;
1157 }
1158
1159 /**
1160  * Set the stripe size of \a layout.
1161  *
1162  * \param[in] layout    layout to set stripe size in
1163  * \param[in] size      value to be set
1164  *
1165  * \retval      0 on success
1166  * \retval      -1 if arguments are invalid
1167  */
1168 int llapi_layout_stripe_size_set(struct llapi_layout *layout,
1169                                  uint64_t size)
1170 {
1171         struct llapi_layout_comp *comp;
1172
1173         comp = __llapi_layout_cur_comp(layout);
1174         if (comp == NULL)
1175                 return -1;
1176
1177         if (!llapi_layout_stripe_size_is_valid(size)) {
1178                 errno = EINVAL;
1179                 return -1;
1180         }
1181
1182         comp->llc_stripe_size = size;
1183
1184         return 0;
1185 }
1186
1187 /**
1188  * Get the RAID pattern of \a layout.
1189  *
1190  * \param[in] layout    layout to get pattern from
1191  * \param[out] pattern  integer to store pattern in
1192  *
1193  * \retval      0 on success
1194  * \retval      -1 if arguments are invalid
1195  */
1196 int llapi_layout_pattern_get(const struct llapi_layout *layout,
1197                              uint64_t *pattern)
1198 {
1199         struct llapi_layout_comp *comp;
1200
1201         comp = __llapi_layout_cur_comp(layout);
1202         if (comp == NULL)
1203                 return -1;
1204
1205         if (pattern == NULL) {
1206                 errno = EINVAL;
1207                 return -1;
1208         }
1209
1210         *pattern = comp->llc_pattern;
1211
1212         return 0;
1213 }
1214
1215 /**
1216  * Set the pattern of \a layout.
1217  *
1218  * \param[in] layout    layout to set pattern in
1219  * \param[in] pattern   value to be set
1220  *
1221  * \retval      0 on success
1222  * \retval      -1 if arguments are invalid or RAID pattern
1223  *              is unsupported
1224  */
1225 int llapi_layout_pattern_set(struct llapi_layout *layout, uint64_t pattern)
1226 {
1227         struct llapi_layout_comp *comp;
1228
1229         comp = __llapi_layout_cur_comp(layout);
1230         if (comp == NULL)
1231                 return -1;
1232
1233         if (pattern != LLAPI_LAYOUT_DEFAULT &&
1234             pattern != LLAPI_LAYOUT_RAID0 && pattern != LLAPI_LAYOUT_MDT) {
1235                 errno = EOPNOTSUPP;
1236                 return -1;
1237         }
1238
1239         comp->llc_pattern = pattern |
1240                             (comp->llc_pattern & LLAPI_LAYOUT_SPECIFIC);
1241
1242         return 0;
1243 }
1244
1245 static inline int stripe_number_roundup(int stripe_number)
1246 {
1247         unsigned int round_up = (stripe_number + 8) & ~7;
1248         return round_up > LOV_MAX_STRIPE_COUNT ?
1249                 LOV_MAX_STRIPE_COUNT : round_up;
1250 }
1251
1252 /**
1253  * Set the OST index of stripe number \a stripe_number to \a ost_index.
1254  *
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.
1259  *
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
1263  *
1264  * \retval      0 on success
1265  * \retval      -1 if arguments are invalid or an unsupported stripe number
1266  *              was specified, error returned in errno
1267  */
1268 int llapi_layout_ost_index_set(struct llapi_layout *layout, int stripe_number,
1269                                uint64_t ost_index)
1270 {
1271         struct llapi_layout_comp *comp;
1272
1273         comp = __llapi_layout_cur_comp(layout);
1274         if (comp == NULL)
1275                 return -1;
1276
1277         if (!llapi_layout_stripe_index_is_valid(ost_index)) {
1278                 errno = EINVAL;
1279                 return -1;
1280         }
1281
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) {
1289                         errno = EINVAL;
1290                         return -1;
1291                 }
1292
1293                 /* Preallocate a few more stripes to avoid realloc() overhead.*/
1294                 if (__llapi_comp_objects_realloc(comp,
1295                                 stripe_number_roundup(stripe_number)) < 0)
1296                         return -1;
1297
1298                 comp->llc_objects[stripe_number].l_ost_idx = ost_index;
1299
1300                 if (stripe_number == 0)
1301                         comp->llc_stripe_offset = ost_index;
1302                 else
1303                         comp->llc_pattern |= LLAPI_LAYOUT_SPECIFIC;
1304
1305                 if (comp->llc_stripe_count == LLAPI_LAYOUT_DEFAULT ||
1306                     comp->llc_stripe_count <= stripe_number)
1307                         comp->llc_stripe_count = stripe_number + 1;
1308         } else {
1309                 errno = EINVAL;
1310                 return -1;
1311         }
1312
1313         return 0;
1314 }
1315
1316 /**
1317  * Get the OST index associated with stripe \a stripe_number.
1318  *
1319  * Stripes are indexed starting from zero.
1320  *
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
1324  *
1325  * \retval      0 on success
1326  * \retval      -1 if arguments are invalid
1327  */
1328 int llapi_layout_ost_index_get(const struct llapi_layout *layout,
1329                                uint64_t stripe_number, uint64_t *index)
1330 {
1331         struct llapi_layout_comp *comp;
1332
1333         comp = __llapi_layout_cur_comp(layout);
1334         if (comp == NULL)
1335                 return -1;
1336
1337         if (index == NULL) {
1338                 errno = EINVAL;
1339                 return -1;
1340         }
1341
1342         if (stripe_number >= comp->llc_stripe_count ||
1343             stripe_number >= comp->llc_objects_count) {
1344                 errno = EINVAL;
1345                 return -1;
1346         }
1347
1348         if (comp->llc_stripe_offset == LLAPI_LAYOUT_DEFAULT)
1349                 *index = LLAPI_LAYOUT_DEFAULT;
1350         else
1351                 *index = comp->llc_objects[stripe_number].l_ost_idx;
1352
1353         return 0;
1354 }
1355
1356 /**
1357  *
1358  * Get the pool name of layout \a layout.
1359  *
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
1363  *
1364  * \retval      0 on success
1365  * \retval      -1 if arguments are invalid
1366  */
1367 int llapi_layout_pool_name_get(const struct llapi_layout *layout, char *dest,
1368                                size_t n)
1369 {
1370         struct llapi_layout_comp *comp;
1371
1372         comp = __llapi_layout_cur_comp(layout);
1373         if (comp == NULL)
1374                 return -1;
1375
1376         if (dest == NULL) {
1377                 errno = EINVAL;
1378                 return -1;
1379         }
1380
1381         strncpy(dest, comp->llc_pool_name, n);
1382
1383         return 0;
1384 }
1385
1386 /**
1387  * Set the name of the pool of layout \a layout.
1388  *
1389  * \param[in] layout    layout to set pool name in
1390  * \param[in] pool_name pool name to set
1391  *
1392  * \retval      0 on success
1393  * \retval      -1 if arguments are invalid or pool name is too long
1394  */
1395 int llapi_layout_pool_name_set(struct llapi_layout *layout,
1396                                const char *pool_name)
1397 {
1398         struct llapi_layout_comp *comp;
1399         char *ptr;
1400
1401         comp = __llapi_layout_cur_comp(layout);
1402         if (comp == NULL)
1403                 return -1;
1404
1405         if (pool_name == NULL) {
1406                 errno = EINVAL;
1407                 return -1;
1408         }
1409
1410         /* Strip off any 'fsname.' portion. */
1411         ptr = strchr(pool_name, '.');
1412         if (ptr != NULL)
1413                 pool_name = ptr + 1;
1414
1415         if (strlen(pool_name) > LOV_MAXPOOLNAME) {
1416                 errno = EINVAL;
1417                 return -1;
1418         }
1419
1420         strncpy(comp->llc_pool_name, pool_name, sizeof(comp->llc_pool_name));
1421
1422         return 0;
1423 }
1424
1425 /**
1426  * Open and possibly create a file with a given \a layout.
1427  *
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.
1431  *
1432  * \param[in] path              name of the file to open
1433  * \param[in] open_flags        open() flags
1434  * \param[in] mode              permissions to create new file with
1435  * \param[in] layout            layout to create new file with
1436  *
1437  * \retval              non-negative file descriptor on successful open
1438  * \retval              -1 if an error occurred
1439  */
1440 int llapi_layout_file_open(const char *path, int open_flags, mode_t mode,
1441                            const struct llapi_layout *layout)
1442 {
1443         int fd;
1444         int rc;
1445         int tmp;
1446         struct lov_user_md *lum;
1447         size_t lum_size;
1448
1449         if (path == NULL ||
1450             (layout != NULL && layout->llot_magic != LLAPI_LAYOUT_MAGIC)) {
1451                 errno = EINVAL;
1452                 return -1;
1453         }
1454
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;
1459
1460         fd = open(path, open_flags, mode);
1461
1462         if (layout == NULL || fd < 0)
1463                 return fd;
1464
1465         lum = llapi_layout_to_lum(layout);
1466
1467         if (lum == NULL) {
1468                 tmp = errno;
1469                 close(fd);
1470                 errno = tmp;
1471                 return -1;
1472         }
1473
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,
1478                                             lum->lmm_magic);
1479         else
1480                 lum_size = lov_user_md_size(0, lum->lmm_magic);
1481
1482         rc = fsetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_size, 0);
1483         if (rc < 0) {
1484                 tmp = errno;
1485                 close(fd);
1486                 errno = tmp;
1487                 fd = -1;
1488         }
1489
1490         free(lum);
1491         errno = errno == EOPNOTSUPP ? ENOTTY : errno;
1492
1493         return fd;
1494 }
1495
1496 /**
1497  * Create a file with a given \a layout.
1498  *
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.
1501  *
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
1506  *
1507  * \retval              non-negative file descriptor on successful open
1508  * \retval              -1 if an error occurred
1509  */
1510 int llapi_layout_file_create(const char *path, int open_flags, int mode,
1511                              const struct llapi_layout *layout)
1512 {
1513         return llapi_layout_file_open(path, open_flags|O_CREAT|O_EXCL, mode,
1514                                       layout);
1515 }
1516
1517 int llapi_layout_flags_get(struct llapi_layout *layout, uint32_t *flags)
1518 {
1519         if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1520                 errno = EINVAL;
1521                 return -1;
1522         }
1523
1524         *flags = layout->llot_flags;
1525         return 0;
1526 }
1527
1528 /**
1529  * Set flags to the header of a component layout.
1530  */
1531 int llapi_layout_flags_set(struct llapi_layout *layout, uint32_t flags)
1532 {
1533         if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1534                 errno = EINVAL;
1535                 return -1;
1536         }
1537
1538         layout->llot_flags = flags;
1539         return 0;
1540 }
1541
1542 /**
1543  * llapi_layout_mirror_count_is_valid() - Check the validity of mirror count.
1544  * @count: Mirror count value to be checked.
1545  *
1546  * This function checks the validity of mirror count.
1547  *
1548  * Return: true on success or false on failure.
1549  */
1550 static bool llapi_layout_mirror_count_is_valid(uint16_t count)
1551 {
1552         return count >= 0 && count <= LUSTRE_MIRROR_COUNT_MAX;
1553 }
1554
1555 /**
1556  * llapi_layout_mirror_count_get() - Get mirror count from the header of
1557  *                                   a layout.
1558  * @layout: Layout to get mirror count from.
1559  * @count:  Returned mirror count value.
1560  *
1561  * This function gets mirror count from the header of a layout.
1562  *
1563  * Return: 0 on success or -1 on failure.
1564  */
1565 int llapi_layout_mirror_count_get(struct llapi_layout *layout,
1566                                   uint16_t *count)
1567 {
1568         if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1569                 errno = EINVAL;
1570                 return -1;
1571         }
1572
1573         *count = layout->llot_mirror_count;
1574         return 0;
1575 }
1576
1577 /**
1578  * llapi_layout_mirror_count_set() - Set mirror count to the header of a layout.
1579  * @layout: Layout to set mirror count in.
1580  * @count:  Mirror count value to be set.
1581  *
1582  * This function sets mirror count to the header of a layout.
1583  *
1584  * Return: 0 on success or -1 on failure.
1585  */
1586 int llapi_layout_mirror_count_set(struct llapi_layout *layout,
1587                                   uint16_t count)
1588 {
1589         if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1590                 errno = EINVAL;
1591                 return -1;
1592         }
1593
1594         if (!llapi_layout_mirror_count_is_valid(count)) {
1595                 errno = EINVAL;
1596                 return -1;
1597         }
1598
1599         layout->llot_mirror_count = count;
1600         return 0;
1601 }
1602
1603 /**
1604  * Fetch the start and end offset of the current layout component.
1605  *
1606  * \param[in] layout    the layout component
1607  * \param[out] start    extent start, inclusive
1608  * \param[out] end      extent end, exclusive
1609  *
1610  * \retval      0 on success
1611  * \retval      <0 if error occurs
1612  */
1613 int llapi_layout_comp_extent_get(const struct llapi_layout *layout,
1614                                  uint64_t *start, uint64_t *end)
1615 {
1616         struct llapi_layout_comp *comp;
1617
1618         comp = __llapi_layout_cur_comp(layout);
1619         if (comp == NULL)
1620                 return -1;
1621
1622         if (start == NULL || end == NULL) {
1623                 errno = EINVAL;
1624                 return -1;
1625         }
1626
1627         *start = comp->llc_extent.e_start;
1628         *end = comp->llc_extent.e_end;
1629
1630         return 0;
1631 }
1632
1633 /**
1634  * Set the layout extent of a layout.
1635  *
1636  * \param[in] layout    the layout to be set
1637  * \param[in] start     extent start, inclusive
1638  * \param[in] end       extent end, exclusive
1639  *
1640  * \retval      0 on success
1641  * \retval      <0 if error occurs
1642  */
1643 int llapi_layout_comp_extent_set(struct llapi_layout *layout,
1644                                  uint64_t start, uint64_t end)
1645 {
1646         struct llapi_layout_comp *prev, *next, *comp;
1647
1648         comp = __llapi_layout_cur_comp(layout);
1649         if (comp == NULL)
1650                 return -1;
1651
1652         if (start >= end) {
1653                 errno = EINVAL;
1654                 return -1;
1655         }
1656
1657         /*
1658          * We need to make sure the extent to be set is valid: the new
1659          * extent must be adjacent with the prev & next component.
1660          */
1661         if (comp->llc_list.prev != &layout->llot_comp_list) {
1662                 prev = list_entry(comp->llc_list.prev, typeof(*prev),
1663                                   llc_list);
1664                 if (start != prev->llc_extent.e_end) {
1665                         errno = EINVAL;
1666                         return -1;
1667                 }
1668         }
1669
1670         if (comp->llc_list.next != &layout->llot_comp_list) {
1671                 next = list_entry(comp->llc_list.next, typeof(*next),
1672                                   llc_list);
1673                 if (end != next->llc_extent.e_start) {
1674                         errno = EINVAL;
1675                         return -1;
1676                 }
1677         }
1678
1679         comp->llc_extent.e_start = start;
1680         comp->llc_extent.e_end = end;
1681         layout->llot_is_composite = true;
1682
1683         return 0;
1684 }
1685
1686 /**
1687  * Gets the attribute flags of the current component.
1688  *
1689  * \param[in] layout    the layout component
1690  * \param[out] flags    stored the returned component flags
1691  *
1692  * \retval      0 on success
1693  * \retval      <0 if error occurs
1694  */
1695 int llapi_layout_comp_flags_get(const struct llapi_layout *layout,
1696                                 uint32_t *flags)
1697 {
1698         struct llapi_layout_comp *comp;
1699
1700         comp = __llapi_layout_cur_comp(layout);
1701         if (comp == NULL)
1702                 return -1;
1703
1704         if (flags == NULL) {
1705                 errno = EINVAL;
1706                 return -1;
1707         }
1708
1709         *flags = comp->llc_flags;
1710
1711         return 0;
1712 }
1713
1714 /**
1715  * Sets the specified flags of the current component leaving other flags as-is.
1716  *
1717  * \param[in] layout    the layout component
1718  * \param[in] flags     component flags to be set
1719  *
1720  * \retval      0 on success
1721  * \retval      <0 if error occurs
1722  */
1723 int llapi_layout_comp_flags_set(struct llapi_layout *layout, uint32_t flags)
1724 {
1725         struct llapi_layout_comp *comp;
1726
1727         comp = __llapi_layout_cur_comp(layout);
1728         if (comp == NULL)
1729                 return -1;
1730
1731         comp->llc_flags |= flags;
1732
1733         return 0;
1734 }
1735
1736 /**
1737  * Clears the flags specified in the flags leaving other flags as-is.
1738  *
1739  * \param[in] layout    the layout component
1740  * \param[in] flags     component flags to be cleared
1741  *
1742  * \retval      0 on success
1743  * \retval      <0 if error occurs
1744  */
1745 int llapi_layout_comp_flags_clear(struct llapi_layout *layout,
1746                                   uint32_t flags)
1747 {
1748         struct llapi_layout_comp *comp;
1749
1750         comp = __llapi_layout_cur_comp(layout);
1751         if (comp == NULL)
1752                 return -1;
1753
1754         comp->llc_flags &= ~flags;
1755
1756         return 0;
1757 }
1758
1759 /**
1760  * Fetches the file-unique component ID of the current layout component.
1761  *
1762  * \param[in] layout    the layout component
1763  * \param[out] id       stored the returned component ID
1764  *
1765  * \retval      0 on success
1766  * \retval      <0 if error occurs
1767  */
1768 int llapi_layout_comp_id_get(const struct llapi_layout *layout, uint32_t *id)
1769 {
1770         struct llapi_layout_comp *comp;
1771
1772         comp = __llapi_layout_cur_comp(layout);
1773         if (comp == NULL)
1774                 return -1;
1775
1776         if (id == NULL) {
1777                 errno = EINVAL;
1778                 return -1;
1779         }
1780         *id = comp->llc_id;
1781
1782         return 0;
1783 }
1784
1785 /**
1786  * Return the mirror id of the current layout component.
1787  *
1788  * \param[in] layout    the layout component
1789  * \param[out] id       stored the returned mirror ID
1790  *
1791  * \retval      0 on success
1792  * \retval      <0 if error occurs
1793  */
1794 int llapi_layout_mirror_id_get(const struct llapi_layout *layout, uint32_t *id)
1795 {
1796         struct llapi_layout_comp *comp;
1797
1798         comp = __llapi_layout_cur_comp(layout);
1799         if (comp == NULL)
1800                 return -1;
1801
1802         if (id == NULL) {
1803                 errno = EINVAL;
1804                 return -1;
1805         }
1806
1807         *id = mirror_id_of(comp->llc_id);
1808
1809         return 0;
1810 }
1811
1812 /**
1813  * Adds a component to \a layout, the new component will be added to
1814  * the tail of components list and it'll inherit attributes of existing
1815  * ones. The \a layout will change it's current component pointer to
1816  * the newly added component, and it'll be turned into a composite
1817  * layout if it was not before the adding.
1818  *
1819  * \param[in] layout    existing composite or plain layout
1820  *
1821  * \retval      0 on success
1822  * \retval      <0 if error occurs
1823  */
1824 int llapi_layout_comp_add(struct llapi_layout *layout)
1825 {
1826         struct llapi_layout_comp *last, *comp, *new;
1827
1828         comp = __llapi_layout_cur_comp(layout);
1829         if (comp == NULL)
1830                 return -1;
1831
1832         new = __llapi_comp_alloc(0);
1833         if (new == NULL)
1834                 return -1;
1835
1836         last = list_entry(layout->llot_comp_list.prev, typeof(*last),
1837                           llc_list);
1838
1839         if (new->llc_extent.e_end <= last->llc_extent.e_end) {
1840                 __llapi_comp_free(new);
1841                 errno = EINVAL;
1842                 return -1;
1843         }
1844         new->llc_extent.e_start = last->llc_extent.e_end;
1845
1846         list_add_tail(&new->llc_list, &layout->llot_comp_list);
1847         layout->llot_cur_comp = new;
1848         layout->llot_is_composite = true;
1849
1850         return 0;
1851 }
1852
1853 /**
1854  * Deletes current component from the composite layout. The component
1855  * to be deleted must be the tail of components list, and it can't be
1856  * the only component in the layout.
1857  *
1858  * \param[in] layout    composite layout
1859  *
1860  * \retval      0 on success
1861  * \retval      <0 if error occurs
1862  */
1863 int llapi_layout_comp_del(struct llapi_layout *layout)
1864 {
1865         struct llapi_layout_comp *comp;
1866
1867         comp = __llapi_layout_cur_comp(layout);
1868         if (comp == NULL)
1869                 return -1;
1870
1871         if (!layout->llot_is_composite) {
1872                 errno = EINVAL;
1873                 return -1;
1874         }
1875
1876         /* It must be the tail of the list (for PFL, can be relaxed
1877          * once we get mirrored components) */
1878         if (comp->llc_list.next != &layout->llot_comp_list) {
1879                 errno = EINVAL;
1880                 return -1;
1881         }
1882         /* It can't be the only one on the list */
1883         if (comp->llc_list.prev == &layout->llot_comp_list) {
1884                 errno = EINVAL;
1885                 return -1;
1886         }
1887
1888         layout->llot_cur_comp =
1889                 list_entry(comp->llc_list.prev, typeof(*comp), llc_list);
1890         list_del_init(&comp->llc_list);
1891         __llapi_comp_free(comp);
1892
1893         return 0;
1894 }
1895
1896 /**
1897  * Move the current component pointer to the component with
1898  * specified component ID.
1899  *
1900  * \param[in] layout    composite layout
1901  * \param[in] id        component ID
1902  *
1903  * \retval      =0 : moved successfully
1904  * \retval      <0 if error occurs
1905  */
1906 int llapi_layout_comp_use_id(struct llapi_layout *layout, uint32_t comp_id)
1907 {
1908         struct llapi_layout_comp *comp;
1909
1910         comp = __llapi_layout_cur_comp(layout);
1911         if (comp == NULL)
1912                 return -1; /* use previously set errno */
1913
1914         if (!layout->llot_is_composite) {
1915                 errno = EINVAL;
1916                 return -1;
1917         }
1918
1919         if (comp_id == LCME_ID_INVAL) {
1920                 errno = EINVAL;
1921                 return -1;
1922         }
1923
1924         list_for_each_entry(comp, &layout->llot_comp_list, llc_list) {
1925                 if (comp->llc_id == comp_id) {
1926                         layout->llot_cur_comp = comp;
1927                         return 0;
1928                 }
1929         }
1930         errno = ENOENT;
1931         return -1;
1932 }
1933
1934 /**
1935  * Move the current component pointer to a specified position.
1936  *
1937  * \param[in] layout    composite layout
1938  * \param[in] pos       the position to be moved, it can be:
1939  *                      LLAPI_LAYOUT_COMP_USE_FIRST: use first component
1940  *                      LLAPI_LAYOUT_COMP_USE_LAST: use last component
1941  *                      LLAPI_LAYOUT_COMP_USE_NEXT: use component after current
1942  *                      LLAPI_LAYOUT_COMP_USE_PREV: use component before current
1943  *
1944  * \retval      =0 : moved successfully
1945  * \retval      =1 : at last component with NEXT, at first component with PREV
1946  * \retval      <0 if error occurs
1947  */
1948 int llapi_layout_comp_use(struct llapi_layout *layout,
1949                           enum llapi_layout_comp_use pos)
1950 {
1951         struct llapi_layout_comp *comp, *head, *tail;
1952
1953         comp = __llapi_layout_cur_comp(layout);
1954         if (comp == NULL)
1955                 return -1;
1956
1957         if (!layout->llot_is_composite) {
1958                 if (pos == LLAPI_LAYOUT_COMP_USE_FIRST ||
1959                     pos == LLAPI_LAYOUT_COMP_USE_LAST)
1960                         return 0;
1961                 errno = ENOENT;
1962                 return 1;
1963         }
1964
1965         head = list_entry(layout->llot_comp_list.next, typeof(*head), llc_list);
1966         tail = list_entry(layout->llot_comp_list.prev, typeof(*tail), llc_list);
1967         switch (pos) {
1968         case LLAPI_LAYOUT_COMP_USE_FIRST:
1969                 layout->llot_cur_comp = head;
1970                 break;
1971         case LLAPI_LAYOUT_COMP_USE_NEXT:
1972                 if (comp == tail) {
1973                         errno = ENOENT;
1974                         return 1;
1975                 }
1976                 layout->llot_cur_comp = list_entry(comp->llc_list.next,
1977                                                    typeof(*comp), llc_list);
1978                 break;
1979         case LLAPI_LAYOUT_COMP_USE_LAST:
1980                 layout->llot_cur_comp = tail;
1981                 break;
1982         case LLAPI_LAYOUT_COMP_USE_PREV:
1983                 if (comp == head) {
1984                         errno = ENOENT;
1985                         return 1;
1986                 }
1987                 layout->llot_cur_comp = list_entry(comp->llc_list.prev,
1988                                                    typeof(*comp), llc_list);
1989                 break;
1990         default:
1991                 errno = EINVAL;
1992                 return -1;
1993         }
1994
1995         return 0;
1996 }
1997
1998 /**
1999  * Add layout component(s) to an existing file.
2000  *
2001  * \param[in] path      The path name of the file
2002  * \param[in] layout    The layout component(s) to be added
2003  */
2004 int llapi_layout_file_comp_add(const char *path,
2005                                const struct llapi_layout *layout)
2006 {
2007         int rc, fd, lum_size, tmp_errno = 0;
2008         struct lov_user_md *lum;
2009
2010         if (path == NULL || layout == NULL ||
2011             layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
2012                 errno = EINVAL;
2013                 return -1;
2014         }
2015
2016         lum = llapi_layout_to_lum(layout);
2017         if (lum == NULL)
2018                 return -1;
2019
2020         if (lum->lmm_magic != LOV_USER_MAGIC_COMP_V1) {
2021                 free(lum);
2022                 errno = EINVAL;
2023                 return -1;
2024         }
2025         lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
2026
2027         fd = open(path, O_RDWR);
2028         if (fd < 0) {
2029                 tmp_errno = errno;
2030                 rc = -1;
2031                 goto out;
2032         }
2033
2034         rc = fsetxattr(fd, XATTR_LUSTRE_LOV".add", lum, lum_size, 0);
2035         if (rc < 0) {
2036                 tmp_errno = errno;
2037                 close(fd);
2038                 rc = -1;
2039                 goto out;
2040         }
2041         close(fd);
2042 out:
2043         free(lum);
2044         errno = tmp_errno;
2045         return rc;
2046 }
2047
2048 /**
2049  * Delete component(s) by the specified component id or component flags
2050  * from an existing file.
2051  *
2052  * \param[in] path      path name of the file
2053  * \param[in] id        unique component ID
2054  * \param[in] flags     flags: LCME_FL_* or;
2055  *                      negative flags: (LCME_FL_NEG|LCME_FL_*)
2056  */
2057 int llapi_layout_file_comp_del(const char *path, uint32_t id, uint32_t flags)
2058 {
2059         int rc, fd, lum_size;
2060         struct llapi_layout *layout;
2061         struct llapi_layout_comp *comp;
2062         struct lov_user_md *lum;
2063
2064         if (path == NULL || id > LCME_ID_MAX || (flags & ~LCME_KNOWN_FLAGS)) {
2065                 errno = EINVAL;
2066                 return -1;
2067         }
2068
2069         /* Can only specify ID or flags, not both. */
2070         if (id != 0 && flags != 0) {
2071                 errno = EINVAL;
2072                 return -1;
2073         }
2074
2075         layout = llapi_layout_alloc();
2076         if (layout == NULL)
2077                 return -1;
2078
2079         llapi_layout_comp_extent_set(layout, 0, LUSTRE_EOF);
2080         comp = __llapi_layout_cur_comp(layout);
2081         if (comp == NULL) {
2082                 llapi_layout_free(layout);
2083                 return -1;
2084         }
2085
2086         comp->llc_id = id;
2087         comp->llc_flags = flags;
2088
2089         lum = llapi_layout_to_lum(layout);
2090         if (lum == NULL) {
2091                 llapi_layout_free(layout);
2092                 return -1;
2093         }
2094         lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
2095
2096         fd = open(path, O_RDWR);
2097         if (fd < 0) {
2098                 rc = -1;
2099                 goto out;
2100         }
2101
2102         rc = fsetxattr(fd, XATTR_LUSTRE_LOV".del", lum, lum_size, 0);
2103         if (rc < 0) {
2104                 int tmp_errno = errno;
2105                 close(fd);
2106                 errno = tmp_errno;
2107                 rc = -1;
2108                 goto out;
2109         }
2110         close(fd);
2111 out:
2112         free(lum);
2113         llapi_layout_free(layout);
2114         return rc;
2115 }
2116
2117 /**
2118  * Change flags or other parameters of the component(s) by component ID of an
2119  * existing file. The component to be modified is specified by the
2120  * comp->lcme_id value, which must be an unique component ID. The new
2121  * attributes are passed in by @comp and @valid is used to specify which
2122  * attributes in the component are going to be changed.
2123  *
2124  * \param[in] path      path name of the file
2125  * \param[in] ids       An array of component IDs
2126  * \param[in] flags     flags: LCME_FL_* or;
2127  *                      negative flags: (LCME_FL_NEG|LCME_FL_*)
2128  * \param[in] count     Number of elements in ids and flags array
2129  */
2130 int llapi_layout_file_comp_set(const char *path, uint32_t *ids, uint32_t *flags,
2131                                size_t count)
2132 {
2133         int rc = -1, fd = -1, i;
2134         size_t lum_size;
2135         struct llapi_layout *layout;
2136         struct llapi_layout_comp *comp;
2137         struct lov_user_md *lum = NULL;
2138
2139         if (path == NULL) {
2140                 errno = EINVAL;
2141                 return -1;
2142         }
2143
2144         if (!count)
2145                 return 0;
2146
2147         for (i = 0; i < count; i++) {
2148                 if (!ids[i] || !flags[i]) {
2149                         errno = EINVAL;
2150                         return -1;
2151                 }
2152
2153                 if (ids[i] > LCME_ID_MAX || (flags[i] & ~LCME_KNOWN_FLAGS)) {
2154                         errno = EINVAL;
2155                         return -1;
2156                 }
2157
2158                 /* do not allow to set or clear INIT flag */
2159                 if (flags[i] & LCME_FL_INIT) {
2160                         errno = EINVAL;
2161                         return -1;
2162                 }
2163         }
2164
2165         layout = __llapi_layout_alloc();
2166         if (layout == NULL)
2167                 return -1;
2168
2169         layout->llot_is_composite = true;
2170         for (i = 0; i < count; i++) {
2171                 comp = __llapi_comp_alloc(0);
2172                 if (comp == NULL)
2173                         goto out;
2174
2175                 comp->llc_id = ids[i];
2176                 comp->llc_flags = flags[i];
2177
2178                 list_add_tail(&comp->llc_list, &layout->llot_comp_list);
2179                 layout->llot_cur_comp = comp;
2180         }
2181
2182         lum = llapi_layout_to_lum(layout);
2183         if (lum == NULL)
2184                 goto out;
2185
2186         lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
2187
2188         fd = open(path, O_RDWR);
2189         if (fd < 0)
2190                 goto out;
2191
2192         /* flush cached pages from clients */
2193         rc = llapi_file_flush(fd);
2194         if (rc) {
2195                 errno = -rc;
2196                 rc = -1;
2197                 goto out_close;
2198         }
2199
2200         rc = fsetxattr(fd, XATTR_LUSTRE_LOV".set.flags", lum, lum_size, 0);
2201         if (rc < 0)
2202                 goto out_close;
2203
2204         rc = 0;
2205
2206 out_close:
2207         if (fd >= 0) {
2208                 int tmp_errno = errno;
2209                 close(fd);
2210                 errno = tmp_errno;
2211         }
2212 out:
2213         if (lum)
2214                 free(lum);
2215         llapi_layout_free(layout);
2216         return rc;
2217 }
2218
2219 /**
2220  * Check if the file layout is composite.
2221  *
2222  * \param[in] layout    the file layout to check
2223  *
2224  * \retval true         composite
2225  * \retval false        not composite
2226  */
2227 bool llapi_layout_is_composite(struct llapi_layout *layout)
2228 {
2229         return layout->llot_is_composite;
2230 }
2231
2232 /**
2233  * Iterate every components in the @layout and call callback function @cb.
2234  *
2235  * \param[in] layout    component layout list.
2236  * \param[in] cb        callback for each component
2237  * \param[in] cbdata    callback data
2238  *
2239  * \retval < 0                          error happens during the iteration
2240  * \retval LLAPI_LAYOUT_ITER_CONT       finished the iteration w/o error
2241  * \retval LLAPI_LAYOUT_ITER_STOP       got something, stop the iteration
2242  */
2243 int llapi_layout_comp_iterate(struct llapi_layout *layout,
2244                               llapi_layout_iter_cb cb, void *cbdata)
2245 {
2246         int rc;
2247
2248         rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
2249         if (rc < 0)
2250                 return rc;
2251
2252         /**
2253          * make sure on success llapi_layout_comp_use() API returns 0 with
2254          * USE_FIRST.
2255          */
2256         assert(rc == 0);
2257
2258         while (1) {
2259                 rc = cb(layout, cbdata);
2260                 if (rc != LLAPI_LAYOUT_ITER_CONT)
2261                         break;
2262
2263                 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
2264                 if (rc < 0)
2265                         return rc;
2266                 else if (rc == 1)       /* reached the last comp */
2267                         return LLAPI_LAYOUT_ITER_CONT;
2268         }
2269
2270         return rc;
2271 }
2272
2273 /**
2274  * llapi_layout_merge() - Merge a composite layout into another one.
2275  * @dst_layout: Destination composite layout.
2276  * @src_layout: Source composite layout.
2277  *
2278  * This function copies all of the components from @src_layout and
2279  * appends them to @dst_layout.
2280  *
2281  * Return: 0 on success or -1 on failure.
2282  */
2283 int llapi_layout_merge(struct llapi_layout **dst_layout,
2284                        const struct llapi_layout *src_layout)
2285 {
2286         struct llapi_layout *new_layout = *dst_layout;
2287         struct llapi_layout_comp *new = NULL;
2288         struct llapi_layout_comp *comp = NULL;
2289         int i = 0;
2290
2291         if (src_layout == NULL ||
2292             list_empty((struct list_head *)&src_layout->llot_comp_list))
2293                 return 0;
2294
2295         if (new_layout == NULL) {
2296                 new_layout = __llapi_layout_alloc();
2297                 if (new_layout == NULL) {
2298                         errno = ENOMEM;
2299                         return -1;
2300                 }
2301         }
2302
2303         list_for_each_entry(comp, &src_layout->llot_comp_list, llc_list) {
2304                 new = __llapi_comp_alloc(0);
2305                 if (new == NULL) {
2306                         errno = ENOMEM;
2307                         goto error;
2308                 }
2309
2310                 new->llc_pattern = comp->llc_pattern;
2311                 new->llc_stripe_size = comp->llc_stripe_size;
2312                 new->llc_stripe_count = comp->llc_stripe_count;
2313                 new->llc_stripe_offset = comp->llc_stripe_offset;
2314
2315                 if (comp->llc_pool_name[0] != '\0')
2316                         strncpy(new->llc_pool_name, comp->llc_pool_name,
2317                                 sizeof(new->llc_pool_name));
2318
2319                 for (i = 0; i < comp->llc_objects_count; i++) {
2320                         if (__llapi_comp_objects_realloc(new,
2321                             stripe_number_roundup(i)) < 0) {
2322                                 errno = EINVAL;
2323                                 __llapi_comp_free(new);
2324                                 goto error;
2325                         }
2326                         new->llc_objects[i].l_ost_idx = \
2327                                 comp->llc_objects[i].l_ost_idx;
2328                 }
2329
2330                 new->llc_objects_count = comp->llc_objects_count;
2331                 new->llc_extent.e_start = comp->llc_extent.e_start;
2332                 new->llc_extent.e_end = comp->llc_extent.e_end;
2333                 new->llc_id = comp->llc_id;
2334                 new->llc_flags = comp->llc_flags;
2335
2336                 list_add_tail(&new->llc_list, &new_layout->llot_comp_list);
2337                 new_layout->llot_cur_comp = new;
2338         }
2339         new_layout->llot_is_composite = true;
2340
2341         *dst_layout = new_layout;
2342         return 0;
2343 error:
2344         llapi_layout_free(new_layout);
2345         return -1;
2346 }
2347
2348 /**
2349  * Find all stale components.
2350  *
2351  * \param[in] layout            component layout list.
2352  * \param[out] comp             array of stale component info.
2353  * \param[in] comp_size         array size of @comp.
2354  * \param[in] mirror_ids        array of mirror id that only components
2355  *                              belonging to these mirror will be collected.
2356  * \param[in] ids_nr            number of mirror ids array.
2357  *
2358  * \retval              number of component info collected on sucess or
2359  *                      an error code on failure.
2360  */
2361 int llapi_mirror_find_stale(struct llapi_layout *layout,
2362                 struct llapi_resync_comp *comp, size_t comp_size,
2363                 __u16 *mirror_ids, int ids_nr)
2364 {
2365         int idx = 0;
2366         int rc;
2367
2368         rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
2369         if (rc < 0)
2370                 goto error;
2371
2372         while (rc == 0) {
2373                 uint32_t id;
2374                 uint32_t mirror_id;
2375                 uint32_t flags;
2376                 uint64_t start, end;
2377
2378                 rc = llapi_layout_comp_flags_get(layout, &flags);
2379                 if (rc < 0)
2380                         goto error;
2381
2382                 if (!(flags & LCME_FL_STALE))
2383                         goto next;
2384
2385                 rc = llapi_layout_mirror_id_get(layout, &mirror_id);
2386                 if (rc < 0)
2387                         goto error;
2388
2389                 /* the caller only wants stale components from specific
2390                  * mirrors */
2391                 if (ids_nr > 0) {
2392                         int j;
2393
2394                         for (j = 0; j < ids_nr; j++) {
2395                                 if (mirror_ids[j] == mirror_id)
2396                                         break;
2397                         }
2398
2399                         /* not in the specified mirror */
2400                         if (j == ids_nr)
2401                                 goto next;
2402                 }
2403
2404                 rc = llapi_layout_comp_id_get(layout, &id);
2405                 if (rc < 0)
2406                         goto error;
2407
2408                 rc = llapi_layout_comp_extent_get(layout, &start, &end);
2409                 if (rc < 0)
2410                         goto error;
2411
2412                 /* pack this component into @comp array */
2413                 comp[idx].lrc_id = id;
2414                 comp[idx].lrc_mirror_id = mirror_id;
2415                 comp[idx].lrc_start = start;
2416                 comp[idx].lrc_end = end;
2417                 idx++;
2418
2419                 if (idx >= comp_size) {
2420                         rc = -EINVAL;
2421                         goto error;
2422                 }
2423
2424         next:
2425                 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
2426                 if (rc < 0) {
2427                         rc = -EINVAL;
2428                         goto error;
2429                 }
2430         }
2431 error:
2432         return rc < 0 ? rc : idx;
2433 }
2434
2435 /* locate @layout to a valid component covering file [file_start, file_end) */
2436 static uint32_t llapi_mirror_find(struct llapi_layout *layout,
2437                                   uint64_t file_start, uint64_t file_end,
2438                                   uint64_t *endp)
2439 {
2440         uint32_t mirror_id = 0;
2441         int rc;
2442
2443         rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
2444         if (rc < 0)
2445                 return rc;
2446
2447         *endp = 0;
2448         while (rc == 0) {
2449                 uint64_t start, end;
2450                 uint32_t flags, id, rid;
2451
2452                 rc = llapi_layout_comp_flags_get(layout, &flags);
2453                 if (rc < 0)
2454                         return rc;
2455
2456                 if (flags & LCME_FL_STALE)
2457                         goto next;
2458
2459                 rc = llapi_layout_mirror_id_get(layout, &rid);
2460                 if (rc < 0)
2461                         return rc;
2462
2463                 rc = llapi_layout_comp_id_get(layout, &id);
2464                 if (rc < 0)
2465                         return rc;
2466
2467                 rc = llapi_layout_comp_extent_get(layout, &start, &end);
2468                 if (rc < 0)
2469                         return rc;
2470
2471                 if (file_start >= start && file_start < end) {
2472                         if (!mirror_id)
2473                                 mirror_id = rid;
2474                         else if (mirror_id != rid || *endp != start)
2475                                 break;
2476
2477                         file_start = *endp = end;
2478                         if (end >= file_end)
2479                                 break;
2480                 }
2481
2482         next:
2483                 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
2484                 if (rc < 0)
2485                         return rc;
2486         }
2487
2488         return mirror_id;
2489 }
2490
2491 ssize_t llapi_mirror_resync_one(int fd, struct llapi_layout *layout,
2492                                 uint32_t dst, uint64_t start, uint64_t end)
2493 {
2494         uint64_t mirror_end = 0;
2495         ssize_t result = 0;
2496         size_t count;
2497
2498         if (end == OBD_OBJECT_EOF)
2499                 count = OBD_OBJECT_EOF;
2500         else
2501                 count = end - start;
2502
2503         while (count > 0) {
2504                 uint32_t src;
2505                 size_t to_copy;
2506                 ssize_t copied;
2507
2508                 src = llapi_mirror_find(layout, start, end, &mirror_end);
2509                 if (src == 0)
2510                         return -ENOENT;
2511
2512                 if (mirror_end == OBD_OBJECT_EOF)
2513                         to_copy = count;
2514                 else
2515                         to_copy = MIN(count, mirror_end - start);
2516
2517                 copied = llapi_mirror_copy(fd, src, dst, start, to_copy);
2518                 if (copied < 0)
2519                         return copied;
2520
2521                 result += copied;
2522                 if (copied < to_copy) /* end of file */
2523                         break;
2524
2525                 if (count != OBD_OBJECT_EOF)
2526                         count -= copied;
2527                 start += copied;
2528         }
2529
2530         return result;
2531 }