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