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