Whamcloud - gitweb
LU-10830 utils: fix create mode for lfs setstripe
[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 file, filtered by umask
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 const char *llapi_layout_flags_string(uint32_t flags)
1543 {
1544         switch (flags & LCM_FL_FLR_MASK) {
1545         case LCM_FL_RDONLY:
1546                 return "ro";
1547         case LCM_FL_WRITE_PENDING:
1548                 return "wp";
1549         case LCM_FL_SYNC_PENDING:
1550                 return "sp";
1551         }
1552
1553         return "0";
1554 }
1555
1556 const __u16 llapi_layout_string_flags(char *string)
1557 {
1558         if (strncmp(string, "ro", strlen(string)) == 0)
1559                 return LCM_FL_RDONLY;
1560         if (strncmp(string, "wp", strlen(string)) == 0)
1561                 return LCM_FL_WRITE_PENDING;
1562         if (strncmp(string, "sp", strlen(string)) == 0)
1563                 return LCM_FL_SYNC_PENDING;
1564
1565         return 0;
1566 }
1567
1568 /**
1569  * llapi_layout_mirror_count_is_valid() - Check the validity of mirror count.
1570  * @count: Mirror count value to be checked.
1571  *
1572  * This function checks the validity of mirror count.
1573  *
1574  * Return: true on success or false on failure.
1575  */
1576 static bool llapi_layout_mirror_count_is_valid(uint16_t count)
1577 {
1578         return count >= 0 && count <= LUSTRE_MIRROR_COUNT_MAX;
1579 }
1580
1581 /**
1582  * llapi_layout_mirror_count_get() - Get mirror count from the header of
1583  *                                   a layout.
1584  * @layout: Layout to get mirror count from.
1585  * @count:  Returned mirror count value.
1586  *
1587  * This function gets mirror count from the header of a layout.
1588  *
1589  * Return: 0 on success or -1 on failure.
1590  */
1591 int llapi_layout_mirror_count_get(struct llapi_layout *layout,
1592                                   uint16_t *count)
1593 {
1594         if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1595                 errno = EINVAL;
1596                 return -1;
1597         }
1598
1599         *count = layout->llot_mirror_count;
1600         return 0;
1601 }
1602
1603 /**
1604  * llapi_layout_mirror_count_set() - Set mirror count to the header of a layout.
1605  * @layout: Layout to set mirror count in.
1606  * @count:  Mirror count value to be set.
1607  *
1608  * This function sets mirror count to the header of a layout.
1609  *
1610  * Return: 0 on success or -1 on failure.
1611  */
1612 int llapi_layout_mirror_count_set(struct llapi_layout *layout,
1613                                   uint16_t count)
1614 {
1615         if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1616                 errno = EINVAL;
1617                 return -1;
1618         }
1619
1620         if (!llapi_layout_mirror_count_is_valid(count)) {
1621                 errno = EINVAL;
1622                 return -1;
1623         }
1624
1625         layout->llot_mirror_count = count;
1626         return 0;
1627 }
1628
1629 /**
1630  * Fetch the start and end offset of the current layout component.
1631  *
1632  * \param[in] layout    the layout component
1633  * \param[out] start    extent start, inclusive
1634  * \param[out] end      extent end, exclusive
1635  *
1636  * \retval      0 on success
1637  * \retval      <0 if error occurs
1638  */
1639 int llapi_layout_comp_extent_get(const struct llapi_layout *layout,
1640                                  uint64_t *start, uint64_t *end)
1641 {
1642         struct llapi_layout_comp *comp;
1643
1644         comp = __llapi_layout_cur_comp(layout);
1645         if (comp == NULL)
1646                 return -1;
1647
1648         if (start == NULL || end == NULL) {
1649                 errno = EINVAL;
1650                 return -1;
1651         }
1652
1653         *start = comp->llc_extent.e_start;
1654         *end = comp->llc_extent.e_end;
1655
1656         return 0;
1657 }
1658
1659 /**
1660  * Set the layout extent of a layout.
1661  *
1662  * \param[in] layout    the layout to be set
1663  * \param[in] start     extent start, inclusive
1664  * \param[in] end       extent end, exclusive
1665  *
1666  * \retval      0 on success
1667  * \retval      <0 if error occurs
1668  */
1669 int llapi_layout_comp_extent_set(struct llapi_layout *layout,
1670                                  uint64_t start, uint64_t end)
1671 {
1672         struct llapi_layout_comp *prev, *next, *comp;
1673
1674         comp = __llapi_layout_cur_comp(layout);
1675         if (comp == NULL)
1676                 return -1;
1677
1678         if (start >= end) {
1679                 errno = EINVAL;
1680                 return -1;
1681         }
1682
1683         /*
1684          * We need to make sure the extent to be set is valid: the new
1685          * extent must be adjacent with the prev & next component.
1686          */
1687         if (comp->llc_list.prev != &layout->llot_comp_list) {
1688                 prev = list_entry(comp->llc_list.prev, typeof(*prev),
1689                                   llc_list);
1690                 if (start != 0 && start != prev->llc_extent.e_end) {
1691                         errno = EINVAL;
1692                         return -1;
1693                 }
1694         }
1695
1696         if (comp->llc_list.next != &layout->llot_comp_list) {
1697                 next = list_entry(comp->llc_list.next, typeof(*next),
1698                                   llc_list);
1699                 if (next->llc_extent.e_start != 0 &&
1700                     end != next->llc_extent.e_start) {
1701                         errno = EINVAL;
1702                         return -1;
1703                 }
1704         }
1705
1706         comp->llc_extent.e_start = start;
1707         comp->llc_extent.e_end = end;
1708         layout->llot_is_composite = true;
1709
1710         return 0;
1711 }
1712
1713 /**
1714  * Gets the attribute flags of the current component.
1715  *
1716  * \param[in] layout    the layout component
1717  * \param[out] flags    stored the returned component flags
1718  *
1719  * \retval      0 on success
1720  * \retval      <0 if error occurs
1721  */
1722 int llapi_layout_comp_flags_get(const struct llapi_layout *layout,
1723                                 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         if (flags == NULL) {
1732                 errno = EINVAL;
1733                 return -1;
1734         }
1735
1736         *flags = comp->llc_flags;
1737
1738         return 0;
1739 }
1740
1741 /**
1742  * Sets the specified flags of the current component leaving other flags as-is.
1743  *
1744  * \param[in] layout    the layout component
1745  * \param[in] flags     component flags to be set
1746  *
1747  * \retval      0 on success
1748  * \retval      <0 if error occurs
1749  */
1750 int llapi_layout_comp_flags_set(struct llapi_layout *layout, uint32_t flags)
1751 {
1752         struct llapi_layout_comp *comp;
1753
1754         comp = __llapi_layout_cur_comp(layout);
1755         if (comp == NULL)
1756                 return -1;
1757
1758         comp->llc_flags |= flags;
1759
1760         return 0;
1761 }
1762
1763 /**
1764  * Clears the flags specified in the flags leaving other flags as-is.
1765  *
1766  * \param[in] layout    the layout component
1767  * \param[in] flags     component flags to be cleared
1768  *
1769  * \retval      0 on success
1770  * \retval      <0 if error occurs
1771  */
1772 int llapi_layout_comp_flags_clear(struct llapi_layout *layout,
1773                                   uint32_t flags)
1774 {
1775         struct llapi_layout_comp *comp;
1776
1777         comp = __llapi_layout_cur_comp(layout);
1778         if (comp == NULL)
1779                 return -1;
1780
1781         comp->llc_flags &= ~flags;
1782
1783         return 0;
1784 }
1785
1786 /**
1787  * Fetches the file-unique component ID of the current layout component.
1788  *
1789  * \param[in] layout    the layout component
1790  * \param[out] id       stored the returned component ID
1791  *
1792  * \retval      0 on success
1793  * \retval      <0 if error occurs
1794  */
1795 int llapi_layout_comp_id_get(const struct llapi_layout *layout, uint32_t *id)
1796 {
1797         struct llapi_layout_comp *comp;
1798
1799         comp = __llapi_layout_cur_comp(layout);
1800         if (comp == NULL)
1801                 return -1;
1802
1803         if (id == NULL) {
1804                 errno = EINVAL;
1805                 return -1;
1806         }
1807         *id = comp->llc_id;
1808
1809         return 0;
1810 }
1811
1812 /**
1813  * Return the mirror id of the current layout component.
1814  *
1815  * \param[in] layout    the layout component
1816  * \param[out] id       stored the returned mirror ID
1817  *
1818  * \retval      0 on success
1819  * \retval      <0 if error occurs
1820  */
1821 int llapi_layout_mirror_id_get(const struct llapi_layout *layout, uint32_t *id)
1822 {
1823         struct llapi_layout_comp *comp;
1824
1825         comp = __llapi_layout_cur_comp(layout);
1826         if (comp == NULL)
1827                 return -1;
1828
1829         if (id == NULL) {
1830                 errno = EINVAL;
1831                 return -1;
1832         }
1833
1834         *id = mirror_id_of(comp->llc_id);
1835
1836         return 0;
1837 }
1838
1839 /**
1840  * Adds a component to \a layout, the new component will be added to
1841  * the tail of components list and it'll inherit attributes of existing
1842  * ones. The \a layout will change it's current component pointer to
1843  * the newly added component, and it'll be turned into a composite
1844  * layout if it was not before the adding.
1845  *
1846  * \param[in] layout    existing composite or plain layout
1847  *
1848  * \retval      0 on success
1849  * \retval      <0 if error occurs
1850  */
1851 int llapi_layout_comp_add(struct llapi_layout *layout)
1852 {
1853         struct llapi_layout_comp *last, *comp, *new;
1854
1855         comp = __llapi_layout_cur_comp(layout);
1856         if (comp == NULL)
1857                 return -1;
1858
1859         new = __llapi_comp_alloc(0);
1860         if (new == NULL)
1861                 return -1;
1862
1863         last = list_entry(layout->llot_comp_list.prev, typeof(*last),
1864                           llc_list);
1865
1866         if (new->llc_extent.e_end <= last->llc_extent.e_end) {
1867                 __llapi_comp_free(new);
1868                 errno = EINVAL;
1869                 return -1;
1870         }
1871         new->llc_extent.e_start = last->llc_extent.e_end;
1872
1873         list_add_tail(&new->llc_list, &layout->llot_comp_list);
1874         layout->llot_cur_comp = new;
1875         layout->llot_is_composite = true;
1876
1877         return 0;
1878 }
1879 /**
1880  * Adds a first component of a mirror to \a layout.
1881  * The \a layout will change it's current component pointer to
1882  * the newly added component, and it'll be turned into a composite
1883  * layout if it was not before the adding.
1884  *
1885  * \param[in] layout            existing composite or plain layout
1886  *
1887  * \retval      0 on success
1888  * \retval      <0 if error occurs
1889  */
1890 int llapi_layout_add_first_comp(struct llapi_layout *layout)
1891 {
1892         struct llapi_layout_comp *comp, *new;
1893
1894         comp = __llapi_layout_cur_comp(layout);
1895         if (comp == NULL)
1896                 return -1;
1897
1898         new = __llapi_comp_alloc(0);
1899         if (new == NULL)
1900                 return -1;
1901
1902         new->llc_extent.e_start = 0;
1903
1904         list_add_tail(&new->llc_list, &layout->llot_comp_list);
1905         layout->llot_cur_comp = new;
1906         layout->llot_is_composite = true;
1907
1908         return 0;
1909 }
1910
1911 /**
1912  * Deletes current component from the composite layout. The component
1913  * to be deleted must be the tail of components list, and it can't be
1914  * the only component in the layout.
1915  *
1916  * \param[in] layout    composite layout
1917  *
1918  * \retval      0 on success
1919  * \retval      <0 if error occurs
1920  */
1921 int llapi_layout_comp_del(struct llapi_layout *layout)
1922 {
1923         struct llapi_layout_comp *comp;
1924
1925         comp = __llapi_layout_cur_comp(layout);
1926         if (comp == NULL)
1927                 return -1;
1928
1929         if (!layout->llot_is_composite) {
1930                 errno = EINVAL;
1931                 return -1;
1932         }
1933
1934         /* It must be the tail of the list (for PFL, can be relaxed
1935          * once we get mirrored components) */
1936         if (comp->llc_list.next != &layout->llot_comp_list) {
1937                 errno = EINVAL;
1938                 return -1;
1939         }
1940         /* It can't be the only one on the list */
1941         if (comp->llc_list.prev == &layout->llot_comp_list) {
1942                 errno = EINVAL;
1943                 return -1;
1944         }
1945
1946         layout->llot_cur_comp =
1947                 list_entry(comp->llc_list.prev, typeof(*comp), llc_list);
1948         list_del_init(&comp->llc_list);
1949         __llapi_comp_free(comp);
1950
1951         return 0;
1952 }
1953
1954 /**
1955  * Move the current component pointer to the component with
1956  * specified component ID.
1957  *
1958  * \param[in] layout    composite layout
1959  * \param[in] id        component ID
1960  *
1961  * \retval      =0 : moved successfully
1962  * \retval      <0 if error occurs
1963  */
1964 int llapi_layout_comp_use_id(struct llapi_layout *layout, uint32_t comp_id)
1965 {
1966         struct llapi_layout_comp *comp;
1967
1968         comp = __llapi_layout_cur_comp(layout);
1969         if (comp == NULL)
1970                 return -1; /* use previously set errno */
1971
1972         if (!layout->llot_is_composite) {
1973                 errno = EINVAL;
1974                 return -1;
1975         }
1976
1977         if (comp_id == LCME_ID_INVAL) {
1978                 errno = EINVAL;
1979                 return -1;
1980         }
1981
1982         list_for_each_entry(comp, &layout->llot_comp_list, llc_list) {
1983                 if (comp->llc_id == comp_id) {
1984                         layout->llot_cur_comp = comp;
1985                         return 0;
1986                 }
1987         }
1988         errno = ENOENT;
1989         return -1;
1990 }
1991
1992 /**
1993  * Move the current component pointer to a specified position.
1994  *
1995  * \param[in] layout    composite layout
1996  * \param[in] pos       the position to be moved, it can be:
1997  *                      LLAPI_LAYOUT_COMP_USE_FIRST: use first component
1998  *                      LLAPI_LAYOUT_COMP_USE_LAST: use last component
1999  *                      LLAPI_LAYOUT_COMP_USE_NEXT: use component after current
2000  *                      LLAPI_LAYOUT_COMP_USE_PREV: use component before current
2001  *
2002  * \retval      =0 : moved successfully
2003  * \retval      =1 : at last component with NEXT, at first component with PREV
2004  * \retval      <0 if error occurs
2005  */
2006 int llapi_layout_comp_use(struct llapi_layout *layout,
2007                           enum llapi_layout_comp_use pos)
2008 {
2009         struct llapi_layout_comp *comp, *head, *tail;
2010
2011         comp = __llapi_layout_cur_comp(layout);
2012         if (comp == NULL)
2013                 return -1;
2014
2015         if (!layout->llot_is_composite) {
2016                 if (pos == LLAPI_LAYOUT_COMP_USE_FIRST ||
2017                     pos == LLAPI_LAYOUT_COMP_USE_LAST)
2018                         return 0;
2019                 errno = ENOENT;
2020                 return 1;
2021         }
2022
2023         head = list_entry(layout->llot_comp_list.next, typeof(*head), llc_list);
2024         tail = list_entry(layout->llot_comp_list.prev, typeof(*tail), llc_list);
2025         switch (pos) {
2026         case LLAPI_LAYOUT_COMP_USE_FIRST:
2027                 layout->llot_cur_comp = head;
2028                 break;
2029         case LLAPI_LAYOUT_COMP_USE_NEXT:
2030                 if (comp == tail) {
2031                         errno = ENOENT;
2032                         return 1;
2033                 }
2034                 layout->llot_cur_comp = list_entry(comp->llc_list.next,
2035                                                    typeof(*comp), llc_list);
2036                 break;
2037         case LLAPI_LAYOUT_COMP_USE_LAST:
2038                 layout->llot_cur_comp = tail;
2039                 break;
2040         case LLAPI_LAYOUT_COMP_USE_PREV:
2041                 if (comp == head) {
2042                         errno = ENOENT;
2043                         return 1;
2044                 }
2045                 layout->llot_cur_comp = list_entry(comp->llc_list.prev,
2046                                                    typeof(*comp), llc_list);
2047                 break;
2048         default:
2049                 errno = EINVAL;
2050                 return -1;
2051         }
2052
2053         return 0;
2054 }
2055
2056 /**
2057  * Add layout component(s) to an existing file.
2058  *
2059  * \param[in] path      The path name of the file
2060  * \param[in] layout    The layout component(s) to be added
2061  */
2062 int llapi_layout_file_comp_add(const char *path,
2063                                const struct llapi_layout *layout)
2064 {
2065         int rc, fd, lum_size, tmp_errno = 0;
2066         struct lov_user_md *lum;
2067
2068         if (path == NULL || layout == NULL ||
2069             layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
2070                 errno = EINVAL;
2071                 return -1;
2072         }
2073
2074         lum = llapi_layout_to_lum(layout);
2075         if (lum == NULL)
2076                 return -1;
2077
2078         if (lum->lmm_magic != LOV_USER_MAGIC_COMP_V1) {
2079                 free(lum);
2080                 errno = EINVAL;
2081                 return -1;
2082         }
2083         lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
2084
2085         fd = open(path, O_RDWR);
2086         if (fd < 0) {
2087                 tmp_errno = errno;
2088                 rc = -1;
2089                 goto out;
2090         }
2091
2092         rc = fsetxattr(fd, XATTR_LUSTRE_LOV".add", lum, lum_size, 0);
2093         if (rc < 0) {
2094                 tmp_errno = errno;
2095                 close(fd);
2096                 rc = -1;
2097                 goto out;
2098         }
2099         close(fd);
2100 out:
2101         free(lum);
2102         errno = tmp_errno;
2103         return rc;
2104 }
2105
2106 /**
2107  * Delete component(s) by the specified component id or component flags
2108  * from an existing file.
2109  *
2110  * \param[in] path      path name of the file
2111  * \param[in] id        unique component ID
2112  * \param[in] flags     flags: LCME_FL_* or;
2113  *                      negative flags: (LCME_FL_NEG|LCME_FL_*)
2114  */
2115 int llapi_layout_file_comp_del(const char *path, uint32_t id, uint32_t flags)
2116 {
2117         int rc, fd, lum_size;
2118         struct llapi_layout *layout;
2119         struct llapi_layout_comp *comp;
2120         struct lov_user_md *lum;
2121
2122         if (path == NULL || id > LCME_ID_MAX || (flags & ~LCME_KNOWN_FLAGS)) {
2123                 errno = EINVAL;
2124                 return -1;
2125         }
2126
2127         /* Can only specify ID or flags, not both. */
2128         if (id != 0 && flags != 0) {
2129                 errno = EINVAL;
2130                 return -1;
2131         }
2132
2133         layout = llapi_layout_alloc();
2134         if (layout == NULL)
2135                 return -1;
2136
2137         llapi_layout_comp_extent_set(layout, 0, LUSTRE_EOF);
2138         comp = __llapi_layout_cur_comp(layout);
2139         if (comp == NULL) {
2140                 llapi_layout_free(layout);
2141                 return -1;
2142         }
2143
2144         comp->llc_id = id;
2145         comp->llc_flags = flags;
2146
2147         lum = llapi_layout_to_lum(layout);
2148         if (lum == NULL) {
2149                 llapi_layout_free(layout);
2150                 return -1;
2151         }
2152         lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
2153
2154         fd = open(path, O_RDWR);
2155         if (fd < 0) {
2156                 rc = -1;
2157                 goto out;
2158         }
2159
2160         rc = fsetxattr(fd, XATTR_LUSTRE_LOV".del", lum, lum_size, 0);
2161         if (rc < 0) {
2162                 int tmp_errno = errno;
2163                 close(fd);
2164                 errno = tmp_errno;
2165                 rc = -1;
2166                 goto out;
2167         }
2168         close(fd);
2169 out:
2170         free(lum);
2171         llapi_layout_free(layout);
2172         return rc;
2173 }
2174
2175 /**
2176  * Change flags or other parameters of the component(s) by component ID of an
2177  * existing file. The component to be modified is specified by the
2178  * comp->lcme_id value, which must be an unique component ID. The new
2179  * attributes are passed in by @comp and @valid is used to specify which
2180  * attributes in the component are going to be changed.
2181  *
2182  * \param[in] path      path name of the file
2183  * \param[in] ids       An array of component IDs
2184  * \param[in] flags     flags: LCME_FL_* or;
2185  *                      negative flags: (LCME_FL_NEG|LCME_FL_*)
2186  * \param[in] count     Number of elements in ids and flags array
2187  */
2188 int llapi_layout_file_comp_set(const char *path, uint32_t *ids, uint32_t *flags,
2189                                size_t count)
2190 {
2191         int rc = -1, fd = -1, i;
2192         size_t lum_size;
2193         struct llapi_layout *layout;
2194         struct llapi_layout_comp *comp;
2195         struct lov_user_md *lum = NULL;
2196
2197         if (path == NULL) {
2198                 errno = EINVAL;
2199                 return -1;
2200         }
2201
2202         if (!count)
2203                 return 0;
2204
2205         for (i = 0; i < count; i++) {
2206                 if (!ids[i] || !flags[i]) {
2207                         errno = EINVAL;
2208                         return -1;
2209                 }
2210
2211                 if (ids[i] > LCME_ID_MAX || (flags[i] & ~LCME_KNOWN_FLAGS)) {
2212                         errno = EINVAL;
2213                         return -1;
2214                 }
2215
2216                 /* do not allow to set or clear INIT flag */
2217                 if (flags[i] & LCME_FL_INIT) {
2218                         errno = EINVAL;
2219                         return -1;
2220                 }
2221         }
2222
2223         layout = __llapi_layout_alloc();
2224         if (layout == NULL)
2225                 return -1;
2226
2227         layout->llot_is_composite = true;
2228         for (i = 0; i < count; i++) {
2229                 comp = __llapi_comp_alloc(0);
2230                 if (comp == NULL)
2231                         goto out;
2232
2233                 comp->llc_id = ids[i];
2234                 comp->llc_flags = flags[i];
2235
2236                 list_add_tail(&comp->llc_list, &layout->llot_comp_list);
2237                 layout->llot_cur_comp = comp;
2238         }
2239
2240         lum = llapi_layout_to_lum(layout);
2241         if (lum == NULL)
2242                 goto out;
2243
2244         lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
2245
2246         fd = open(path, O_RDWR);
2247         if (fd < 0)
2248                 goto out;
2249
2250         /* flush cached pages from clients */
2251         rc = llapi_file_flush(fd);
2252         if (rc) {
2253                 errno = -rc;
2254                 rc = -1;
2255                 goto out_close;
2256         }
2257
2258         rc = fsetxattr(fd, XATTR_LUSTRE_LOV".set.flags", lum, lum_size, 0);
2259         if (rc < 0)
2260                 goto out_close;
2261
2262         rc = 0;
2263
2264 out_close:
2265         if (fd >= 0) {
2266                 int tmp_errno = errno;
2267                 close(fd);
2268                 errno = tmp_errno;
2269         }
2270 out:
2271         if (lum)
2272                 free(lum);
2273         llapi_layout_free(layout);
2274         return rc;
2275 }
2276
2277 /**
2278  * Check if the file layout is composite.
2279  *
2280  * \param[in] layout    the file layout to check
2281  *
2282  * \retval true         composite
2283  * \retval false        not composite
2284  */
2285 bool llapi_layout_is_composite(struct llapi_layout *layout)
2286 {
2287         return layout->llot_is_composite;
2288 }
2289
2290 /**
2291  * Iterate every components in the @layout and call callback function @cb.
2292  *
2293  * \param[in] layout    component layout list.
2294  * \param[in] cb        callback for each component
2295  * \param[in] cbdata    callback data
2296  *
2297  * \retval < 0                          error happens during the iteration
2298  * \retval LLAPI_LAYOUT_ITER_CONT       finished the iteration w/o error
2299  * \retval LLAPI_LAYOUT_ITER_STOP       got something, stop the iteration
2300  */
2301 int llapi_layout_comp_iterate(struct llapi_layout *layout,
2302                               llapi_layout_iter_cb cb, void *cbdata)
2303 {
2304         int rc;
2305
2306         rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
2307         if (rc < 0)
2308                 return rc;
2309
2310         /**
2311          * make sure on success llapi_layout_comp_use() API returns 0 with
2312          * USE_FIRST.
2313          */
2314         assert(rc == 0);
2315
2316         while (1) {
2317                 rc = cb(layout, cbdata);
2318                 if (rc != LLAPI_LAYOUT_ITER_CONT)
2319                         break;
2320
2321                 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
2322                 if (rc < 0)
2323                         return rc;
2324                 else if (rc == 1)       /* reached the last comp */
2325                         return LLAPI_LAYOUT_ITER_CONT;
2326         }
2327
2328         return rc;
2329 }
2330
2331 /**
2332  * llapi_layout_merge() - Merge a composite layout into another one.
2333  * @dst_layout: Destination composite layout.
2334  * @src_layout: Source composite layout.
2335  *
2336  * This function copies all of the components from @src_layout and
2337  * appends them to @dst_layout.
2338  *
2339  * Return: 0 on success or -1 on failure.
2340  */
2341 int llapi_layout_merge(struct llapi_layout **dst_layout,
2342                        const struct llapi_layout *src_layout)
2343 {
2344         struct llapi_layout *new_layout = *dst_layout;
2345         struct llapi_layout_comp *new = NULL;
2346         struct llapi_layout_comp *comp = NULL;
2347         int i = 0;
2348
2349         if (src_layout == NULL ||
2350             list_empty((struct list_head *)&src_layout->llot_comp_list))
2351                 return 0;
2352
2353         if (new_layout == NULL) {
2354                 new_layout = __llapi_layout_alloc();
2355                 if (new_layout == NULL) {
2356                         errno = ENOMEM;
2357                         return -1;
2358                 }
2359         }
2360
2361         list_for_each_entry(comp, &src_layout->llot_comp_list, llc_list) {
2362                 new = __llapi_comp_alloc(0);
2363                 if (new == NULL) {
2364                         errno = ENOMEM;
2365                         goto error;
2366                 }
2367
2368                 new->llc_pattern = comp->llc_pattern;
2369                 new->llc_stripe_size = comp->llc_stripe_size;
2370                 new->llc_stripe_count = comp->llc_stripe_count;
2371                 new->llc_stripe_offset = comp->llc_stripe_offset;
2372
2373                 if (comp->llc_pool_name[0] != '\0')
2374                         strncpy(new->llc_pool_name, comp->llc_pool_name,
2375                                 sizeof(new->llc_pool_name));
2376
2377                 for (i = 0; i < comp->llc_objects_count; i++) {
2378                         if (__llapi_comp_objects_realloc(new,
2379                             stripe_number_roundup(i)) < 0) {
2380                                 errno = EINVAL;
2381                                 __llapi_comp_free(new);
2382                                 goto error;
2383                         }
2384                         new->llc_objects[i].l_ost_idx = \
2385                                 comp->llc_objects[i].l_ost_idx;
2386                 }
2387
2388                 new->llc_objects_count = comp->llc_objects_count;
2389                 new->llc_extent.e_start = comp->llc_extent.e_start;
2390                 new->llc_extent.e_end = comp->llc_extent.e_end;
2391                 new->llc_id = comp->llc_id;
2392                 new->llc_flags = comp->llc_flags;
2393
2394                 list_add_tail(&new->llc_list, &new_layout->llot_comp_list);
2395                 new_layout->llot_cur_comp = new;
2396         }
2397         new_layout->llot_is_composite = true;
2398
2399         *dst_layout = new_layout;
2400         return 0;
2401 error:
2402         llapi_layout_free(new_layout);
2403         return -1;
2404 }
2405
2406 /**
2407  * Find all stale components.
2408  *
2409  * \param[in] layout            component layout list.
2410  * \param[out] comp             array of stale component info.
2411  * \param[in] comp_size         array size of @comp.
2412  * \param[in] mirror_ids        array of mirror id that only components
2413  *                              belonging to these mirror will be collected.
2414  * \param[in] ids_nr            number of mirror ids array.
2415  *
2416  * \retval              number of component info collected on sucess or
2417  *                      an error code on failure.
2418  */
2419 int llapi_mirror_find_stale(struct llapi_layout *layout,
2420                 struct llapi_resync_comp *comp, size_t comp_size,
2421                 __u16 *mirror_ids, int ids_nr)
2422 {
2423         int idx = 0;
2424         int rc;
2425
2426         rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
2427         if (rc < 0)
2428                 goto error;
2429
2430         while (rc == 0) {
2431                 uint32_t id;
2432                 uint32_t mirror_id;
2433                 uint32_t flags;
2434                 uint64_t start, end;
2435
2436                 rc = llapi_layout_comp_flags_get(layout, &flags);
2437                 if (rc < 0)
2438                         goto error;
2439
2440                 if (!(flags & LCME_FL_STALE))
2441                         goto next;
2442
2443                 rc = llapi_layout_mirror_id_get(layout, &mirror_id);
2444                 if (rc < 0)
2445                         goto error;
2446
2447                 /* the caller only wants stale components from specific
2448                  * mirrors */
2449                 if (ids_nr > 0) {
2450                         int j;
2451
2452                         for (j = 0; j < ids_nr; j++) {
2453                                 if (mirror_ids[j] == mirror_id)
2454                                         break;
2455                         }
2456
2457                         /* not in the specified mirror */
2458                         if (j == ids_nr)
2459                                 goto next;
2460                 }
2461
2462                 rc = llapi_layout_comp_id_get(layout, &id);
2463                 if (rc < 0)
2464                         goto error;
2465
2466                 rc = llapi_layout_comp_extent_get(layout, &start, &end);
2467                 if (rc < 0)
2468                         goto error;
2469
2470                 /* pack this component into @comp array */
2471                 comp[idx].lrc_id = id;
2472                 comp[idx].lrc_mirror_id = mirror_id;
2473                 comp[idx].lrc_start = start;
2474                 comp[idx].lrc_end = end;
2475                 idx++;
2476
2477                 if (idx >= comp_size) {
2478                         rc = -EINVAL;
2479                         goto error;
2480                 }
2481
2482         next:
2483                 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
2484                 if (rc < 0) {
2485                         rc = -EINVAL;
2486                         goto error;
2487                 }
2488         }
2489 error:
2490         return rc < 0 ? rc : idx;
2491 }
2492
2493 /* locate @layout to a valid component covering file [file_start, file_end) */
2494 static uint32_t llapi_mirror_find(struct llapi_layout *layout,
2495                                   uint64_t file_start, uint64_t file_end,
2496                                   uint64_t *endp)
2497 {
2498         uint32_t mirror_id = 0;
2499         int rc;
2500
2501         rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
2502         if (rc < 0)
2503                 return rc;
2504
2505         *endp = 0;
2506         while (rc == 0) {
2507                 uint64_t start, end;
2508                 uint32_t flags, id, rid;
2509
2510                 rc = llapi_layout_comp_flags_get(layout, &flags);
2511                 if (rc < 0)
2512                         return rc;
2513
2514                 if (flags & LCME_FL_STALE)
2515                         goto next;
2516
2517                 rc = llapi_layout_mirror_id_get(layout, &rid);
2518                 if (rc < 0)
2519                         return rc;
2520
2521                 rc = llapi_layout_comp_id_get(layout, &id);
2522                 if (rc < 0)
2523                         return rc;
2524
2525                 rc = llapi_layout_comp_extent_get(layout, &start, &end);
2526                 if (rc < 0)
2527                         return rc;
2528
2529                 if (file_start >= start && file_start < end) {
2530                         if (!mirror_id)
2531                                 mirror_id = rid;
2532                         else if (mirror_id != rid || *endp != start)
2533                                 break;
2534
2535                         file_start = *endp = end;
2536                         if (end >= file_end)
2537                                 break;
2538                 }
2539
2540         next:
2541                 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
2542                 if (rc < 0)
2543                         return rc;
2544         }
2545
2546         return mirror_id;
2547 }
2548
2549 ssize_t llapi_mirror_resync_one(int fd, struct llapi_layout *layout,
2550                                 uint32_t dst, uint64_t start, uint64_t end)
2551 {
2552         uint64_t mirror_end = 0;
2553         ssize_t result = 0;
2554         size_t count;
2555
2556         if (end == OBD_OBJECT_EOF)
2557                 count = OBD_OBJECT_EOF;
2558         else
2559                 count = end - start;
2560
2561         while (count > 0) {
2562                 uint32_t src;
2563                 size_t to_copy;
2564                 ssize_t copied;
2565
2566                 src = llapi_mirror_find(layout, start, end, &mirror_end);
2567                 if (src == 0)
2568                         return -ENOENT;
2569
2570                 if (mirror_end == OBD_OBJECT_EOF)
2571                         to_copy = count;
2572                 else
2573                         to_copy = MIN(count, mirror_end - start);
2574
2575                 copied = llapi_mirror_copy(fd, src, dst, start, to_copy);
2576                 if (copied < 0)
2577                         return copied;
2578
2579                 result += copied;
2580                 if (copied < to_copy) /* end of file */
2581                         break;
2582
2583                 if (count != OBD_OBJECT_EOF)
2584                         count -= copied;
2585                 start += copied;
2586         }
2587
2588         return result;
2589 }