Whamcloud - gitweb
2ff37b6addf30e8094fa3a0f8cbc0b518f5afc35
[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 int llapi_layout_flags_get(struct llapi_layout *layout, uint32_t *flags)
1515 {
1516         if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1517                 errno = EINVAL;
1518                 return -1;
1519         }
1520
1521         *flags = layout->llot_flags;
1522         return 0;
1523 }
1524
1525 /**
1526  * Set flags to the header of a component layout.
1527  */
1528 int llapi_layout_flags_set(struct llapi_layout *layout, uint32_t flags)
1529 {
1530         if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1531                 errno = EINVAL;
1532                 return -1;
1533         }
1534
1535         layout->llot_flags = flags;
1536         return 0;
1537 }
1538
1539 /**
1540  * Fetch the start and end offset of the current layout component.
1541  *
1542  * \param[in] layout    the layout component
1543  * \param[out] start    extent start, inclusive
1544  * \param[out] end      extent end, exclusive
1545  *
1546  * \retval      0 on success
1547  * \retval      <0 if error occurs
1548  */
1549 int llapi_layout_comp_extent_get(const struct llapi_layout *layout,
1550                                  uint64_t *start, uint64_t *end)
1551 {
1552         struct llapi_layout_comp *comp;
1553
1554         comp = __llapi_layout_cur_comp(layout);
1555         if (comp == NULL)
1556                 return -1;
1557
1558         if (start == NULL || end == NULL) {
1559                 errno = EINVAL;
1560                 return -1;
1561         }
1562
1563         *start = comp->llc_extent.e_start;
1564         *end = comp->llc_extent.e_end;
1565
1566         return 0;
1567 }
1568
1569 /**
1570  * Set the layout extent of a layout.
1571  *
1572  * \param[in] layout    the layout to be set
1573  * \param[in] start     extent start, inclusive
1574  * \param[in] end       extent end, exclusive
1575  *
1576  * \retval      0 on success
1577  * \retval      <0 if error occurs
1578  */
1579 int llapi_layout_comp_extent_set(struct llapi_layout *layout,
1580                                  uint64_t start, uint64_t end)
1581 {
1582         struct llapi_layout_comp *prev, *next, *comp;
1583
1584         comp = __llapi_layout_cur_comp(layout);
1585         if (comp == NULL)
1586                 return -1;
1587
1588         if (start >= end) {
1589                 errno = EINVAL;
1590                 return -1;
1591         }
1592
1593         /*
1594          * We need to make sure the extent to be set is valid: the new
1595          * extent must be adjacent with the prev & next component.
1596          */
1597         if (comp->llc_list.prev != &layout->llot_comp_list) {
1598                 prev = list_entry(comp->llc_list.prev, typeof(*prev),
1599                                   llc_list);
1600                 if (start != prev->llc_extent.e_end) {
1601                         errno = EINVAL;
1602                         return -1;
1603                 }
1604         }
1605
1606         if (comp->llc_list.next != &layout->llot_comp_list) {
1607                 next = list_entry(comp->llc_list.next, typeof(*next),
1608                                   llc_list);
1609                 if (end != next->llc_extent.e_start) {
1610                         errno = EINVAL;
1611                         return -1;
1612                 }
1613         }
1614
1615         comp->llc_extent.e_start = start;
1616         comp->llc_extent.e_end = end;
1617         layout->llot_is_composite = true;
1618
1619         return 0;
1620 }
1621
1622 /**
1623  * Gets the attribute flags of the current component.
1624  *
1625  * \param[in] layout    the layout component
1626  * \param[out] flags    stored the returned component flags
1627  *
1628  * \retval      0 on success
1629  * \retval      <0 if error occurs
1630  */
1631 int llapi_layout_comp_flags_get(const struct llapi_layout *layout,
1632                                 uint32_t *flags)
1633 {
1634         struct llapi_layout_comp *comp;
1635
1636         comp = __llapi_layout_cur_comp(layout);
1637         if (comp == NULL)
1638                 return -1;
1639
1640         if (flags == NULL) {
1641                 errno = EINVAL;
1642                 return -1;
1643         }
1644
1645         *flags = comp->llc_flags;
1646
1647         return 0;
1648 }
1649
1650 /**
1651  * Sets the specified flags of the current component leaving other flags as-is.
1652  *
1653  * \param[in] layout    the layout component
1654  * \param[in] flags     component flags to be set
1655  *
1656  * \retval      0 on success
1657  * \retval      <0 if error occurs
1658  */
1659 int llapi_layout_comp_flags_set(struct llapi_layout *layout, uint32_t flags)
1660 {
1661         struct llapi_layout_comp *comp;
1662
1663         comp = __llapi_layout_cur_comp(layout);
1664         if (comp == NULL)
1665                 return -1;
1666
1667         comp->llc_flags |= flags;
1668
1669         return 0;
1670 }
1671
1672 /**
1673  * Clears the flags specified in the flags leaving other flags as-is.
1674  *
1675  * \param[in] layout    the layout component
1676  * \param[in] flags     component flags to be cleared
1677  *
1678  * \retval      0 on success
1679  * \retval      <0 if error occurs
1680  */
1681 int llapi_layout_comp_flags_clear(struct llapi_layout *layout,
1682                                   uint32_t flags)
1683 {
1684         struct llapi_layout_comp *comp;
1685
1686         comp = __llapi_layout_cur_comp(layout);
1687         if (comp == NULL)
1688                 return -1;
1689
1690         comp->llc_flags &= ~flags;
1691
1692         return 0;
1693 }
1694
1695 /**
1696  * Fetches the file-unique component ID of the current layout component.
1697  *
1698  * \param[in] layout    the layout component
1699  * \param[out] id       stored the returned component ID
1700  *
1701  * \retval      0 on success
1702  * \retval      <0 if error occurs
1703  */
1704 int llapi_layout_comp_id_get(const struct llapi_layout *layout, uint32_t *id)
1705 {
1706         struct llapi_layout_comp *comp;
1707
1708         comp = __llapi_layout_cur_comp(layout);
1709         if (comp == NULL)
1710                 return -1;
1711
1712         if (id == NULL) {
1713                 errno = EINVAL;
1714                 return -1;
1715         }
1716         *id = comp->llc_id;
1717
1718         return 0;
1719 }
1720
1721 /**
1722  * Return the mirror id of the current layout component.
1723  *
1724  * \param[in] layout    the layout component
1725  * \param[out] id       stored the returned mirror ID
1726  *
1727  * \retval      0 on success
1728  * \retval      <0 if error occurs
1729  */
1730 int llapi_layout_mirror_id_get(const struct llapi_layout *layout, uint32_t *id)
1731 {
1732         struct llapi_layout_comp *comp;
1733
1734         comp = __llapi_layout_cur_comp(layout);
1735         if (comp == NULL)
1736                 return -1;
1737
1738         if (id == NULL) {
1739                 errno = EINVAL;
1740                 return -1;
1741         }
1742
1743         *id = mirror_id_of(comp->llc_id);
1744
1745         return 0;
1746 }
1747
1748 /**
1749  * Adds a component to \a layout, the new component will be added to
1750  * the tail of components list and it'll inherit attributes of existing
1751  * ones. The \a layout will change it's current component pointer to
1752  * the newly added component, and it'll be turned into a composite
1753  * layout if it was not before the adding.
1754  *
1755  * \param[in] layout    existing composite or plain layout
1756  *
1757  * \retval      0 on success
1758  * \retval      <0 if error occurs
1759  */
1760 int llapi_layout_comp_add(struct llapi_layout *layout)
1761 {
1762         struct llapi_layout_comp *last, *comp, *new;
1763
1764         comp = __llapi_layout_cur_comp(layout);
1765         if (comp == NULL)
1766                 return -1;
1767
1768         new = __llapi_comp_alloc(0);
1769         if (new == NULL)
1770                 return -1;
1771
1772         last = list_entry(layout->llot_comp_list.prev, typeof(*last),
1773                           llc_list);
1774
1775         /* Inherit some attributes from existing component */
1776         new->llc_stripe_size = comp->llc_stripe_size;
1777         new->llc_stripe_count = comp->llc_stripe_count;
1778         if (comp->llc_pool_name[0] != '\0')
1779                 strncpy(new->llc_pool_name, comp->llc_pool_name,
1780                         sizeof(comp->llc_pool_name));
1781         if (new->llc_extent.e_end <= last->llc_extent.e_end) {
1782                 __llapi_comp_free(new);
1783                 errno = EINVAL;
1784                 return -1;
1785         }
1786         new->llc_extent.e_start = last->llc_extent.e_end;
1787
1788         list_add_tail(&new->llc_list, &layout->llot_comp_list);
1789         layout->llot_cur_comp = new;
1790         layout->llot_is_composite = true;
1791
1792         return 0;
1793 }
1794
1795 /**
1796  * Deletes current component from the composite layout. The component
1797  * to be deleted must be the tail of components list, and it can't be
1798  * the only component in the layout.
1799  *
1800  * \param[in] layout    composite layout
1801  *
1802  * \retval      0 on success
1803  * \retval      <0 if error occurs
1804  */
1805 int llapi_layout_comp_del(struct llapi_layout *layout)
1806 {
1807         struct llapi_layout_comp *comp;
1808
1809         comp = __llapi_layout_cur_comp(layout);
1810         if (comp == NULL)
1811                 return -1;
1812
1813         if (!layout->llot_is_composite) {
1814                 errno = EINVAL;
1815                 return -1;
1816         }
1817
1818         /* It must be the tail of the list (for PFL, can be relaxed
1819          * once we get mirrored components) */
1820         if (comp->llc_list.next != &layout->llot_comp_list) {
1821                 errno = EINVAL;
1822                 return -1;
1823         }
1824         /* It can't be the only one on the list */
1825         if (comp->llc_list.prev == &layout->llot_comp_list) {
1826                 errno = EINVAL;
1827                 return -1;
1828         }
1829
1830         layout->llot_cur_comp =
1831                 list_entry(comp->llc_list.prev, typeof(*comp), llc_list);
1832         list_del_init(&comp->llc_list);
1833         __llapi_comp_free(comp);
1834
1835         return 0;
1836 }
1837
1838 /**
1839  * Move the current component pointer to the component with
1840  * specified component ID.
1841  *
1842  * \param[in] layout    composite layout
1843  * \param[in] id        component ID
1844  *
1845  * \retval      =0 : moved successfully
1846  * \retval      <0 if error occurs
1847  */
1848 int llapi_layout_comp_use_id(struct llapi_layout *layout, uint32_t comp_id)
1849 {
1850         struct llapi_layout_comp *comp;
1851
1852         comp = __llapi_layout_cur_comp(layout);
1853         if (comp == NULL)
1854                 return -1; /* use previously set errno */
1855
1856         if (!layout->llot_is_composite) {
1857                 errno = EINVAL;
1858                 return -1;
1859         }
1860
1861         if (comp_id == LCME_ID_INVAL) {
1862                 errno = EINVAL;
1863                 return -1;
1864         }
1865
1866         list_for_each_entry(comp, &layout->llot_comp_list, llc_list) {
1867                 if (comp->llc_id == comp_id) {
1868                         layout->llot_cur_comp = comp;
1869                         return 0;
1870                 }
1871         }
1872         errno = ENOENT;
1873         return -1;
1874 }
1875
1876 /**
1877  * Move the current component pointer to a specified position.
1878  *
1879  * \param[in] layout    composite layout
1880  * \param[in] pos       the position to be moved, it can be:
1881  *                      LLAPI_LAYOUT_COMP_USE_FIRST: use first component
1882  *                      LLAPI_LAYOUT_COMP_USE_LAST: use last component
1883  *                      LLAPI_LAYOUT_COMP_USE_NEXT: use component after current
1884  *                      LLAPI_LAYOUT_COMP_USE_PREV: use component before current
1885  *
1886  * \retval      =0 : moved successfully
1887  * \retval      =1 : at last component with NEXT, at first component with PREV
1888  * \retval      <0 if error occurs
1889  */
1890 int llapi_layout_comp_use(struct llapi_layout *layout,
1891                           enum llapi_layout_comp_use pos)
1892 {
1893         struct llapi_layout_comp *comp, *head, *tail;
1894
1895         comp = __llapi_layout_cur_comp(layout);
1896         if (comp == NULL)
1897                 return -1;
1898
1899         if (!layout->llot_is_composite) {
1900                 if (pos == LLAPI_LAYOUT_COMP_USE_FIRST ||
1901                     pos == LLAPI_LAYOUT_COMP_USE_LAST)
1902                         return 0;
1903                 errno = ENOENT;
1904                 return 1;
1905         }
1906
1907         head = list_entry(layout->llot_comp_list.next, typeof(*head), llc_list);
1908         tail = list_entry(layout->llot_comp_list.prev, typeof(*tail), llc_list);
1909         switch (pos) {
1910         case LLAPI_LAYOUT_COMP_USE_FIRST:
1911                 layout->llot_cur_comp = head;
1912                 break;
1913         case LLAPI_LAYOUT_COMP_USE_NEXT:
1914                 if (comp == tail) {
1915                         errno = ENOENT;
1916                         return 1;
1917                 }
1918                 layout->llot_cur_comp = list_entry(comp->llc_list.next,
1919                                                    typeof(*comp), llc_list);
1920                 break;
1921         case LLAPI_LAYOUT_COMP_USE_LAST:
1922                 layout->llot_cur_comp = tail;
1923                 break;
1924         case LLAPI_LAYOUT_COMP_USE_PREV:
1925                 if (comp == head) {
1926                         errno = ENOENT;
1927                         return 1;
1928                 }
1929                 layout->llot_cur_comp = list_entry(comp->llc_list.prev,
1930                                                    typeof(*comp), llc_list);
1931                 break;
1932         default:
1933                 errno = EINVAL;
1934                 return -1;
1935         }
1936
1937         return 0;
1938 }
1939
1940 /**
1941  * Add layout component(s) to an existing file.
1942  *
1943  * \param[in] path      The path name of the file
1944  * \param[in] layout    The layout component(s) to be added
1945  */
1946 int llapi_layout_file_comp_add(const char *path,
1947                                const struct llapi_layout *layout)
1948 {
1949         int rc, fd, lum_size, tmp_errno = 0;
1950         struct lov_user_md *lum;
1951
1952         if (path == NULL || layout == NULL ||
1953             layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1954                 errno = EINVAL;
1955                 return -1;
1956         }
1957
1958         lum = llapi_layout_to_lum(layout);
1959         if (lum == NULL)
1960                 return -1;
1961
1962         if (lum->lmm_magic != LOV_USER_MAGIC_COMP_V1) {
1963                 free(lum);
1964                 errno = EINVAL;
1965                 return -1;
1966         }
1967         lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
1968
1969         fd = open(path, O_RDWR);
1970         if (fd < 0) {
1971                 tmp_errno = errno;
1972                 rc = -1;
1973                 goto out;
1974         }
1975
1976         rc = fsetxattr(fd, XATTR_LUSTRE_LOV".add", lum, lum_size, 0);
1977         if (rc < 0) {
1978                 tmp_errno = errno;
1979                 close(fd);
1980                 rc = -1;
1981                 goto out;
1982         }
1983         close(fd);
1984 out:
1985         free(lum);
1986         errno = tmp_errno;
1987         return rc;
1988 }
1989
1990 /**
1991  * Delete component(s) by the specified component id or component flags
1992  * from an existing file.
1993  *
1994  * \param[in] path      path name of the file
1995  * \param[in] id        unique component ID
1996  * \param[in] flags     flags: LCME_FL_* or;
1997  *                      negative flags: (LCME_FL_NEG|LCME_FL_*)
1998  */
1999 int llapi_layout_file_comp_del(const char *path, uint32_t id, uint32_t flags)
2000 {
2001         int rc, fd, lum_size;
2002         struct llapi_layout *layout;
2003         struct llapi_layout_comp *comp;
2004         struct lov_user_md *lum;
2005
2006         if (path == NULL || id > LCME_ID_MAX || (flags & ~LCME_KNOWN_FLAGS)) {
2007                 errno = EINVAL;
2008                 return -1;
2009         }
2010
2011         /* Can only specify ID or flags, not both. */
2012         if (id != 0 && flags != 0) {
2013                 errno = EINVAL;
2014                 return -1;
2015         }
2016
2017         layout = llapi_layout_alloc();
2018         if (layout == NULL)
2019                 return -1;
2020
2021         llapi_layout_comp_extent_set(layout, 0, LUSTRE_EOF);
2022         comp = __llapi_layout_cur_comp(layout);
2023         if (comp == NULL) {
2024                 llapi_layout_free(layout);
2025                 return -1;
2026         }
2027
2028         comp->llc_id = id;
2029         comp->llc_flags = flags;
2030
2031         lum = llapi_layout_to_lum(layout);
2032         if (lum == NULL) {
2033                 llapi_layout_free(layout);
2034                 return -1;
2035         }
2036         lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
2037
2038         fd = open(path, O_RDWR);
2039         if (fd < 0) {
2040                 rc = -1;
2041                 goto out;
2042         }
2043
2044         rc = fsetxattr(fd, XATTR_LUSTRE_LOV".del", lum, lum_size, 0);
2045         if (rc < 0) {
2046                 int tmp_errno = errno;
2047                 close(fd);
2048                 errno = tmp_errno;
2049                 rc = -1;
2050                 goto out;
2051         }
2052         close(fd);
2053 out:
2054         free(lum);
2055         llapi_layout_free(layout);
2056         return rc;
2057 }
2058
2059 /**
2060  * Change flags or other parameters of the component(s) by component ID of an
2061  * existing file. The component to be modified is specified by the
2062  * comp->lcme_id value, which must be an unique component ID. The new
2063  * attributes are passed in by @comp and @valid is used to specify which
2064  * attributes in the component are going to be changed.
2065  */
2066 int llapi_layout_file_comp_set(const char *path,
2067                                const struct llapi_layout *comp,
2068                                uint32_t valid)
2069 {
2070         errno = EOPNOTSUPP;
2071         return -1;
2072 }
2073
2074 /**
2075  * Check if the file layout is composite.
2076  *
2077  * \param[in] layout    the file layout to check
2078  *
2079  * \retval true         composite
2080  * \retval false        not composite
2081  */
2082 bool llapi_layout_is_composite(struct llapi_layout *layout)
2083 {
2084         return layout->llot_is_composite;
2085 }