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