Whamcloud - gitweb
LU-9008 pfl: dynamic layout modification with write/truncate
[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 (comp_v1) {
803                         if (!(comp_v1->lcm_entries[i].lcme_flags &
804                                  LCME_FL_INIT) && obj_count != 0)
805                                 return false;
806                 } else if (obj_count != lum->lmm_stripe_count) {
807                         return false;
808                 }
809         }
810         return true;
811 }
812
813 /**
814  * Get the striping layout for the file referenced by file descriptor \a fd.
815  *
816  * If the filesystem does not support the "lustre." xattr namespace, the
817  * file must be on a non-Lustre filesystem, so set errno to ENOTTY per
818  * convention.  If the file has no "lustre.lov" data, the file will
819  * inherit default values, so return a default layout.
820  *
821  * If the kernel gives us back less than the expected amount of data,
822  * we fail with errno set to EINTR.
823  *
824  * \param[in] fd        open file descriptor
825  * \param[in] flags     open file descriptor
826  *
827  * \retval      valid llapi_layout pointer on success
828  * \retval      NULL if an error occurs
829  */
830 struct llapi_layout *llapi_layout_get_by_fd(int fd, uint32_t flags)
831 {
832         size_t lum_len;
833         struct lov_user_md *lum;
834         struct llapi_layout *layout = NULL;
835         ssize_t bytes_read;
836         struct stat st;
837
838         lum_len = XATTR_SIZE_MAX;
839         lum = malloc(lum_len);
840         if (lum == NULL)
841                 return NULL;
842
843         bytes_read = fgetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_len);
844         if (bytes_read < 0) {
845                 if (errno == EOPNOTSUPP)
846                         errno = ENOTTY;
847                 else if (errno == ENODATA)
848                         layout = llapi_layout_alloc();
849                 goto out;
850         }
851
852         /* Return an error if we got back a partial layout. */
853         if (llapi_layout_lum_truncated(lum, bytes_read)) {
854                 errno = EINTR;
855                 goto out;
856         }
857
858         llapi_layout_swab_lov_user_md(lum, bytes_read);
859
860         /* Directories may have a positive non-zero lum->lmm_stripe_count
861          * yet have an empty lum->lmm_objects array. For non-directories the
862          * amount of data returned from the kernel must be consistent
863          * with the stripe count. */
864         if (fstat(fd, &st) < 0)
865                 goto out;
866
867         if (!S_ISDIR(st.st_mode) && !llapi_layout_lum_valid(lum, bytes_read)) {
868                 errno = EINTR;
869                 goto out;
870         }
871
872         layout = llapi_layout_from_lum(lum, bytes_read);
873 out:
874         free(lum);
875         return layout;
876 }
877
878 /**
879  * Get the expected striping layout for a file at \a path.
880  *
881  * Substitute expected inherited attribute values for unspecified
882  * attributes.  Unspecified attributes may belong to directories and
883  * never-written-to files, and indicate that default values will be
884  * assigned when files are created or first written to.  A default value
885  * is inherited from the parent directory if the attribute is specified
886  * there, otherwise it is inherited from the filesystem root.
887  * Unspecified attributes normally have the value LLAPI_LAYOUT_DEFAULT.
888  *
889  * The complete \a path need not refer to an existing file or directory,
890  * but some leading portion of it must reside within a lustre filesystem.
891  * A use case for this interface would be to obtain the literal striping
892  * values that would be assigned to a new file in a given directory.
893  *
894  * \param[in] path      path for which to get the expected layout
895  *
896  * \retval      valid llapi_layout pointer on success
897  * \retval      NULL if an error occurs
898  */
899 static struct llapi_layout *llapi_layout_expected(const char *path)
900 {
901         struct llapi_layout     *path_layout = NULL;
902         char                    donor_path[PATH_MAX];
903         struct stat st;
904         int fd;
905         int rc;
906
907         fd = open(path, O_RDONLY);
908         if (fd < 0 && errno != ENOENT)
909                 return NULL;
910
911         if (fd >= 0) {
912                 int tmp;
913
914                 path_layout = llapi_layout_get_by_fd(fd, 0);
915                 tmp = errno;
916                 close(fd);
917                 errno = tmp;
918         }
919
920         if (path_layout == NULL) {
921                 if (errno != ENODATA && errno != ENOENT)
922                         return NULL;
923
924                 path_layout = llapi_layout_alloc();
925                 if (path_layout == NULL)
926                         return NULL;
927         }
928
929         if (is_any_specified(path_layout)) {
930                 inherit_sys_attributes(path_layout, path);
931                 return path_layout;
932         }
933
934         llapi_layout_free(path_layout);
935
936         rc = stat(path, &st);
937         if (rc < 0 && errno != ENOENT)
938                 return NULL;
939
940         /* If path is a not a directory or doesn't exist, inherit layout
941          * from parent directory. */
942         if ((rc == 0 && !S_ISDIR(st.st_mode)) ||
943             (rc < 0 && errno == ENOENT)) {
944                 get_parent_dir(path, donor_path, sizeof(donor_path));
945                 path_layout = llapi_layout_get_by_path(donor_path, 0);
946                 if (path_layout != NULL) {
947                         if (is_any_specified(path_layout)) {
948                                 inherit_sys_attributes(path_layout, donor_path);
949                                 return path_layout;
950                         }
951                         llapi_layout_free(path_layout);
952                 }
953         }
954
955         /* Inherit layout from the filesystem root. */
956         rc = llapi_search_mounts(path, 0, donor_path, NULL);
957         if (rc < 0)
958                 return NULL;
959         path_layout = llapi_layout_get_by_path(donor_path, 0);
960         if (path_layout == NULL)
961                 return NULL;
962
963         inherit_sys_attributes(path_layout, donor_path);
964         return path_layout;
965 }
966
967 /**
968  * Get the striping layout for the file at \a path.
969  *
970  * If \a flags contains LAYOUT_GET_EXPECTED, substitute
971  * expected inherited attribute values for unspecified attributes. See
972  * llapi_layout_expected().
973  *
974  * \param[in] path      path for which to get the layout
975  * \param[in] flags     flags to control how layout is retrieved
976  *
977  * \retval      valid llapi_layout pointer on success
978  * \retval      NULL if an error occurs
979  */
980 struct llapi_layout *llapi_layout_get_by_path(const char *path, uint32_t flags)
981 {
982         struct llapi_layout *layout = NULL;
983         int fd;
984         int tmp;
985
986         if (flags & LAYOUT_GET_EXPECTED)
987                 return llapi_layout_expected(path);
988
989         fd = open(path, O_RDONLY);
990         if (fd < 0)
991                 return layout;
992
993         layout = llapi_layout_get_by_fd(fd, flags);
994         tmp = errno;
995         close(fd);
996         errno = tmp;
997
998         return layout;
999 }
1000
1001 /**
1002  * Get the layout for the file with FID \a fidstr in filesystem \a lustre_dir.
1003  *
1004  * \param[in] lustre_dir        path within Lustre filesystem containing \a fid
1005  * \param[in] fid               Lustre identifier of file to get layout for
1006  *
1007  * \retval      valid llapi_layout pointer on success
1008  * \retval      NULL if an error occurs
1009  */
1010 struct llapi_layout *llapi_layout_get_by_fid(const char *lustre_dir,
1011                                              const lustre_fid *fid,
1012                                              uint32_t flags)
1013 {
1014         int fd;
1015         int tmp;
1016         int saved_msg_level = llapi_msg_get_level();
1017         struct llapi_layout *layout = NULL;
1018
1019         /* Prevent llapi internal routines from writing to console
1020          * while executing this function, then restore previous message
1021          * level. */
1022         llapi_msg_set_level(LLAPI_MSG_OFF);
1023         fd = llapi_open_by_fid(lustre_dir, fid, O_RDONLY);
1024         llapi_msg_set_level(saved_msg_level);
1025
1026         if (fd < 0)
1027                 return NULL;
1028
1029         layout = llapi_layout_get_by_fd(fd, flags);
1030         tmp = errno;
1031         close(fd);
1032         errno = tmp;
1033
1034         return layout;
1035 }
1036
1037 /**
1038  * Get the stripe count of \a layout.
1039  *
1040  * \param[in] layout    layout to get stripe count from
1041  * \param[out] count    integer to store stripe count in
1042  *
1043  * \retval      0 on success
1044  * \retval      -1 if arguments are invalid
1045  */
1046 int llapi_layout_stripe_count_get(const struct llapi_layout *layout,
1047                                   uint64_t *count)
1048 {
1049         struct llapi_layout_comp *comp;
1050
1051         comp = __llapi_layout_cur_comp(layout);
1052         if (comp == NULL)
1053                 return -1;
1054
1055         if (count == NULL) {
1056                 errno = EINVAL;
1057                 return -1;
1058         }
1059
1060         *count = comp->llc_stripe_count;
1061
1062         return 0;
1063 }
1064
1065 /*
1066  * The llapi_layout API functions have these extra validity checks since
1067  * they use intuitively named macros to denote special behavior, whereas
1068  * the old API uses 0 and -1.
1069  */
1070
1071 static bool llapi_layout_stripe_count_is_valid(int64_t stripe_count)
1072 {
1073         return stripe_count == LLAPI_LAYOUT_DEFAULT ||
1074                 stripe_count == LLAPI_LAYOUT_WIDE ||
1075                 (stripe_count != 0 && stripe_count != -1 &&
1076                  llapi_stripe_count_is_valid(stripe_count));
1077 }
1078
1079 static bool llapi_layout_stripe_size_is_valid(uint64_t stripe_size)
1080 {
1081         return stripe_size == LLAPI_LAYOUT_DEFAULT ||
1082                 (stripe_size != 0 &&
1083                  llapi_stripe_size_is_aligned(stripe_size) &&
1084                  !llapi_stripe_size_is_too_big(stripe_size));
1085 }
1086
1087 static bool llapi_layout_stripe_index_is_valid(int64_t stripe_index)
1088 {
1089         return stripe_index == LLAPI_LAYOUT_DEFAULT ||
1090                 (stripe_index >= 0 &&
1091                 llapi_stripe_index_is_valid(stripe_index));
1092 }
1093
1094 /**
1095  * Set the stripe count of \a layout.
1096  *
1097  * \param[in] layout    layout to set stripe count in
1098  * \param[in] count     value to be set
1099  *
1100  * \retval      0 on success
1101  * \retval      -1 if arguments are invalid
1102  */
1103 int llapi_layout_stripe_count_set(struct llapi_layout *layout,
1104                                   uint64_t count)
1105 {
1106         struct llapi_layout_comp *comp;
1107
1108         comp = __llapi_layout_cur_comp(layout);
1109         if (comp == NULL)
1110                 return -1;
1111
1112         if (!llapi_layout_stripe_count_is_valid(count)) {
1113                 errno = EINVAL;
1114                 return -1;
1115         }
1116
1117         comp->llc_stripe_count = count;
1118
1119         return 0;
1120 }
1121
1122 /**
1123  * Get the stripe size of \a layout.
1124  *
1125  * \param[in] layout    layout to get stripe size from
1126  * \param[out] size     integer to store stripe size in
1127  *
1128  * \retval      0 on success
1129  * \retval      -1 if arguments are invalid
1130  */
1131 int llapi_layout_stripe_size_get(const struct llapi_layout *layout,
1132                                  uint64_t *size)
1133 {
1134         struct llapi_layout_comp *comp;
1135
1136         comp = __llapi_layout_cur_comp(layout);
1137         if (comp == NULL)
1138                 return -1;
1139
1140         if (size == NULL) {
1141                 errno = EINVAL;
1142                 return -1;
1143         }
1144
1145         *size = comp->llc_stripe_size;
1146
1147         return 0;
1148 }
1149
1150 /**
1151  * Set the stripe size of \a layout.
1152  *
1153  * \param[in] layout    layout to set stripe size in
1154  * \param[in] size      value to be set
1155  *
1156  * \retval      0 on success
1157  * \retval      -1 if arguments are invalid
1158  */
1159 int llapi_layout_stripe_size_set(struct llapi_layout *layout,
1160                                  uint64_t size)
1161 {
1162         struct llapi_layout_comp *comp;
1163
1164         comp = __llapi_layout_cur_comp(layout);
1165         if (comp == NULL)
1166                 return -1;
1167
1168         if (!llapi_layout_stripe_size_is_valid(size)) {
1169                 errno = EINVAL;
1170                 return -1;
1171         }
1172
1173         comp->llc_stripe_size = size;
1174
1175         return 0;
1176 }
1177
1178 /**
1179  * Get the RAID pattern of \a layout.
1180  *
1181  * \param[in] layout    layout to get pattern from
1182  * \param[out] pattern  integer to store pattern in
1183  *
1184  * \retval      0 on success
1185  * \retval      -1 if arguments are invalid
1186  */
1187 int llapi_layout_pattern_get(const struct llapi_layout *layout,
1188                              uint64_t *pattern)
1189 {
1190         struct llapi_layout_comp *comp;
1191
1192         comp = __llapi_layout_cur_comp(layout);
1193         if (comp == NULL)
1194                 return -1;
1195
1196         if (pattern == NULL) {
1197                 errno = EINVAL;
1198                 return -1;
1199         }
1200
1201         *pattern = comp->llc_pattern;
1202
1203         return 0;
1204 }
1205
1206 /**
1207  * Set the RAID pattern of \a layout.
1208  *
1209  * \param[in] layout    layout to set pattern in
1210  * \param[in] pattern   value to be set
1211  *
1212  * \retval      0 on success
1213  * \retval      -1 if arguments are invalid or RAID pattern
1214  *              is unsupported
1215  */
1216 int llapi_layout_pattern_set(struct llapi_layout *layout, uint64_t pattern)
1217 {
1218         struct llapi_layout_comp *comp;
1219
1220         comp = __llapi_layout_cur_comp(layout);
1221         if (comp == NULL)
1222                 return -1;
1223
1224         if (pattern != LLAPI_LAYOUT_DEFAULT &&
1225             pattern != LLAPI_LAYOUT_RAID0) {
1226                 errno = EOPNOTSUPP;
1227                 return -1;
1228         }
1229
1230         comp->llc_pattern = pattern |
1231                             (comp->llc_pattern & LLAPI_LAYOUT_SPECIFIC);
1232
1233         return 0;
1234 }
1235
1236 static inline int stripe_number_roundup(int stripe_number)
1237 {
1238         unsigned int round_up = (stripe_number + 8) & ~7;
1239         return round_up > LOV_MAX_STRIPE_COUNT ?
1240                 LOV_MAX_STRIPE_COUNT : round_up;
1241 }
1242
1243 /**
1244  * Set the OST index of stripe number \a stripe_number to \a ost_index.
1245  *
1246  * If only the starting stripe's OST index is specified, then this can use
1247  * the normal LOV_MAGIC_{V1,V3} layout type.  If multiple OST indices are
1248  * given, then allocate an array to hold the list of indices and ensure that
1249  * the LOV_USER_MAGIC_SPECIFIC layout is used when creating the file.
1250  *
1251  * \param[in] layout            layout to set OST index in
1252  * \param[in] stripe_number     stripe number to set index for
1253  * \param[in] ost_index         the index to set
1254  *
1255  * \retval      0 on success
1256  * \retval      -1 if arguments are invalid or an unsupported stripe number
1257  *              was specified, error returned in errno
1258  */
1259 int llapi_layout_ost_index_set(struct llapi_layout *layout, int stripe_number,
1260                                uint64_t ost_index)
1261 {
1262         struct llapi_layout_comp *comp;
1263
1264         comp = __llapi_layout_cur_comp(layout);
1265         if (comp == NULL)
1266                 return -1;
1267
1268         if (!llapi_layout_stripe_index_is_valid(ost_index)) {
1269                 errno = EINVAL;
1270                 return -1;
1271         }
1272
1273         if (stripe_number == 0 && ost_index == LLAPI_LAYOUT_DEFAULT) {
1274                 comp->llc_stripe_offset = ost_index;
1275                 comp->llc_pattern &= ~LLAPI_LAYOUT_SPECIFIC;
1276                 __llapi_comp_objects_realloc(comp, 0);
1277         } else if (stripe_number >= 0 &&
1278                    stripe_number < LOV_MAX_STRIPE_COUNT) {
1279                 if (ost_index >= LLAPI_LAYOUT_IDX_MAX) {
1280                         errno = EINVAL;
1281                         return -1;
1282                 }
1283
1284                 /* Preallocate a few more stripes to avoid realloc() overhead.*/
1285                 if (__llapi_comp_objects_realloc(comp,
1286                                 stripe_number_roundup(stripe_number)) < 0)
1287                         return -1;
1288
1289                 comp->llc_objects[stripe_number].l_ost_idx = ost_index;
1290
1291                 if (stripe_number == 0)
1292                         comp->llc_stripe_offset = ost_index;
1293                 else
1294                         comp->llc_pattern |= LLAPI_LAYOUT_SPECIFIC;
1295
1296                 if (comp->llc_stripe_count == LLAPI_LAYOUT_DEFAULT ||
1297                     comp->llc_stripe_count <= stripe_number)
1298                         comp->llc_stripe_count = stripe_number + 1;
1299         } else {
1300                 errno = EINVAL;
1301                 return -1;
1302         }
1303
1304         return 0;
1305 }
1306
1307 /**
1308  * Get the OST index associated with stripe \a stripe_number.
1309  *
1310  * Stripes are indexed starting from zero.
1311  *
1312  * \param[in] layout            layout to get index from
1313  * \param[in] stripe_number     stripe number to get index for
1314  * \param[out] index            integer to store index in
1315  *
1316  * \retval      0 on success
1317  * \retval      -1 if arguments are invalid
1318  */
1319 int llapi_layout_ost_index_get(const struct llapi_layout *layout,
1320                                uint64_t stripe_number, uint64_t *index)
1321 {
1322         struct llapi_layout_comp *comp;
1323
1324         comp = __llapi_layout_cur_comp(layout);
1325         if (comp == NULL)
1326                 return -1;
1327
1328         if (index == NULL) {
1329                 errno = EINVAL;
1330                 return -1;
1331         }
1332
1333         if (stripe_number >= comp->llc_stripe_count ||
1334             stripe_number >= comp->llc_objects_count) {
1335                 errno = EINVAL;
1336                 return -1;
1337         }
1338
1339         if (comp->llc_stripe_offset == LLAPI_LAYOUT_DEFAULT)
1340                 *index = LLAPI_LAYOUT_DEFAULT;
1341         else
1342                 *index = comp->llc_objects[stripe_number].l_ost_idx;
1343
1344         return 0;
1345 }
1346
1347 /**
1348  *
1349  * Get the pool name of layout \a layout.
1350  *
1351  * \param[in] layout    layout to get pool name from
1352  * \param[out] dest     buffer to store pool name in
1353  * \param[in] n         size in bytes of buffer \a dest
1354  *
1355  * \retval      0 on success
1356  * \retval      -1 if arguments are invalid
1357  */
1358 int llapi_layout_pool_name_get(const struct llapi_layout *layout, char *dest,
1359                                size_t n)
1360 {
1361         struct llapi_layout_comp *comp;
1362
1363         comp = __llapi_layout_cur_comp(layout);
1364         if (comp == NULL)
1365                 return -1;
1366
1367         if (dest == NULL) {
1368                 errno = EINVAL;
1369                 return -1;
1370         }
1371
1372         strncpy(dest, comp->llc_pool_name, n);
1373
1374         return 0;
1375 }
1376
1377 /**
1378  * Set the name of the pool of layout \a layout.
1379  *
1380  * \param[in] layout    layout to set pool name in
1381  * \param[in] pool_name pool name to set
1382  *
1383  * \retval      0 on success
1384  * \retval      -1 if arguments are invalid or pool name is too long
1385  */
1386 int llapi_layout_pool_name_set(struct llapi_layout *layout,
1387                                const char *pool_name)
1388 {
1389         struct llapi_layout_comp *comp;
1390         char *ptr;
1391
1392         comp = __llapi_layout_cur_comp(layout);
1393         if (comp == NULL)
1394                 return -1;
1395
1396         if (pool_name == NULL) {
1397                 errno = EINVAL;
1398                 return -1;
1399         }
1400
1401         /* Strip off any 'fsname.' portion. */
1402         ptr = strchr(pool_name, '.');
1403         if (ptr != NULL)
1404                 pool_name = ptr + 1;
1405
1406         if (strlen(pool_name) > LOV_MAXPOOLNAME) {
1407                 errno = EINVAL;
1408                 return -1;
1409         }
1410
1411         strncpy(comp->llc_pool_name, pool_name, sizeof(comp->llc_pool_name));
1412
1413         return 0;
1414 }
1415
1416 /**
1417  * Open and possibly create a file with a given \a layout.
1418  *
1419  * If \a layout is NULL this function acts as a simple wrapper for
1420  * open().  By convention, ENOTTY is returned in errno if \a path
1421  * refers to a non-Lustre file.
1422  *
1423  * \param[in] path              name of the file to open
1424  * \param[in] open_flags        open() flags
1425  * \param[in] mode              permissions to create new file with
1426  * \param[in] layout            layout to create new file with
1427  *
1428  * \retval              non-negative file descriptor on successful open
1429  * \retval              -1 if an error occurred
1430  */
1431 int llapi_layout_file_open(const char *path, int open_flags, mode_t mode,
1432                            const struct llapi_layout *layout)
1433 {
1434         int fd;
1435         int rc;
1436         int tmp;
1437         struct lov_user_md *lum;
1438         size_t lum_size;
1439
1440         if (path == NULL ||
1441             (layout != NULL && layout->llot_magic != LLAPI_LAYOUT_MAGIC)) {
1442                 errno = EINVAL;
1443                 return -1;
1444         }
1445
1446         /* Object creation must be postponed until after layout attributes
1447          * have been applied. */
1448         if (layout != NULL && (open_flags & O_CREAT))
1449                 open_flags |= O_LOV_DELAY_CREATE;
1450
1451         fd = open(path, open_flags, mode);
1452
1453         if (layout == NULL || fd < 0)
1454                 return fd;
1455
1456         lum = llapi_layout_to_lum(layout);
1457
1458         if (lum == NULL) {
1459                 tmp = errno;
1460                 close(fd);
1461                 errno = tmp;
1462                 return -1;
1463         }
1464
1465         if (lum->lmm_magic == LOV_USER_MAGIC_COMP_V1)
1466                 lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
1467         else if (lum->lmm_magic == LOV_USER_MAGIC_SPECIFIC)
1468                 lum_size = lov_user_md_size(lum->lmm_stripe_count,
1469                                             lum->lmm_magic);
1470         else
1471                 lum_size = lov_user_md_size(0, lum->lmm_magic);
1472
1473         rc = fsetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_size, 0);
1474         if (rc < 0) {
1475                 tmp = errno;
1476                 close(fd);
1477                 errno = tmp;
1478                 fd = -1;
1479         }
1480
1481         free(lum);
1482         errno = errno == EOPNOTSUPP ? ENOTTY : errno;
1483
1484         return fd;
1485 }
1486
1487 /**
1488  * Create a file with a given \a layout.
1489  *
1490  * Force O_CREAT and O_EXCL flags on so caller is assured that file was
1491  * created with the given \a layout on successful function return.
1492  *
1493  * \param[in] path              name of the file to open
1494  * \param[in] open_flags        open() flags
1495  * \param[in] mode              permissions to create new file with
1496  * \param[in] layout            layout to create new file with
1497  *
1498  * \retval              non-negative file descriptor on successful open
1499  * \retval              -1 if an error occurred
1500  */
1501 int llapi_layout_file_create(const char *path, int open_flags, int mode,
1502                              const struct llapi_layout *layout)
1503 {
1504         return llapi_layout_file_open(path, open_flags|O_CREAT|O_EXCL, mode,
1505                                       layout);
1506 }
1507
1508 /**
1509  * Fetch the start and end offset of the current layout component.
1510  *
1511  * \param[in] layout    the layout component
1512  * \param[out] start    extent start, inclusive
1513  * \param[out] end      extent end, exclusive
1514  *
1515  * \retval      0 on success
1516  * \retval      <0 if error occurs
1517  */
1518 int llapi_layout_comp_extent_get(const struct llapi_layout *layout,
1519                                  uint64_t *start, uint64_t *end)
1520 {
1521         struct llapi_layout_comp *comp;
1522
1523         comp = __llapi_layout_cur_comp(layout);
1524         if (comp == NULL)
1525                 return -1;
1526
1527         if (start == NULL || end == NULL) {
1528                 errno = EINVAL;
1529                 return -1;
1530         }
1531
1532         *start = comp->llc_extent.e_start;
1533         *end = comp->llc_extent.e_end;
1534
1535         return 0;
1536 }
1537
1538 /**
1539  * Set the layout extent of a layout.
1540  *
1541  * \param[in] layout    the layout to be set
1542  * \param[in] start     extent start, inclusive
1543  * \param[in] end       extent end, exclusive
1544  *
1545  * \retval      0 on success
1546  * \retval      <0 if error occurs
1547  */
1548 int llapi_layout_comp_extent_set(struct llapi_layout *layout,
1549                                  uint64_t start, uint64_t end)
1550 {
1551         struct llapi_layout_comp *prev, *next, *comp;
1552
1553         comp = __llapi_layout_cur_comp(layout);
1554         if (comp == NULL)
1555                 return -1;
1556
1557         if (start >= end) {
1558                 errno = EINVAL;
1559                 return -1;
1560         }
1561
1562         /*
1563          * We need to make sure the extent to be set is valid: the new
1564          * extent must be adjacent with the prev & next component.
1565          */
1566         if (comp->llc_list.prev != &layout->llot_comp_list) {
1567                 prev = list_entry(comp->llc_list.prev, typeof(*prev),
1568                                   llc_list);
1569                 if (start != prev->llc_extent.e_end) {
1570                         errno = EINVAL;
1571                         return -1;
1572                 }
1573         }
1574
1575         if (comp->llc_list.next != &layout->llot_comp_list) {
1576                 next = list_entry(comp->llc_list.next, typeof(*next),
1577                                   llc_list);
1578                 if (end != next->llc_extent.e_start) {
1579                         errno = EINVAL;
1580                         return -1;
1581                 }
1582         }
1583
1584         comp->llc_extent.e_start = start;
1585         comp->llc_extent.e_end = end;
1586         layout->llot_is_composite = true;
1587
1588         return 0;
1589 }
1590
1591 /**
1592  * Gets the attribute flags of the current component.
1593  *
1594  * \param[in] layout    the layout component
1595  * \param[out] flags    stored the returned component flags
1596  *
1597  * \retval      0 on success
1598  * \retval      <0 if error occurs
1599  */
1600 int llapi_layout_comp_flags_get(const struct llapi_layout *layout,
1601                                 uint32_t *flags)
1602 {
1603         struct llapi_layout_comp *comp;
1604
1605         comp = __llapi_layout_cur_comp(layout);
1606         if (comp == NULL)
1607                 return -1;
1608
1609         if (flags == NULL) {
1610                 errno = EINVAL;
1611                 return -1;
1612         }
1613
1614         *flags = comp->llc_flags;
1615
1616         return 0;
1617 }
1618
1619 /**
1620  * Sets the specified flags of the current component leaving other flags as-is.
1621  *
1622  * \param[in] layout    the layout component
1623  * \param[in] flags     component flags to be set
1624  *
1625  * \retval      0 on success
1626  * \retval      <0 if error occurs
1627  */
1628 int llapi_layout_comp_flags_set(struct llapi_layout *layout, uint32_t flags)
1629 {
1630         struct llapi_layout_comp *comp;
1631
1632         comp = __llapi_layout_cur_comp(layout);
1633         if (comp == NULL)
1634                 return -1;
1635
1636         comp->llc_flags |= flags;
1637
1638         return 0;
1639 }
1640
1641 /**
1642  * Clears the flags specified in the flags leaving other flags as-is.
1643  *
1644  * \param[in] layout    the layout component
1645  * \param[in] flags     component flags to be cleared
1646  *
1647  * \retval      0 on success
1648  * \retval      <0 if error occurs
1649  */
1650 int llapi_layout_comp_flags_clear(struct llapi_layout *layout,
1651                                   uint32_t flags)
1652 {
1653         struct llapi_layout_comp *comp;
1654
1655         comp = __llapi_layout_cur_comp(layout);
1656         if (comp == NULL)
1657                 return -1;
1658
1659         comp->llc_flags &= ~flags;
1660
1661         return 0;
1662 }
1663
1664 /**
1665  * Fetches the file-unique component ID of the current layout component.
1666  *
1667  * \param[in] layout    the layout component
1668  * \param[out] id       stored the returned component ID
1669  *
1670  * \retval      0 on success
1671  * \retval      <0 if error occurs
1672  */
1673 int llapi_layout_comp_id_get(const struct llapi_layout *layout, uint32_t *id)
1674 {
1675         struct llapi_layout_comp *comp;
1676
1677         comp = __llapi_layout_cur_comp(layout);
1678         if (comp == NULL)
1679                 return -1;
1680
1681         if (id == NULL) {
1682                 errno = EINVAL;
1683                 return -1;
1684         }
1685         *id = comp->llc_id;
1686
1687         return 0;
1688 }
1689
1690 /**
1691  * Adds a component to \a layout, the new component will be added to
1692  * the tail of components list and it'll inherit attributes of existing
1693  * ones. The \a layout will change it's current component pointer to
1694  * the newly added component, and it'll be turned into a composite
1695  * layout if it was not before the adding.
1696  *
1697  * \param[in] layout    existing composite or plain layout
1698  *
1699  * \retval      0 on success
1700  * \retval      <0 if error occurs
1701  */
1702 int llapi_layout_comp_add(struct llapi_layout *layout)
1703 {
1704         struct llapi_layout_comp *last, *comp, *new;
1705
1706         comp = __llapi_layout_cur_comp(layout);
1707         if (comp == NULL)
1708                 return -1;
1709
1710         new = __llapi_comp_alloc(0);
1711         if (new == NULL)
1712                 return -1;
1713
1714         last = list_entry(layout->llot_comp_list.prev, typeof(*last),
1715                           llc_list);
1716
1717         /* Inherit some attributes from existing component */
1718         new->llc_stripe_size = comp->llc_stripe_size;
1719         new->llc_stripe_count = comp->llc_stripe_count;
1720         if (new->llc_extent.e_end <= last->llc_extent.e_end) {
1721                 __llapi_comp_free(new);
1722                 errno = EINVAL;
1723                 return -1;
1724         }
1725         new->llc_extent.e_start = last->llc_extent.e_end;
1726
1727         list_add_tail(&new->llc_list, &layout->llot_comp_list);
1728         layout->llot_cur_comp = new;
1729         layout->llot_is_composite = true;
1730
1731         return 0;
1732 }
1733
1734 /**
1735  * Deletes current component from the composite layout. The component
1736  * to be deleted must be the tail of components list, and it can't be
1737  * the last component in the layout.
1738  *
1739  * \param[in] layout    composite layout
1740  *
1741  * \retval      0 on success
1742  * \retval      <0 if error occurs
1743  */
1744 int llapi_layout_comp_del(struct llapi_layout *layout)
1745 {
1746         struct llapi_layout_comp *comp;
1747
1748         comp = __llapi_layout_cur_comp(layout);
1749         if (comp == NULL)
1750                 return -1;
1751
1752         if (!layout->llot_is_composite) {
1753                 errno = EINVAL;
1754                 return -1;
1755         }
1756
1757         /* It must be the tail of the list */
1758         if (comp->llc_list.next != &layout->llot_comp_list) {
1759                 errno = EINVAL;
1760                 return -1;
1761         }
1762         /* It can't be the last one on the list */
1763         if (comp->llc_list.prev == &layout->llot_comp_list) {
1764                 errno = EINVAL;
1765                 return -1;
1766         }
1767
1768         list_del_init(&comp->llc_list);
1769         __llapi_comp_free(comp);
1770         layout->llot_cur_comp =
1771                 list_entry(comp->llc_list.prev, typeof(*comp),
1772                            llc_list);
1773
1774         return 0;
1775 }
1776
1777 /**
1778  * Move the current component pointer to the component with
1779  * specified component ID.
1780  *
1781  * \param[in] layout    composite layout
1782  * \param[in] id        component ID
1783  *
1784  * \retval      =0 : moved successfully
1785  * \retval      <0 if error occurs
1786  */
1787 int llapi_layout_comp_move_at(struct llapi_layout *layout, uint32_t id)
1788 {
1789         struct llapi_layout_comp *comp;
1790
1791         comp = __llapi_layout_cur_comp(layout);
1792         if (comp == NULL)
1793                 return -1;
1794
1795         if (!layout->llot_is_composite) {
1796                 errno = EINVAL;
1797                 return -1;
1798         }
1799
1800         if (id == 0) {
1801                 errno = EINVAL;
1802                 return -1;
1803         }
1804
1805         list_for_each_entry(comp, &layout->llot_comp_list, llc_list) {
1806                 if (comp->llc_id == id) {
1807                         layout->llot_cur_comp = comp;
1808                         return 0;
1809                 }
1810         }
1811         errno = ENOENT;
1812         return -1;
1813 }
1814
1815 /**
1816  * Move the current component pointer to a specified position.
1817  *
1818  * \param[in] layout    composite layout
1819  * \param[in] pos       the position to be moved, it can be:
1820  *                      LLAPI_LAYOUT_COMP_POS_FIRST: move to head
1821  *                      LLAPI_LAYOUT_COMP_POS_LAST: move to tail
1822  *                      LLAPI_LAYOUT_COMP_POS_NEXT: move to next
1823  *
1824  * \retval      =0 : moved successfully
1825  * \retval      =1 : already at the tail when move to the next
1826  * \retval      <0 if error occurs
1827  */
1828 int llapi_layout_comp_move(struct llapi_layout *layout, uint32_t pos)
1829 {
1830         struct llapi_layout_comp *comp, *head, *tail;
1831
1832         comp = __llapi_layout_cur_comp(layout);
1833         if (comp == NULL)
1834                 return -1;
1835
1836         if (!layout->llot_is_composite) {
1837                 errno = EINVAL;
1838                 return -1;
1839         }
1840
1841         head = list_entry(layout->llot_comp_list.next, typeof(*head),
1842                           llc_list);
1843         tail = list_entry(layout->llot_comp_list.prev, typeof(*tail),
1844                           llc_list);
1845
1846         if (pos == LLAPI_LAYOUT_COMP_POS_NEXT) {
1847                 if (comp == tail)
1848                         return 1;
1849                 layout->llot_cur_comp = list_entry(comp->llc_list.next,
1850                                                    typeof(*comp), llc_list);
1851         } else if (pos == LLAPI_LAYOUT_COMP_POS_FIRST) {
1852                 layout->llot_cur_comp = head;
1853         } else if (pos == LLAPI_LAYOUT_COMP_POS_LAST) {
1854                 layout->llot_cur_comp = tail;
1855         } else {
1856                 errno = EINVAL;
1857                 return -1;
1858         }
1859
1860         return 0;
1861 }
1862
1863 /**
1864  * Add layout component(s) to an existing file.
1865  *
1866  * \param[in] path      The path name of the file
1867  * \param[in] layout    The layout component(s) to be added
1868  */
1869 int llapi_layout_file_comp_add(const char *path,
1870                                const struct llapi_layout *layout)
1871 {
1872         int rc, fd, lum_size, tmp_errno = 0;
1873         struct lov_user_md *lum;
1874
1875         if (path == NULL || layout == NULL ||
1876             layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1877                 errno = EINVAL;
1878                 return -1;
1879         }
1880
1881         lum = llapi_layout_to_lum(layout);
1882         if (lum == NULL)
1883                 return -1;
1884
1885         if (lum->lmm_magic != LOV_USER_MAGIC_COMP_V1) {
1886                 free(lum);
1887                 errno = EINVAL;
1888                 return -1;
1889         }
1890         lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
1891
1892         fd = open(path, O_RDWR);
1893         if (fd < 0) {
1894                 tmp_errno = errno;
1895                 rc = -1;
1896                 goto out;
1897         }
1898
1899         rc = fsetxattr(fd, XATTR_LUSTRE_LOV".add", lum, lum_size, 0);
1900         if (rc < 0) {
1901                 tmp_errno = errno;
1902                 close(fd);
1903                 rc = -1;
1904                 goto out;
1905         }
1906         close(fd);
1907 out:
1908         free(lum);
1909         errno = tmp_errno;
1910         return rc;
1911 }
1912
1913 /**
1914  * Delete component(s) by the specified component id (accepting lcme_id
1915  * wildcards also) from an existing file.
1916  *
1917  * \param[in] path      path name of the file
1918  * \param[in] id        unique component ID or an lcme_id
1919  *                      (LCME_ID_NONE | LCME_FL_* )
1920  */
1921 int llapi_layout_file_comp_del(const char *path, uint32_t id)
1922 {
1923         int rc, fd;
1924
1925         if (path == NULL || id == 0) {
1926                 errno = EINVAL;
1927                 return -1;
1928         }
1929
1930         fd = open(path, O_RDWR);
1931         if (fd < 0)
1932                 return -1;
1933
1934         rc = fsetxattr(fd, XATTR_LUSTRE_LOV".del", &id, sizeof(id), 0);
1935         if (rc < 0) {
1936                 int tmp_errno = errno;
1937                 close(fd);
1938                 errno = tmp_errno;
1939                 return -1;
1940         }
1941         close(fd);
1942         return 0;
1943 }
1944
1945 /**
1946  * Change flags or other parameters of the component(s) by component ID of an
1947  * existing file. The component to be modified is specified by the
1948  * comp->lcme_id value, which must be an unique component ID. The new
1949  * attributes are passed in by @comp and @valid is used to specify which
1950  * attributes in the component are going to be changed.
1951  */
1952 int llapi_layout_file_comp_set(const char *path,
1953                                const struct llapi_layout *comp,
1954                                uint32_t valid)
1955 {
1956         errno = EOPNOTSUPP;
1957         return -1;
1958 }