Whamcloud - gitweb
LU-9771 flr: lfs setstripe to create a new mirror
[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 = layout->llot_flags;
519                 comp_v1->lcm_entry_count = comp_cnt;
520                 comp_v1->lcm_mirror_count = 0;
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 if (pattern == LLAPI_LAYOUT_MDT)
574                         blob->lmm_pattern = LOV_PATTERN_MDT;
575                 else
576                         blob->lmm_pattern = pattern;
577
578                 if (comp->llc_stripe_size == LLAPI_LAYOUT_DEFAULT)
579                         blob->lmm_stripe_size = 0;
580                 else
581                         blob->lmm_stripe_size = comp->llc_stripe_size;
582
583                 if (comp->llc_stripe_count == LLAPI_LAYOUT_DEFAULT)
584                         blob->lmm_stripe_count = 0;
585                 else if (comp->llc_stripe_count == LLAPI_LAYOUT_WIDE)
586                         blob->lmm_stripe_count = LOV_ALL_STRIPES;
587                 else
588                         blob->lmm_stripe_count = comp->llc_stripe_count;
589
590                 if (comp->llc_stripe_offset == LLAPI_LAYOUT_DEFAULT)
591                         blob->lmm_stripe_offset = -1;
592                 else
593                         blob->lmm_stripe_offset = comp->llc_stripe_offset;
594
595                 if (magic == LOV_USER_MAGIC_V3 ||
596                     magic == LOV_USER_MAGIC_SPECIFIC) {
597                         struct lov_user_md_v3 *lumv3 =
598                                 (struct lov_user_md_v3 *)blob;
599
600                         if (comp->llc_pool_name[0] != '\0') {
601                                 strncpy(lumv3->lmm_pool_name,
602                                         comp->llc_pool_name,
603                                         sizeof(lumv3->lmm_pool_name));
604                         } else {
605                                 memset(lumv3->lmm_pool_name, 0,
606                                        sizeof(lumv3->lmm_pool_name));
607                         }
608                         lmm_objects = lumv3->lmm_objects;
609                 } else {
610                         lmm_objects = blob->lmm_objects;
611                 }
612
613                 for (i = 0; i < obj_count; i++)
614                         lmm_objects[i].l_ost_idx =
615                                 comp->llc_objects[i].l_ost_idx;
616
617                 if (layout->llot_is_composite) {
618                         ent = &comp_v1->lcm_entries[ent_idx];
619                         ent->lcme_id = comp->llc_id;
620                         ent->lcme_flags = comp->llc_flags;
621                         ent->lcme_extent.e_start = comp->llc_extent.e_start;
622                         ent->lcme_extent.e_end = comp->llc_extent.e_end;
623                         ent->lcme_size = blob_size;
624                         ent->lcme_offset = offset;
625                         offset += blob_size;
626                         comp_v1->lcm_size += blob_size;
627                         ent_idx++;
628                 } else {
629                         break;
630                 }
631         }
632
633         return lum;
634 error:
635         free(lum);
636         return NULL;
637 }
638
639 /**
640  * Get the parent directory of a path.
641  *
642  * \param[in] path      path to get parent of
643  * \param[out] buf      buffer in which to store parent path
644  * \param[in] size      size in bytes of buffer \a buf
645  */
646 static void get_parent_dir(const char *path, char *buf, size_t size)
647 {
648         char *p;
649
650         strncpy(buf, path, size);
651         p = strrchr(buf, '/');
652
653         if (p != NULL) {
654                 *p = '\0';
655         } else if (size >= 2) {
656                 strncpy(buf, ".", 2);
657                 buf[size - 1] = '\0';
658         }
659 }
660
661 /**
662  * Substitute unspecified attribute values in \a layout with values
663  * from fs global settings. (lov.stripesize, lov.stripecount,
664  * lov.stripeoffset)
665  *
666  * \param[in] layout    layout to inherit values from
667  * \param[in] path      file path of the filesystem
668  */
669 static void inherit_sys_attributes(struct llapi_layout *layout,
670                                    const char *path)
671 {
672         struct llapi_layout_comp *comp;
673         unsigned int ssize, scount, soffset;
674         int rc;
675
676         rc = sattr_cache_get_defaults(NULL, path, &scount, &ssize, &soffset);
677         if (rc)
678                 return;
679
680         list_for_each_entry(comp, &layout->llot_comp_list, llc_list) {
681                 if (comp->llc_pattern == LLAPI_LAYOUT_DEFAULT)
682                         comp->llc_pattern = LLAPI_LAYOUT_RAID0;
683                 if (comp->llc_stripe_size == LLAPI_LAYOUT_DEFAULT)
684                         comp->llc_stripe_size = ssize;
685                 if (comp->llc_stripe_count == LLAPI_LAYOUT_DEFAULT)
686                         comp->llc_stripe_count = scount;
687                 if (comp->llc_stripe_offset == LLAPI_LAYOUT_DEFAULT)
688                         comp->llc_stripe_offset = soffset;
689         }
690 }
691
692 /**
693  * Get the current component of \a layout.
694  *
695  * \param[in] layout    layout to get current component
696  *
697  * \retval      valid llapi_layout_comp pointer on success
698  * \retval      NULL on error
699  */
700 static struct llapi_layout_comp *
701 __llapi_layout_cur_comp(const struct llapi_layout *layout)
702 {
703         struct llapi_layout_comp *comp;
704
705         if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
706                 errno = EINVAL;
707                 return NULL;
708         }
709         if (layout->llot_cur_comp == NULL) {
710                 errno = EINVAL;
711                 return NULL;
712         }
713         /* Verify data consistency */
714         list_for_each_entry(comp, &layout->llot_comp_list, llc_list)
715                 if (comp == layout->llot_cur_comp)
716                         return comp;
717         errno = EFAULT;
718         return NULL;
719 }
720
721 /**
722  * Test if any attributes of \a layout are specified.
723  *
724  * \param[in] layout    the layout to check
725  *
726  * \retval true         any attributes are specified
727  * \retval false        all attributes are unspecified
728  */
729 static bool is_any_specified(const struct llapi_layout *layout)
730 {
731         struct llapi_layout_comp *comp;
732
733         comp = __llapi_layout_cur_comp(layout);
734         if (comp == NULL)
735                 return false;
736
737         if (layout->llot_is_composite)
738                 return true;
739
740         return comp->llc_pattern != LLAPI_LAYOUT_DEFAULT ||
741                comp->llc_stripe_size != LLAPI_LAYOUT_DEFAULT ||
742                comp->llc_stripe_count != LLAPI_LAYOUT_DEFAULT ||
743                comp->llc_stripe_offset != LLAPI_LAYOUT_DEFAULT ||
744                strlen(comp->llc_pool_name);
745 }
746
747 /**
748  * Check if the given \a lum_size is large enough to hold the required
749  * fields in \a lum.
750  *
751  * \param[in] lum       the struct lov_user_md to check
752  * \param[in] lum_size  the number of bytes in \a lum
753  *
754  * \retval true         the \a lum_size is too small
755  * \retval false        the \a lum_size is large enough
756  */
757 static bool llapi_layout_lum_truncated(struct lov_user_md *lum, size_t lum_size)
758 {
759         uint32_t magic;
760
761         if (lum_size < sizeof(lum->lmm_magic))
762                 return true;
763
764         if (lum->lmm_magic == LOV_MAGIC_V1 ||
765             lum->lmm_magic == __swab32(LOV_MAGIC_V1))
766                 magic = LOV_MAGIC_V1;
767         else if (lum->lmm_magic == LOV_MAGIC_V3 ||
768                  lum->lmm_magic == __swab32(LOV_MAGIC_V3))
769                 magic = LOV_MAGIC_V3;
770         else if (lum->lmm_magic == LOV_MAGIC_COMP_V1 ||
771                  lum->lmm_magic == __swab32(LOV_MAGIC_COMP_V1))
772                 magic = LOV_MAGIC_COMP_V1;
773         else
774                 return true;
775
776         if (magic == LOV_MAGIC_V1 || magic == LOV_MAGIC_V3)
777                 return lum_size < lov_user_md_size(0, magic);
778         else
779                 return lum_size < sizeof(struct lov_comp_md_v1);
780 }
781
782 /* Verify if the objects count in lum is consistent with the
783  * stripe count in lum. It applies to regular file only. */
784 static bool llapi_layout_lum_valid(struct lov_user_md *lum, int lum_size)
785 {
786         struct lov_comp_md_v1 *comp_v1 = NULL;
787         int i, ent_count, obj_count;
788
789         if (lum->lmm_magic == LOV_MAGIC_COMP_V1) {
790                 comp_v1 = (struct lov_comp_md_v1 *)lum;
791                 ent_count = comp_v1->lcm_entry_count;
792         } else if (lum->lmm_magic == LOV_MAGIC_V1 ||
793                    lum->lmm_magic == LOV_MAGIC_V3) {
794                 ent_count = 1;
795         } else {
796                 return false;
797         }
798
799         for (i = 0; i < ent_count; i++) {
800                 if (comp_v1) {
801                         lum = (struct lov_user_md *)((char *)comp_v1 +
802                                 comp_v1->lcm_entries[i].lcme_offset);
803                         lum_size = comp_v1->lcm_entries[i].lcme_size;
804                 }
805                 obj_count = llapi_layout_objects_in_lum(lum, lum_size);
806
807                 if (comp_v1) {
808                         if (!(comp_v1->lcm_entries[i].lcme_flags &
809                                  LCME_FL_INIT) && obj_count != 0)
810                                 return false;
811                 } else if (obj_count != lum->lmm_stripe_count) {
812                         return false;
813                 }
814         }
815         return true;
816 }
817
818 /**
819  * Get the striping layout for the file referenced by file descriptor \a fd.
820  *
821  * If the filesystem does not support the "lustre." xattr namespace, the
822  * file must be on a non-Lustre filesystem, so set errno to ENOTTY per
823  * convention.  If the file has no "lustre.lov" data, the file will
824  * inherit default values, so return a default layout.
825  *
826  * If the kernel gives us back less than the expected amount of data,
827  * we fail with errno set to EINTR.
828  *
829  * \param[in] fd        open file descriptor
830  * \param[in] flags     open file descriptor
831  *
832  * \retval      valid llapi_layout pointer on success
833  * \retval      NULL if an error occurs
834  */
835 struct llapi_layout *llapi_layout_get_by_fd(int fd, uint32_t flags)
836 {
837         size_t lum_len;
838         struct lov_user_md *lum;
839         struct llapi_layout *layout = NULL;
840         ssize_t bytes_read;
841         struct stat st;
842
843         lum_len = XATTR_SIZE_MAX;
844         lum = malloc(lum_len);
845         if (lum == NULL)
846                 return NULL;
847
848         bytes_read = fgetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_len);
849         if (bytes_read < 0) {
850                 if (errno == EOPNOTSUPP)
851                         errno = ENOTTY;
852                 else if (errno == ENODATA)
853                         layout = llapi_layout_alloc();
854                 goto out;
855         }
856
857         /* Return an error if we got back a partial layout. */
858         if (llapi_layout_lum_truncated(lum, bytes_read)) {
859                 errno = EINTR;
860                 goto out;
861         }
862
863         llapi_layout_swab_lov_user_md(lum, bytes_read);
864
865         /* Directories may have a positive non-zero lum->lmm_stripe_count
866          * yet have an empty lum->lmm_objects array. For non-directories the
867          * amount of data returned from the kernel must be consistent
868          * with the stripe count. */
869         if (fstat(fd, &st) < 0)
870                 goto out;
871
872         if (!S_ISDIR(st.st_mode) && !llapi_layout_lum_valid(lum, bytes_read)) {
873                 errno = EINTR;
874                 goto out;
875         }
876
877         layout = llapi_layout_from_lum(lum, bytes_read);
878 out:
879         free(lum);
880         return layout;
881 }
882
883 /**
884  * Get the expected striping layout for a file at \a path.
885  *
886  * Substitute expected inherited attribute values for unspecified
887  * attributes.  Unspecified attributes may belong to directories and
888  * never-written-to files, and indicate that default values will be
889  * assigned when files are created or first written to.  A default value
890  * is inherited from the parent directory if the attribute is specified
891  * there, otherwise it is inherited from the filesystem root.
892  * Unspecified attributes normally have the value LLAPI_LAYOUT_DEFAULT.
893  *
894  * The complete \a path need not refer to an existing file or directory,
895  * but some leading portion of it must reside within a lustre filesystem.
896  * A use case for this interface would be to obtain the literal striping
897  * values that would be assigned to a new file in a given directory.
898  *
899  * \param[in] path      path for which to get the expected layout
900  *
901  * \retval      valid llapi_layout pointer on success
902  * \retval      NULL if an error occurs
903  */
904 static struct llapi_layout *llapi_layout_expected(const char *path)
905 {
906         struct llapi_layout     *path_layout = NULL;
907         char                    donor_path[PATH_MAX];
908         struct stat st;
909         int fd;
910         int rc;
911
912         fd = open(path, O_RDONLY);
913         if (fd < 0 && errno != ENOENT)
914                 return NULL;
915
916         if (fd >= 0) {
917                 int tmp;
918
919                 path_layout = llapi_layout_get_by_fd(fd, 0);
920                 tmp = errno;
921                 close(fd);
922                 errno = tmp;
923         }
924
925         if (path_layout == NULL) {
926                 if (errno != ENODATA && errno != ENOENT)
927                         return NULL;
928
929                 path_layout = llapi_layout_alloc();
930                 if (path_layout == NULL)
931                         return NULL;
932         }
933
934         if (is_any_specified(path_layout)) {
935                 inherit_sys_attributes(path_layout, path);
936                 return path_layout;
937         }
938
939         llapi_layout_free(path_layout);
940
941         rc = stat(path, &st);
942         if (rc < 0 && errno != ENOENT)
943                 return NULL;
944
945         /* If path is a not a directory or doesn't exist, inherit layout
946          * from parent directory. */
947         if ((rc == 0 && !S_ISDIR(st.st_mode)) ||
948             (rc < 0 && errno == ENOENT)) {
949                 get_parent_dir(path, donor_path, sizeof(donor_path));
950                 path_layout = llapi_layout_get_by_path(donor_path, 0);
951                 if (path_layout != NULL) {
952                         if (is_any_specified(path_layout)) {
953                                 inherit_sys_attributes(path_layout, donor_path);
954                                 return path_layout;
955                         }
956                         llapi_layout_free(path_layout);
957                 }
958         }
959
960         /* Inherit layout from the filesystem root. */
961         rc = llapi_search_mounts(path, 0, donor_path, NULL);
962         if (rc < 0)
963                 return NULL;
964         path_layout = llapi_layout_get_by_path(donor_path, 0);
965         if (path_layout == NULL)
966                 return NULL;
967
968         inherit_sys_attributes(path_layout, donor_path);
969         return path_layout;
970 }
971
972 /**
973  * Get the striping layout for the file at \a path.
974  *
975  * If \a flags contains LAYOUT_GET_EXPECTED, substitute
976  * expected inherited attribute values for unspecified attributes. See
977  * llapi_layout_expected().
978  *
979  * \param[in] path      path for which to get the layout
980  * \param[in] flags     flags to control how layout is retrieved
981  *
982  * \retval      valid llapi_layout pointer on success
983  * \retval      NULL if an error occurs
984  */
985 struct llapi_layout *llapi_layout_get_by_path(const char *path, uint32_t flags)
986 {
987         struct llapi_layout *layout = NULL;
988         int fd;
989         int tmp;
990
991         if (flags & LAYOUT_GET_EXPECTED)
992                 return llapi_layout_expected(path);
993
994         fd = open(path, O_RDONLY);
995         if (fd < 0)
996                 return layout;
997
998         layout = llapi_layout_get_by_fd(fd, flags);
999         tmp = errno;
1000         close(fd);
1001         errno = tmp;
1002
1003         return layout;
1004 }
1005
1006 /**
1007  * Get the layout for the file with FID \a fidstr in filesystem \a lustre_dir.
1008  *
1009  * \param[in] lustre_dir        path within Lustre filesystem containing \a fid
1010  * \param[in] fid               Lustre identifier of file to get layout for
1011  *
1012  * \retval      valid llapi_layout pointer on success
1013  * \retval      NULL if an error occurs
1014  */
1015 struct llapi_layout *llapi_layout_get_by_fid(const char *lustre_dir,
1016                                              const lustre_fid *fid,
1017                                              uint32_t flags)
1018 {
1019         int fd;
1020         int tmp;
1021         int saved_msg_level = llapi_msg_get_level();
1022         struct llapi_layout *layout = NULL;
1023
1024         /* Prevent llapi internal routines from writing to console
1025          * while executing this function, then restore previous message
1026          * level. */
1027         llapi_msg_set_level(LLAPI_MSG_OFF);
1028         fd = llapi_open_by_fid(lustre_dir, fid, O_RDONLY);
1029         llapi_msg_set_level(saved_msg_level);
1030
1031         if (fd < 0)
1032                 return NULL;
1033
1034         layout = llapi_layout_get_by_fd(fd, flags);
1035         tmp = errno;
1036         close(fd);
1037         errno = tmp;
1038
1039         return layout;
1040 }
1041
1042 /**
1043  * Get the stripe count of \a layout.
1044  *
1045  * \param[in] layout    layout to get stripe count from
1046  * \param[out] count    integer to store stripe count in
1047  *
1048  * \retval      0 on success
1049  * \retval      -1 if arguments are invalid
1050  */
1051 int llapi_layout_stripe_count_get(const struct llapi_layout *layout,
1052                                   uint64_t *count)
1053 {
1054         struct llapi_layout_comp *comp;
1055
1056         comp = __llapi_layout_cur_comp(layout);
1057         if (comp == NULL)
1058                 return -1;
1059
1060         if (count == NULL) {
1061                 errno = EINVAL;
1062                 return -1;
1063         }
1064
1065         *count = comp->llc_stripe_count;
1066
1067         return 0;
1068 }
1069
1070 /*
1071  * The llapi_layout API functions have these extra validity checks since
1072  * they use intuitively named macros to denote special behavior, whereas
1073  * the old API uses 0 and -1.
1074  */
1075
1076 static bool llapi_layout_stripe_count_is_valid(int64_t stripe_count)
1077 {
1078         return stripe_count == LLAPI_LAYOUT_DEFAULT ||
1079                 stripe_count == LLAPI_LAYOUT_WIDE ||
1080                 (stripe_count != 0 && stripe_count != -1 &&
1081                  llapi_stripe_count_is_valid(stripe_count));
1082 }
1083
1084 static bool llapi_layout_stripe_size_is_valid(uint64_t stripe_size)
1085 {
1086         return stripe_size == LLAPI_LAYOUT_DEFAULT ||
1087                 (stripe_size != 0 &&
1088                  llapi_stripe_size_is_aligned(stripe_size) &&
1089                  !llapi_stripe_size_is_too_big(stripe_size));
1090 }
1091
1092 static bool llapi_layout_stripe_index_is_valid(int64_t stripe_index)
1093 {
1094         return stripe_index == LLAPI_LAYOUT_DEFAULT ||
1095                 (stripe_index >= 0 &&
1096                 llapi_stripe_index_is_valid(stripe_index));
1097 }
1098
1099 /**
1100  * Set the stripe count of \a layout.
1101  *
1102  * \param[in] layout    layout to set stripe count in
1103  * \param[in] count     value to be set
1104  *
1105  * \retval      0 on success
1106  * \retval      -1 if arguments are invalid
1107  */
1108 int llapi_layout_stripe_count_set(struct llapi_layout *layout,
1109                                   uint64_t count)
1110 {
1111         struct llapi_layout_comp *comp;
1112
1113         comp = __llapi_layout_cur_comp(layout);
1114         if (comp == NULL)
1115                 return -1;
1116
1117         if (!llapi_layout_stripe_count_is_valid(count)) {
1118                 errno = EINVAL;
1119                 return -1;
1120         }
1121
1122         comp->llc_stripe_count = count;
1123
1124         return 0;
1125 }
1126
1127 /**
1128  * Get the stripe size of \a layout.
1129  *
1130  * \param[in] layout    layout to get stripe size from
1131  * \param[out] size     integer to store stripe size in
1132  *
1133  * \retval      0 on success
1134  * \retval      -1 if arguments are invalid
1135  */
1136 int llapi_layout_stripe_size_get(const struct llapi_layout *layout,
1137                                  uint64_t *size)
1138 {
1139         struct llapi_layout_comp *comp;
1140
1141         comp = __llapi_layout_cur_comp(layout);
1142         if (comp == NULL)
1143                 return -1;
1144
1145         if (size == NULL) {
1146                 errno = EINVAL;
1147                 return -1;
1148         }
1149
1150         *size = comp->llc_stripe_size;
1151
1152         return 0;
1153 }
1154
1155 /**
1156  * Set the stripe size of \a layout.
1157  *
1158  * \param[in] layout    layout to set stripe size in
1159  * \param[in] size      value to be set
1160  *
1161  * \retval      0 on success
1162  * \retval      -1 if arguments are invalid
1163  */
1164 int llapi_layout_stripe_size_set(struct llapi_layout *layout,
1165                                  uint64_t size)
1166 {
1167         struct llapi_layout_comp *comp;
1168
1169         comp = __llapi_layout_cur_comp(layout);
1170         if (comp == NULL)
1171                 return -1;
1172
1173         if (!llapi_layout_stripe_size_is_valid(size)) {
1174                 errno = EINVAL;
1175                 return -1;
1176         }
1177
1178         comp->llc_stripe_size = size;
1179
1180         return 0;
1181 }
1182
1183 /**
1184  * Get the RAID pattern of \a layout.
1185  *
1186  * \param[in] layout    layout to get pattern from
1187  * \param[out] pattern  integer to store pattern in
1188  *
1189  * \retval      0 on success
1190  * \retval      -1 if arguments are invalid
1191  */
1192 int llapi_layout_pattern_get(const struct llapi_layout *layout,
1193                              uint64_t *pattern)
1194 {
1195         struct llapi_layout_comp *comp;
1196
1197         comp = __llapi_layout_cur_comp(layout);
1198         if (comp == NULL)
1199                 return -1;
1200
1201         if (pattern == NULL) {
1202                 errno = EINVAL;
1203                 return -1;
1204         }
1205
1206         *pattern = comp->llc_pattern;
1207
1208         return 0;
1209 }
1210
1211 /**
1212  * Set the pattern of \a layout.
1213  *
1214  * \param[in] layout    layout to set pattern in
1215  * \param[in] pattern   value to be set
1216  *
1217  * \retval      0 on success
1218  * \retval      -1 if arguments are invalid or RAID pattern
1219  *              is unsupported
1220  */
1221 int llapi_layout_pattern_set(struct llapi_layout *layout, uint64_t pattern)
1222 {
1223         struct llapi_layout_comp *comp;
1224
1225         comp = __llapi_layout_cur_comp(layout);
1226         if (comp == NULL)
1227                 return -1;
1228
1229         if (pattern != LLAPI_LAYOUT_DEFAULT &&
1230             pattern != LLAPI_LAYOUT_RAID0 &&
1231             pattern != LLAPI_LAYOUT_MDT) {
1232                 errno = EOPNOTSUPP;
1233                 return -1;
1234         }
1235
1236         comp->llc_pattern = pattern |
1237                             (comp->llc_pattern & LLAPI_LAYOUT_SPECIFIC);
1238
1239         return 0;
1240 }
1241
1242 static inline int stripe_number_roundup(int stripe_number)
1243 {
1244         unsigned int round_up = (stripe_number + 8) & ~7;
1245         return round_up > LOV_MAX_STRIPE_COUNT ?
1246                 LOV_MAX_STRIPE_COUNT : round_up;
1247 }
1248
1249 /**
1250  * Set the OST index of stripe number \a stripe_number to \a ost_index.
1251  *
1252  * If only the starting stripe's OST index is specified, then this can use
1253  * the normal LOV_MAGIC_{V1,V3} layout type.  If multiple OST indices are
1254  * given, then allocate an array to hold the list of indices and ensure that
1255  * the LOV_USER_MAGIC_SPECIFIC layout is used when creating the file.
1256  *
1257  * \param[in] layout            layout to set OST index in
1258  * \param[in] stripe_number     stripe number to set index for
1259  * \param[in] ost_index         the index to set
1260  *
1261  * \retval      0 on success
1262  * \retval      -1 if arguments are invalid or an unsupported stripe number
1263  *              was specified, error returned in errno
1264  */
1265 int llapi_layout_ost_index_set(struct llapi_layout *layout, int stripe_number,
1266                                uint64_t ost_index)
1267 {
1268         struct llapi_layout_comp *comp;
1269
1270         comp = __llapi_layout_cur_comp(layout);
1271         if (comp == NULL)
1272                 return -1;
1273
1274         if (!llapi_layout_stripe_index_is_valid(ost_index)) {
1275                 errno = EINVAL;
1276                 return -1;
1277         }
1278
1279         if (stripe_number == 0 && ost_index == LLAPI_LAYOUT_DEFAULT) {
1280                 comp->llc_stripe_offset = ost_index;
1281                 comp->llc_pattern &= ~LLAPI_LAYOUT_SPECIFIC;
1282                 __llapi_comp_objects_realloc(comp, 0);
1283         } else if (stripe_number >= 0 &&
1284                    stripe_number < LOV_MAX_STRIPE_COUNT) {
1285                 if (ost_index >= LLAPI_LAYOUT_IDX_MAX) {
1286                         errno = EINVAL;
1287                         return -1;
1288                 }
1289
1290                 /* Preallocate a few more stripes to avoid realloc() overhead.*/
1291                 if (__llapi_comp_objects_realloc(comp,
1292                                 stripe_number_roundup(stripe_number)) < 0)
1293                         return -1;
1294
1295                 comp->llc_objects[stripe_number].l_ost_idx = ost_index;
1296
1297                 if (stripe_number == 0)
1298                         comp->llc_stripe_offset = ost_index;
1299                 else
1300                         comp->llc_pattern |= LLAPI_LAYOUT_SPECIFIC;
1301
1302                 if (comp->llc_stripe_count == LLAPI_LAYOUT_DEFAULT ||
1303                     comp->llc_stripe_count <= stripe_number)
1304                         comp->llc_stripe_count = stripe_number + 1;
1305         } else {
1306                 errno = EINVAL;
1307                 return -1;
1308         }
1309
1310         return 0;
1311 }
1312
1313 /**
1314  * Get the OST index associated with stripe \a stripe_number.
1315  *
1316  * Stripes are indexed starting from zero.
1317  *
1318  * \param[in] layout            layout to get index from
1319  * \param[in] stripe_number     stripe number to get index for
1320  * \param[out] index            integer to store index in
1321  *
1322  * \retval      0 on success
1323  * \retval      -1 if arguments are invalid
1324  */
1325 int llapi_layout_ost_index_get(const struct llapi_layout *layout,
1326                                uint64_t stripe_number, uint64_t *index)
1327 {
1328         struct llapi_layout_comp *comp;
1329
1330         comp = __llapi_layout_cur_comp(layout);
1331         if (comp == NULL)
1332                 return -1;
1333
1334         if (index == NULL) {
1335                 errno = EINVAL;
1336                 return -1;
1337         }
1338
1339         if (stripe_number >= comp->llc_stripe_count ||
1340             stripe_number >= comp->llc_objects_count) {
1341                 errno = EINVAL;
1342                 return -1;
1343         }
1344
1345         if (comp->llc_stripe_offset == LLAPI_LAYOUT_DEFAULT)
1346                 *index = LLAPI_LAYOUT_DEFAULT;
1347         else
1348                 *index = comp->llc_objects[stripe_number].l_ost_idx;
1349
1350         return 0;
1351 }
1352
1353 /**
1354  *
1355  * Get the pool name of layout \a layout.
1356  *
1357  * \param[in] layout    layout to get pool name from
1358  * \param[out] dest     buffer to store pool name in
1359  * \param[in] n         size in bytes of buffer \a dest
1360  *
1361  * \retval      0 on success
1362  * \retval      -1 if arguments are invalid
1363  */
1364 int llapi_layout_pool_name_get(const struct llapi_layout *layout, char *dest,
1365                                size_t n)
1366 {
1367         struct llapi_layout_comp *comp;
1368
1369         comp = __llapi_layout_cur_comp(layout);
1370         if (comp == NULL)
1371                 return -1;
1372
1373         if (dest == NULL) {
1374                 errno = EINVAL;
1375                 return -1;
1376         }
1377
1378         strncpy(dest, comp->llc_pool_name, n);
1379
1380         return 0;
1381 }
1382
1383 /**
1384  * Set the name of the pool of layout \a layout.
1385  *
1386  * \param[in] layout    layout to set pool name in
1387  * \param[in] pool_name pool name to set
1388  *
1389  * \retval      0 on success
1390  * \retval      -1 if arguments are invalid or pool name is too long
1391  */
1392 int llapi_layout_pool_name_set(struct llapi_layout *layout,
1393                                const char *pool_name)
1394 {
1395         struct llapi_layout_comp *comp;
1396         char *ptr;
1397
1398         comp = __llapi_layout_cur_comp(layout);
1399         if (comp == NULL)
1400                 return -1;
1401
1402         if (pool_name == NULL) {
1403                 errno = EINVAL;
1404                 return -1;
1405         }
1406
1407         /* Strip off any 'fsname.' portion. */
1408         ptr = strchr(pool_name, '.');
1409         if (ptr != NULL)
1410                 pool_name = ptr + 1;
1411
1412         if (strlen(pool_name) > LOV_MAXPOOLNAME) {
1413                 errno = EINVAL;
1414                 return -1;
1415         }
1416
1417         strncpy(comp->llc_pool_name, pool_name, sizeof(comp->llc_pool_name));
1418
1419         return 0;
1420 }
1421
1422 /**
1423  * Open and possibly create a file with a given \a layout.
1424  *
1425  * If \a layout is NULL this function acts as a simple wrapper for
1426  * open().  By convention, ENOTTY is returned in errno if \a path
1427  * refers to a non-Lustre file.
1428  *
1429  * \param[in] path              name of the file to open
1430  * \param[in] open_flags        open() flags
1431  * \param[in] mode              permissions to create new file with
1432  * \param[in] layout            layout to create new file with
1433  *
1434  * \retval              non-negative file descriptor on successful open
1435  * \retval              -1 if an error occurred
1436  */
1437 int llapi_layout_file_open(const char *path, int open_flags, mode_t mode,
1438                            const struct llapi_layout *layout)
1439 {
1440         int fd;
1441         int rc;
1442         int tmp;
1443         struct lov_user_md *lum;
1444         size_t lum_size;
1445
1446         if (path == NULL ||
1447             (layout != NULL && layout->llot_magic != LLAPI_LAYOUT_MAGIC)) {
1448                 errno = EINVAL;
1449                 return -1;
1450         }
1451
1452         /* Object creation must be postponed until after layout attributes
1453          * have been applied. */
1454         if (layout != NULL && (open_flags & O_CREAT))
1455                 open_flags |= O_LOV_DELAY_CREATE;
1456
1457         fd = open(path, open_flags, mode);
1458
1459         if (layout == NULL || fd < 0)
1460                 return fd;
1461
1462         lum = llapi_layout_to_lum(layout);
1463
1464         if (lum == NULL) {
1465                 tmp = errno;
1466                 close(fd);
1467                 errno = tmp;
1468                 return -1;
1469         }
1470
1471         if (lum->lmm_magic == LOV_USER_MAGIC_COMP_V1)
1472                 lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
1473         else if (lum->lmm_magic == LOV_USER_MAGIC_SPECIFIC)
1474                 lum_size = lov_user_md_size(lum->lmm_stripe_count,
1475                                             lum->lmm_magic);
1476         else
1477                 lum_size = lov_user_md_size(0, lum->lmm_magic);
1478
1479         rc = fsetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_size, 0);
1480         if (rc < 0) {
1481                 tmp = errno;
1482                 close(fd);
1483                 errno = tmp;
1484                 fd = -1;
1485         }
1486
1487         free(lum);
1488         errno = errno == EOPNOTSUPP ? ENOTTY : errno;
1489
1490         return fd;
1491 }
1492
1493 /**
1494  * Create a file with a given \a layout.
1495  *
1496  * Force O_CREAT and O_EXCL flags on so caller is assured that file was
1497  * created with the given \a layout on successful function return.
1498  *
1499  * \param[in] path              name of the file to open
1500  * \param[in] open_flags        open() flags
1501  * \param[in] mode              permissions to create new file with
1502  * \param[in] layout            layout to create new file with
1503  *
1504  * \retval              non-negative file descriptor on successful open
1505  * \retval              -1 if an error occurred
1506  */
1507 int llapi_layout_file_create(const char *path, int open_flags, int mode,
1508                              const struct llapi_layout *layout)
1509 {
1510         return llapi_layout_file_open(path, open_flags|O_CREAT|O_EXCL, mode,
1511                                       layout);
1512 }
1513
1514 /**
1515  * Set flags to the header of a component layout.
1516  */
1517 int llapi_layout_flags_set(struct llapi_layout *layout, uint32_t flags)
1518 {
1519         if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1520                 errno = EINVAL;
1521                 return -1;
1522         }
1523
1524         layout->llot_flags = flags;
1525         return 0;
1526 }
1527
1528 /**
1529  * Fetch the start and end offset of the current layout component.
1530  *
1531  * \param[in] layout    the layout component
1532  * \param[out] start    extent start, inclusive
1533  * \param[out] end      extent end, exclusive
1534  *
1535  * \retval      0 on success
1536  * \retval      <0 if error occurs
1537  */
1538 int llapi_layout_comp_extent_get(const struct llapi_layout *layout,
1539                                  uint64_t *start, uint64_t *end)
1540 {
1541         struct llapi_layout_comp *comp;
1542
1543         comp = __llapi_layout_cur_comp(layout);
1544         if (comp == NULL)
1545                 return -1;
1546
1547         if (start == NULL || end == NULL) {
1548                 errno = EINVAL;
1549                 return -1;
1550         }
1551
1552         *start = comp->llc_extent.e_start;
1553         *end = comp->llc_extent.e_end;
1554
1555         return 0;
1556 }
1557
1558 /**
1559  * Set the layout extent of a layout.
1560  *
1561  * \param[in] layout    the layout to be set
1562  * \param[in] start     extent start, inclusive
1563  * \param[in] end       extent end, exclusive
1564  *
1565  * \retval      0 on success
1566  * \retval      <0 if error occurs
1567  */
1568 int llapi_layout_comp_extent_set(struct llapi_layout *layout,
1569                                  uint64_t start, uint64_t end)
1570 {
1571         struct llapi_layout_comp *prev, *next, *comp;
1572
1573         comp = __llapi_layout_cur_comp(layout);
1574         if (comp == NULL)
1575                 return -1;
1576
1577         if (start >= end) {
1578                 errno = EINVAL;
1579                 return -1;
1580         }
1581
1582         /*
1583          * We need to make sure the extent to be set is valid: the new
1584          * extent must be adjacent with the prev & next component.
1585          */
1586         if (comp->llc_list.prev != &layout->llot_comp_list) {
1587                 prev = list_entry(comp->llc_list.prev, typeof(*prev),
1588                                   llc_list);
1589                 if (start != prev->llc_extent.e_end) {
1590                         errno = EINVAL;
1591                         return -1;
1592                 }
1593         }
1594
1595         if (comp->llc_list.next != &layout->llot_comp_list) {
1596                 next = list_entry(comp->llc_list.next, typeof(*next),
1597                                   llc_list);
1598                 if (end != next->llc_extent.e_start) {
1599                         errno = EINVAL;
1600                         return -1;
1601                 }
1602         }
1603
1604         comp->llc_extent.e_start = start;
1605         comp->llc_extent.e_end = end;
1606         layout->llot_is_composite = true;
1607
1608         return 0;
1609 }
1610
1611 /**
1612  * Gets the attribute flags of the current component.
1613  *
1614  * \param[in] layout    the layout component
1615  * \param[out] flags    stored the returned component flags
1616  *
1617  * \retval      0 on success
1618  * \retval      <0 if error occurs
1619  */
1620 int llapi_layout_comp_flags_get(const struct llapi_layout *layout,
1621                                 uint32_t *flags)
1622 {
1623         struct llapi_layout_comp *comp;
1624
1625         comp = __llapi_layout_cur_comp(layout);
1626         if (comp == NULL)
1627                 return -1;
1628
1629         if (flags == NULL) {
1630                 errno = EINVAL;
1631                 return -1;
1632         }
1633
1634         *flags = comp->llc_flags;
1635
1636         return 0;
1637 }
1638
1639 /**
1640  * Sets the specified flags of the current component leaving other flags as-is.
1641  *
1642  * \param[in] layout    the layout component
1643  * \param[in] flags     component flags to be set
1644  *
1645  * \retval      0 on success
1646  * \retval      <0 if error occurs
1647  */
1648 int llapi_layout_comp_flags_set(struct llapi_layout *layout, uint32_t flags)
1649 {
1650         struct llapi_layout_comp *comp;
1651
1652         comp = __llapi_layout_cur_comp(layout);
1653         if (comp == NULL)
1654                 return -1;
1655
1656         comp->llc_flags |= flags;
1657
1658         return 0;
1659 }
1660
1661 /**
1662  * Clears the flags specified in the flags leaving other flags as-is.
1663  *
1664  * \param[in] layout    the layout component
1665  * \param[in] flags     component flags to be cleared
1666  *
1667  * \retval      0 on success
1668  * \retval      <0 if error occurs
1669  */
1670 int llapi_layout_comp_flags_clear(struct llapi_layout *layout,
1671                                   uint32_t flags)
1672 {
1673         struct llapi_layout_comp *comp;
1674
1675         comp = __llapi_layout_cur_comp(layout);
1676         if (comp == NULL)
1677                 return -1;
1678
1679         comp->llc_flags &= ~flags;
1680
1681         return 0;
1682 }
1683
1684 /**
1685  * Fetches the file-unique component ID of the current layout component.
1686  *
1687  * \param[in] layout    the layout component
1688  * \param[out] id       stored the returned component ID
1689  *
1690  * \retval      0 on success
1691  * \retval      <0 if error occurs
1692  */
1693 int llapi_layout_comp_id_get(const struct llapi_layout *layout, uint32_t *id)
1694 {
1695         struct llapi_layout_comp *comp;
1696
1697         comp = __llapi_layout_cur_comp(layout);
1698         if (comp == NULL)
1699                 return -1;
1700
1701         if (id == NULL) {
1702                 errno = EINVAL;
1703                 return -1;
1704         }
1705         *id = comp->llc_id;
1706
1707         return 0;
1708 }
1709
1710 /**
1711  * Adds a component to \a layout, the new component will be added to
1712  * the tail of components list and it'll inherit attributes of existing
1713  * ones. The \a layout will change it's current component pointer to
1714  * the newly added component, and it'll be turned into a composite
1715  * layout if it was not before the adding.
1716  *
1717  * \param[in] layout    existing composite or plain layout
1718  *
1719  * \retval      0 on success
1720  * \retval      <0 if error occurs
1721  */
1722 int llapi_layout_comp_add(struct llapi_layout *layout)
1723 {
1724         struct llapi_layout_comp *last, *comp, *new;
1725
1726         comp = __llapi_layout_cur_comp(layout);
1727         if (comp == NULL)
1728                 return -1;
1729
1730         new = __llapi_comp_alloc(0);
1731         if (new == NULL)
1732                 return -1;
1733
1734         last = list_entry(layout->llot_comp_list.prev, typeof(*last),
1735                           llc_list);
1736
1737         /* Inherit some attributes from existing component */
1738         new->llc_stripe_size = comp->llc_stripe_size;
1739         new->llc_stripe_count = comp->llc_stripe_count;
1740         if (comp->llc_pool_name[0] != '\0')
1741                 strncpy(new->llc_pool_name, comp->llc_pool_name,
1742                         sizeof(comp->llc_pool_name));
1743         if (new->llc_extent.e_end <= last->llc_extent.e_end) {
1744                 __llapi_comp_free(new);
1745                 errno = EINVAL;
1746                 return -1;
1747         }
1748         new->llc_extent.e_start = last->llc_extent.e_end;
1749
1750         list_add_tail(&new->llc_list, &layout->llot_comp_list);
1751         layout->llot_cur_comp = new;
1752         layout->llot_is_composite = true;
1753
1754         return 0;
1755 }
1756
1757 /**
1758  * Deletes current component from the composite layout. The component
1759  * to be deleted must be the tail of components list, and it can't be
1760  * the only component in the layout.
1761  *
1762  * \param[in] layout    composite layout
1763  *
1764  * \retval      0 on success
1765  * \retval      <0 if error occurs
1766  */
1767 int llapi_layout_comp_del(struct llapi_layout *layout)
1768 {
1769         struct llapi_layout_comp *comp;
1770
1771         comp = __llapi_layout_cur_comp(layout);
1772         if (comp == NULL)
1773                 return -1;
1774
1775         if (!layout->llot_is_composite) {
1776                 errno = EINVAL;
1777                 return -1;
1778         }
1779
1780         /* It must be the tail of the list (for PFL, can be relaxed
1781          * once we get mirrored components) */
1782         if (comp->llc_list.next != &layout->llot_comp_list) {
1783                 errno = EINVAL;
1784                 return -1;
1785         }
1786         /* It can't be the only one on the list */
1787         if (comp->llc_list.prev == &layout->llot_comp_list) {
1788                 errno = EINVAL;
1789                 return -1;
1790         }
1791
1792         layout->llot_cur_comp =
1793                 list_entry(comp->llc_list.prev, typeof(*comp), llc_list);
1794         list_del_init(&comp->llc_list);
1795         __llapi_comp_free(comp);
1796
1797         return 0;
1798 }
1799
1800 /**
1801  * Move the current component pointer to the component with
1802  * specified component ID.
1803  *
1804  * \param[in] layout    composite layout
1805  * \param[in] id        component ID
1806  *
1807  * \retval      =0 : moved successfully
1808  * \retval      <0 if error occurs
1809  */
1810 int llapi_layout_comp_use_id(struct llapi_layout *layout, uint32_t comp_id)
1811 {
1812         struct llapi_layout_comp *comp;
1813
1814         comp = __llapi_layout_cur_comp(layout);
1815         if (comp == NULL)
1816                 return -1; /* use previously set errno */
1817
1818         if (!layout->llot_is_composite) {
1819                 errno = EINVAL;
1820                 return -1;
1821         }
1822
1823         if (comp_id == LCME_ID_INVAL) {
1824                 errno = EINVAL;
1825                 return -1;
1826         }
1827
1828         list_for_each_entry(comp, &layout->llot_comp_list, llc_list) {
1829                 if (comp->llc_id == comp_id) {
1830                         layout->llot_cur_comp = comp;
1831                         return 0;
1832                 }
1833         }
1834         errno = ENOENT;
1835         return -1;
1836 }
1837
1838 /**
1839  * Move the current component pointer to a specified position.
1840  *
1841  * \param[in] layout    composite layout
1842  * \param[in] pos       the position to be moved, it can be:
1843  *                      LLAPI_LAYOUT_COMP_USE_FIRST: use first component
1844  *                      LLAPI_LAYOUT_COMP_USE_LAST: use last component
1845  *                      LLAPI_LAYOUT_COMP_USE_NEXT: use component after current
1846  *                      LLAPI_LAYOUT_COMP_USE_PREV: use component before current
1847  *
1848  * \retval      =0 : moved successfully
1849  * \retval      =1 : at last component with NEXT, at first component with PREV
1850  * \retval      <0 if error occurs
1851  */
1852 int llapi_layout_comp_use(struct llapi_layout *layout,
1853                           enum llapi_layout_comp_use pos)
1854 {
1855         struct llapi_layout_comp *comp, *head, *tail;
1856
1857         comp = __llapi_layout_cur_comp(layout);
1858         if (comp == NULL)
1859                 return -1;
1860
1861         if (!layout->llot_is_composite) {
1862                 if (pos == LLAPI_LAYOUT_COMP_USE_FIRST ||
1863                     pos == LLAPI_LAYOUT_COMP_USE_LAST)
1864                         return 0;
1865                 errno = ENOENT;
1866                 return 1;
1867         }
1868
1869         head = list_entry(layout->llot_comp_list.next, typeof(*head), llc_list);
1870         tail = list_entry(layout->llot_comp_list.prev, typeof(*tail), llc_list);
1871         switch (pos) {
1872         case LLAPI_LAYOUT_COMP_USE_FIRST:
1873                 layout->llot_cur_comp = head;
1874                 break;
1875         case LLAPI_LAYOUT_COMP_USE_NEXT:
1876                 if (comp == tail) {
1877                         errno = ENOENT;
1878                         return 1;
1879                 }
1880                 layout->llot_cur_comp = list_entry(comp->llc_list.next,
1881                                                    typeof(*comp), llc_list);
1882                 break;
1883         case LLAPI_LAYOUT_COMP_USE_LAST:
1884                 layout->llot_cur_comp = tail;
1885                 break;
1886         case LLAPI_LAYOUT_COMP_USE_PREV:
1887                 if (comp == head) {
1888                         errno = ENOENT;
1889                         return 1;
1890                 }
1891                 layout->llot_cur_comp = list_entry(comp->llc_list.prev,
1892                                                    typeof(*comp), llc_list);
1893                 break;
1894         default:
1895                 errno = EINVAL;
1896                 return -1;
1897         }
1898
1899         return 0;
1900 }
1901
1902 /**
1903  * Add layout component(s) to an existing file.
1904  *
1905  * \param[in] path      The path name of the file
1906  * \param[in] layout    The layout component(s) to be added
1907  */
1908 int llapi_layout_file_comp_add(const char *path,
1909                                const struct llapi_layout *layout)
1910 {
1911         int rc, fd, lum_size, tmp_errno = 0;
1912         struct lov_user_md *lum;
1913
1914         if (path == NULL || layout == NULL ||
1915             layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1916                 errno = EINVAL;
1917                 return -1;
1918         }
1919
1920         lum = llapi_layout_to_lum(layout);
1921         if (lum == NULL)
1922                 return -1;
1923
1924         if (lum->lmm_magic != LOV_USER_MAGIC_COMP_V1) {
1925                 free(lum);
1926                 errno = EINVAL;
1927                 return -1;
1928         }
1929         lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
1930
1931         fd = open(path, O_RDWR);
1932         if (fd < 0) {
1933                 tmp_errno = errno;
1934                 rc = -1;
1935                 goto out;
1936         }
1937
1938         rc = fsetxattr(fd, XATTR_LUSTRE_LOV".add", lum, lum_size, 0);
1939         if (rc < 0) {
1940                 tmp_errno = errno;
1941                 close(fd);
1942                 rc = -1;
1943                 goto out;
1944         }
1945         close(fd);
1946 out:
1947         free(lum);
1948         errno = tmp_errno;
1949         return rc;
1950 }
1951
1952 /**
1953  * Delete component(s) by the specified component id or component flags
1954  * from an existing file.
1955  *
1956  * \param[in] path      path name of the file
1957  * \param[in] id        unique component ID
1958  * \param[in] flags     flags: LCME_FL_* or;
1959  *                      negative flags: (LCME_FL_NEG|LCME_FL_*)
1960  */
1961 int llapi_layout_file_comp_del(const char *path, uint32_t id, uint32_t flags)
1962 {
1963         int rc, fd, lum_size;
1964         struct llapi_layout *layout;
1965         struct llapi_layout_comp *comp;
1966         struct lov_user_md *lum;
1967
1968         if (path == NULL || id > LCME_ID_MAX || (flags & ~LCME_KNOWN_FLAGS)) {
1969                 errno = EINVAL;
1970                 return -1;
1971         }
1972
1973         /* Can only specify ID or flags, not both. */
1974         if (id != 0 && flags != 0) {
1975                 errno = EINVAL;
1976                 return -1;
1977         }
1978
1979         layout = llapi_layout_alloc();
1980         if (layout == NULL)
1981                 return -1;
1982
1983         llapi_layout_comp_extent_set(layout, 0, LUSTRE_EOF);
1984         comp = __llapi_layout_cur_comp(layout);
1985         if (comp == NULL) {
1986                 llapi_layout_free(layout);
1987                 return -1;
1988         }
1989
1990         comp->llc_id = id;
1991         comp->llc_flags = flags;
1992
1993         lum = llapi_layout_to_lum(layout);
1994         if (lum == NULL) {
1995                 llapi_layout_free(layout);
1996                 return -1;
1997         }
1998         lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
1999
2000         fd = open(path, O_RDWR);
2001         if (fd < 0) {
2002                 rc = -1;
2003                 goto out;
2004         }
2005
2006         rc = fsetxattr(fd, XATTR_LUSTRE_LOV".del", lum, lum_size, 0);
2007         if (rc < 0) {
2008                 int tmp_errno = errno;
2009                 close(fd);
2010                 errno = tmp_errno;
2011                 rc = -1;
2012                 goto out;
2013         }
2014         close(fd);
2015 out:
2016         free(lum);
2017         llapi_layout_free(layout);
2018         return rc;
2019 }
2020
2021 /**
2022  * Change flags or other parameters of the component(s) by component ID of an
2023  * existing file. The component to be modified is specified by the
2024  * comp->lcme_id value, which must be an unique component ID. The new
2025  * attributes are passed in by @comp and @valid is used to specify which
2026  * attributes in the component are going to be changed.
2027  */
2028 int llapi_layout_file_comp_set(const char *path,
2029                                const struct llapi_layout *comp,
2030                                uint32_t valid)
2031 {
2032         errno = EOPNOTSUPP;
2033         return -1;
2034 }
2035
2036 /**
2037  * Check if the file layout is composite.
2038  *
2039  * \param[in] layout    the file layout to check
2040  *
2041  * \retval true         composite
2042  * \retval false        not composite
2043  */
2044 bool llapi_layout_is_composite(struct llapi_layout *layout)
2045 {
2046         return layout->llot_is_composite;
2047 }