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