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