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