Whamcloud - gitweb
LU-17744 ldiskfs: mballoc stats fixes
[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, 2017, 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 <assert.h>
38 #include <sys/xattr.h>
39 #include <sys/param.h>
40 #include <sys/time.h>
41 #include <time.h>
42
43 #include <libcfs/util/list.h>
44 #include <lustre/lustreapi.h>
45 #include "lustreapi_internal.h"
46
47 /**
48  * Layout component, which contains all attributes of a plain
49  * V1/V3/FOREIGN(HSM) layout.
50  */
51 struct llapi_layout_comp {
52         uint64_t        llc_pattern;
53         union {
54                 struct { /* For plain layout. */
55                         uint64_t        llc_stripe_size;
56                         uint64_t        llc_stripe_count;
57                         uint64_t        llc_stripe_offset;
58                         /**
59                          * Add 1 so user always gets back a null terminated
60                          * string.
61                          */
62                         char            llc_pool_name[LOV_MAXPOOLNAME + 1];
63                         /**
64                          * Number of objects in llc_objects array if was
65                          * initialized.
66                          */
67                         uint32_t        llc_objects_count;
68                         struct lov_user_ost_data_v1 *llc_objects;
69                 };
70                 struct { /* For FOREIGN/HSM layout. */
71                         uint32_t         llc_length;
72                         uint32_t         llc_type;
73                         uint32_t         llc_hsm_flags;
74                         union {
75                                 struct lov_hsm_base      llc_hsm;
76                                 char                    *llc_value;
77                         };
78                 };
79         };
80
81         /* fields used only for composite layouts */
82         struct lu_extent        llc_extent;     /* [start, end) of component */
83         uint32_t                llc_id;         /* unique ID of component */
84         uint32_t                llc_flags;      /* LCME_FL_* flags */
85         uint64_t                llc_timestamp;  /* snapshot timestamp */
86         struct list_head        llc_list;       /* linked to the llapi_layout
87                                                    components list */
88         bool            llc_ondisk;
89 };
90
91 #define llc_archive_id  llc_hsm.lhb_archive_id
92 #define llc_archive_ver llc_hsm.lhb_archive_ver
93 #define llc_uuid        llc_hsm.lhb_uuid
94
95 /**
96  * An Opaque data type abstracting the layout of a Lustre file.
97  */
98 struct llapi_layout {
99         uint32_t        llot_magic; /* LLAPI_LAYOUT_MAGIC */
100         uint32_t        llot_gen;
101         uint32_t        llot_flags;
102         bool            llot_is_composite;
103         uint16_t        llot_mirror_count;
104         /* Cursor pointing to one of the components in llot_comp_list */
105         struct llapi_layout_comp *llot_cur_comp;
106         struct list_head          llot_comp_list;
107 };
108
109 /**
110  * Compute the number of elements in the lmm_objects array of \a lum
111  * with size \a lum_size.
112  *
113  * \param[in] lum       the struct lov_user_md to check
114  * \param[in] lum_size  the number of bytes in \a lum
115  *
116  * \retval              number of elements in array lum->lmm_objects
117  */
118 static int llapi_layout_objects_in_lum(struct lov_user_md *lum, size_t lum_size)
119 {
120         uint32_t magic;
121         size_t base_size;
122
123         if (lum->lmm_magic == __swab32(LOV_MAGIC_FOREIGN))
124                 return 0;
125
126         if (lum_size < lov_user_md_size(0, LOV_MAGIC_V1))
127                 return 0;
128
129         if (lum->lmm_magic == __swab32(LOV_MAGIC_V1) ||
130             lum->lmm_magic == __swab32(LOV_MAGIC_V3))
131                 magic = __swab32(lum->lmm_magic);
132         else
133                 magic = lum->lmm_magic;
134
135         base_size = lov_user_md_size(0, magic);
136
137         if (lum_size <= base_size)
138                 return 0;
139         else
140                 return (lum_size - base_size) / sizeof(lum->lmm_objects[0]);
141 }
142
143 /**
144  * Byte-swap the fields of struct lov_user_md.
145  *
146  * XXX Rather than duplicating swabbing code here, we should eventually
147  * refactor the needed functions in lustre/ptlrpc/pack_generic.c
148  * into a library that can be shared between kernel and user code.
149  */
150 static void
151 llapi_layout_swab_lov_user_md(struct lov_user_md *lum, int lum_size)
152 {
153         int i, j, ent_count, obj_count;
154         struct lov_comp_md_v1 *comp_v1 = NULL;
155         struct lov_comp_md_entry_v1 *ent;
156         struct lov_user_ost_data *lod;
157
158         if (lum->lmm_magic != __swab32(LOV_MAGIC_V1) &&
159             lum->lmm_magic != __swab32(LOV_MAGIC_V3) &&
160             lum->lmm_magic != __swab32(LOV_MAGIC_COMP_V1))
161                 return;
162
163         if (lum->lmm_magic == __swab32(LOV_MAGIC_COMP_V1))
164                 comp_v1 = (struct lov_comp_md_v1 *)lum;
165
166         if (comp_v1 != NULL) {
167                 comp_v1->lcm_magic = __swab32(comp_v1->lcm_magic);
168                 comp_v1->lcm_size = __swab32(comp_v1->lcm_size);
169                 comp_v1->lcm_layout_gen = __swab32(comp_v1->lcm_layout_gen);
170                 comp_v1->lcm_flags = __swab16(comp_v1->lcm_flags);
171                 comp_v1->lcm_entry_count = __swab16(comp_v1->lcm_entry_count);
172                 ent_count = comp_v1->lcm_entry_count;
173         } else {
174                 ent_count = 1;
175         }
176
177         for (i = 0; i < ent_count; i++) {
178                 if (comp_v1 != NULL) {
179                         ent = &comp_v1->lcm_entries[i];
180                         ent->lcme_id = __swab32(ent->lcme_id);
181                         ent->lcme_flags = __swab32(ent->lcme_flags);
182                         ent->lcme_timestamp = __swab64(ent->lcme_timestamp);
183                         ent->lcme_extent.e_start = __swab64(ent->lcme_extent.e_start);
184                         ent->lcme_extent.e_end = __swab64(ent->lcme_extent.e_end);
185                         ent->lcme_offset = __swab32(ent->lcme_offset);
186                         ent->lcme_size = __swab32(ent->lcme_size);
187
188                         lum = (struct lov_user_md *)((char *)comp_v1 +
189                                         ent->lcme_offset);
190                         lum_size = ent->lcme_size;
191                 }
192
193                 lum->lmm_magic = __swab32(lum->lmm_magic);
194                 if (lum->lmm_magic == LOV_MAGIC_FOREIGN) {
195                         struct lov_hsm_md *lhm;
196
197                         lhm = (struct lov_hsm_md *)lum;
198                         lhm->lhm_length = __swab32(lhm->lhm_length);
199                         lhm->lhm_type = __swab32(lhm->lhm_type);
200                         lhm->lhm_flags = __swab32(lhm->lhm_flags);
201                         if (!lov_hsm_type_supported(lhm->lhm_type))
202                                 continue;
203
204                         lhm->lhm_archive_id = __swab64(lhm->lhm_archive_id);
205                         lhm->lhm_archive_ver = __swab64(lhm->lhm_archive_ver);
206                 } else {
207                         obj_count = llapi_layout_objects_in_lum(lum, lum_size);
208
209                         lum->lmm_pattern = __swab32(lum->lmm_pattern);
210                         lum->lmm_stripe_size = __swab32(lum->lmm_stripe_size);
211                         lum->lmm_stripe_count = __swab16(lum->lmm_stripe_count);
212                         lum->lmm_stripe_offset =
213                                 __swab16(lum->lmm_stripe_offset);
214
215                         if (lum->lmm_magic != LOV_MAGIC_V1) {
216                                 struct lov_user_md_v3 *v3;
217
218                                 v3 = (struct lov_user_md_v3 *)lum;
219                                 lod = v3->lmm_objects;
220                         } else {
221                                 lod = lum->lmm_objects;
222                         }
223
224                         for (j = 0; j < obj_count; j++)
225                                 lod[j].l_ost_idx = __swab32(lod[j].l_ost_idx);
226                 }
227         }
228 }
229
230 /**
231  * (Re-)allocate llc_objects[] to \a num_stripes stripes.
232  *
233  * Copy over existing llc_objects[], if any, to the new llc_objects[].
234  *
235  * \param[in] layout            existing layout to be modified
236  * \param[in] num_stripes       number of stripes in new layout
237  *
238  * \retval      0 if the objects are re-allocated successfully
239  * \retval      -1 on error with errno set
240  */
241 static int __llapi_comp_objects_realloc(struct llapi_layout_comp *comp,
242                                         unsigned int new_stripes)
243 {
244         struct lov_user_ost_data_v1 *new_objects;
245         unsigned int i;
246
247         if (new_stripes > LOV_MAX_STRIPE_COUNT) {
248                 errno = EINVAL;
249                 return -1;
250         }
251
252         if (new_stripes == comp->llc_objects_count)
253                 return 0;
254
255         if (new_stripes != 0 && new_stripes <= comp->llc_objects_count)
256                 return 0;
257
258         new_objects = realloc(comp->llc_objects,
259                               sizeof(*new_objects) * new_stripes);
260         if (new_objects == NULL && new_stripes != 0) {
261                 errno = ENOMEM;
262                 return -1;
263         }
264
265         for (i = comp->llc_objects_count; i < new_stripes; i++)
266                 new_objects[i].l_ost_idx = LLAPI_LAYOUT_IDX_MAX;
267
268         comp->llc_objects = new_objects;
269         comp->llc_objects_count = new_stripes;
270
271         return 0;
272 }
273
274 /**
275  * Allocate storage for a llapi_layout_comp with \a num_stripes stripes.
276  *
277  * \param[in] num_stripes       number of stripes in new layout
278  *
279  * \retval      valid pointer if allocation succeeds
280  * \retval      NULL if allocation fails
281  */
282 static struct llapi_layout_comp *__llapi_comp_alloc(unsigned int num_stripes)
283 {
284         struct llapi_layout_comp *comp;
285
286         if (num_stripes > LOV_MAX_STRIPE_COUNT) {
287                 errno = EINVAL;
288                 return NULL;
289         }
290
291         comp = calloc(1, sizeof(*comp));
292         if (comp == NULL) {
293                 errno = ENOMEM;
294                 return NULL;
295         }
296
297         comp->llc_objects = NULL;
298         comp->llc_objects_count = 0;
299
300         if (__llapi_comp_objects_realloc(comp, num_stripes) < 0) {
301                 free(comp);
302                 return NULL;
303         }
304
305         /* Set defaults. */
306         comp->llc_pattern = LLAPI_LAYOUT_DEFAULT;
307         comp->llc_stripe_size = LLAPI_LAYOUT_DEFAULT;
308         comp->llc_stripe_count = LLAPI_LAYOUT_DEFAULT;
309         comp->llc_stripe_offset = LLAPI_LAYOUT_DEFAULT;
310         comp->llc_pool_name[0] = '\0';
311         comp->llc_extent.e_start = 0;
312         comp->llc_extent.e_end = LUSTRE_EOF;
313         comp->llc_flags = 0;
314         comp->llc_id = 0;
315         INIT_LIST_HEAD(&comp->llc_list);
316
317         return comp;
318 }
319
320 /**
321  * Allocate storage for a HSM component with \a length buffer.
322  *
323  * \retval      valid pointer if allocation succeeds
324  * \retval      NULL if allocate fails
325  */
326 static struct llapi_layout_comp *__llapi_comp_hsm_alloc(uint32_t length)
327 {
328         struct llapi_layout_comp *comp;
329
330         if (lov_foreign_md_size(length) > XATTR_SIZE_MAX) {
331                 errno = EINVAL;
332                 return NULL;
333         }
334
335         comp = calloc(1, sizeof(*comp));
336         if (comp == NULL) {
337                 errno = ENOMEM;
338                 return NULL;
339         }
340
341         comp->llc_pattern = LLAPI_LAYOUT_FOREIGN;
342         comp->llc_length = length;
343         comp->llc_type = LU_FOREIGN_TYPE_UNKNOWN;
344         comp->llc_hsm_flags = 0;
345         comp->llc_archive_id = 0;
346         comp->llc_archive_ver = 0;
347         comp->llc_extent.e_start = 0;
348         comp->llc_extent.e_end = LUSTRE_EOF;
349         comp->llc_flags = 0;
350         comp->llc_id = 0;
351         INIT_LIST_HEAD(&comp->llc_list);
352
353         return comp;
354 }
355
356 /**
357  * Free memory allocated for \a comp
358  *
359  * \param[in] comp      previously allocated by __llapi_comp_alloc()
360  */
361 static void __llapi_comp_free(struct llapi_layout_comp *comp)
362 {
363         if (comp->llc_pattern != LLAPI_LAYOUT_FOREIGN &&
364             comp->llc_objects != NULL) {
365                 free(comp->llc_objects);
366         }
367         free(comp);
368 }
369
370 /**
371  * Free memory allocated for \a layout.
372  *
373  * \param[in] layout    previously allocated by llapi_layout_alloc()
374  */
375 void llapi_layout_free(struct llapi_layout *layout)
376 {
377         struct llapi_layout_comp *comp, *n;
378
379         if (layout == NULL)
380                 return;
381
382         list_for_each_entry_safe(comp, n, &layout->llot_comp_list, llc_list) {
383                 list_del_init(&comp->llc_list);
384                 __llapi_comp_free(comp);
385         }
386         free(layout);
387 }
388
389 /**
390  * Allocate and initialize a llapi_layout structure.
391  *
392  * \retval      valid llapi_layout pointer on success
393  * \retval      NULL if memory allocation fails
394  */
395 static struct llapi_layout *__llapi_layout_alloc(void)
396 {
397         struct llapi_layout *layout;
398
399         layout = calloc(1, sizeof(*layout));
400         if (layout == NULL) {
401                 errno = ENOMEM;
402                 return NULL;
403         }
404
405         /* Set defaults. */
406         layout->llot_magic = LLAPI_LAYOUT_MAGIC;
407         layout->llot_gen = 0;
408         layout->llot_flags = 0;
409         layout->llot_is_composite = false;
410         layout->llot_mirror_count = 1;
411         layout->llot_cur_comp = NULL;
412         INIT_LIST_HEAD(&layout->llot_comp_list);
413
414         return layout;
415 }
416
417 /**
418  * Allocate and initialize a new plain layout.
419  *
420  * \retval      valid llapi_layout pointer on success
421  * \retval      NULL if memory allocation fails
422  */
423 struct llapi_layout *llapi_layout_alloc(void)
424 {
425         struct llapi_layout_comp *comp;
426         struct llapi_layout *layout;
427
428         layout = __llapi_layout_alloc();
429         if (layout == NULL)
430                 return NULL;
431
432         comp = __llapi_comp_alloc(0);
433         if (comp == NULL) {
434                 free(layout);
435                 return NULL;
436         }
437
438         list_add_tail(&comp->llc_list, &layout->llot_comp_list);
439         layout->llot_cur_comp = comp;
440
441         return layout;
442 }
443
444 /**
445  * Check if the given \a lum_size is large enough to hold the required
446  * fields in \a lum.
447  *
448  * \param[in] lum       the struct lov_user_md to check
449  * \param[in] lum_size  the number of bytes in \a lum
450  *
451  * \retval true         the \a lum_size is too small
452  * \retval false        the \a lum_size is large enough
453  */
454 static bool llapi_layout_lum_truncated(struct lov_user_md *lum, size_t lum_size)
455 {
456         uint32_t magic;
457
458         if (lum_size < sizeof(lum->lmm_magic))
459                 return true;
460
461         if (lum->lmm_magic == LOV_MAGIC_V1 ||
462             lum->lmm_magic == __swab32(LOV_MAGIC_V1))
463                 magic = LOV_MAGIC_V1;
464         else if (lum->lmm_magic == LOV_MAGIC_V3 ||
465                  lum->lmm_magic == __swab32(LOV_MAGIC_V3))
466                 magic = LOV_MAGIC_V3;
467         else if (lum->lmm_magic == LOV_MAGIC_COMP_V1 ||
468                  lum->lmm_magic == __swab32(LOV_MAGIC_COMP_V1))
469                 magic = LOV_MAGIC_COMP_V1;
470         else
471                 return true;
472
473         if (magic == LOV_MAGIC_V1 || magic == LOV_MAGIC_V3)
474                 return lum_size < lov_user_md_size(0, magic);
475         else
476                 return lum_size < sizeof(struct lov_comp_md_v1);
477 }
478
479 /* Verify if the objects count in lum is consistent with the
480  * stripe count in lum. It applies to regular file only. */
481 static bool llapi_layout_lum_valid(struct lov_user_md *lum, int lum_size)
482 {
483         struct lov_comp_md_v1 *comp_v1 = NULL;
484         int i, ent_count, obj_count;
485
486         if (lum->lmm_magic == LOV_MAGIC_COMP_V1) {
487                 comp_v1 = (struct lov_comp_md_v1 *)lum;
488                 ent_count = comp_v1->lcm_entry_count;
489         } else if (lum->lmm_magic == LOV_MAGIC_V1 ||
490                    lum->lmm_magic == LOV_MAGIC_V3) {
491                 ent_count = 1;
492         } else {
493                 return false;
494         }
495
496         for (i = 0; i < ent_count; i++) {
497                 if (comp_v1) {
498                         lum = (struct lov_user_md *)((char *)comp_v1 +
499                                 comp_v1->lcm_entries[i].lcme_offset);
500                         lum_size = comp_v1->lcm_entries[i].lcme_size;
501
502                         if (lum->lmm_magic == LOV_MAGIC_FOREIGN)
503                                 continue;
504                 }
505                 obj_count = llapi_layout_objects_in_lum(lum, lum_size);
506
507                 if (comp_v1) {
508                         if (!(comp_v1->lcm_entries[i].lcme_flags &
509                                  LCME_FL_INIT) && obj_count != 0)
510                                 return false;
511                 } else if (obj_count != lum->lmm_stripe_count) {
512                         return false;
513                 }
514         }
515         return true;
516 }
517
518 /**
519  * Convert the data from a lov_user_md to a newly allocated llapi_layout.
520  * The caller is responsible for freeing the returned pointer.
521  *
522  * \param[in] lov_xattr         LOV user metadata xattr to copy data from
523  * \param[in] lov_xattr_size    size the lov_xattr_size passed in
524  * \param[in] flags             flags to control how layout is retrieved
525  *
526  * \retval              valid llapi_layout pointer on success
527  * \retval              NULL if memory allocation fails
528  */
529 struct llapi_layout *llapi_layout_get_by_xattr(void *lov_xattr,
530                                               ssize_t lov_xattr_size,
531                                               enum llapi_layout_get_flags flags)
532 {
533         struct lov_user_md *lum = lov_xattr;
534         struct lov_comp_md_v1 *comp_v1 = NULL;
535         struct lov_comp_md_entry_v1 *ent;
536         struct lov_user_md *v1;
537         struct llapi_layout *layout = NULL;
538         struct llapi_layout_comp *comp;
539         int i, ent_count = 0, obj_count = 0;
540
541         if (lov_xattr == NULL || lov_xattr_size <= 0) {
542                 errno = EINVAL;
543                 return NULL;
544         }
545
546         /* Return an error if we got back a partial layout. */
547         if (llapi_layout_lum_truncated(lov_xattr, lov_xattr_size)) {
548                 errno = ERANGE;
549                 return NULL;
550         }
551
552 #if __BYTE_ORDER == __BIG_ENDIAN
553         if (flags & LLAPI_LAYOUT_GET_COPY) {
554                 lum = malloc(lov_xattr_size);
555                 if (lum == NULL) {
556                         errno = ENOMEM;
557                         return NULL;
558                 }
559                 memcpy(lum, lov_xattr, lov_xattr_size);
560         }
561 #endif
562
563         llapi_layout_swab_lov_user_md(lum, lov_xattr_size);
564
565 #if LUSTRE_VERSION_CODE > OBD_OCD_VERSION(2, 16, 53, 0)
566 #define LLAPI_LXF_CHECK_OLD 0x0001
567         if (flags & LLAPI_LXF_CHECK_OLD)
568                 flags = (flags & ~LLAPI_LXF_CHECK_OLD) | LLAPI_LAYOUT_GET_CHECK;
569 #endif
570         if ((flags & LLAPI_LAYOUT_GET_CHECK) &&
571             !llapi_layout_lum_valid(lum, lov_xattr_size)) {
572                 errno = EBADSLT;
573                 goto out;
574         }
575
576         layout = __llapi_layout_alloc();
577         if (layout == NULL) {
578                 errno = ENOMEM;
579                 goto out;
580         }
581
582         if (lum->lmm_magic == LOV_MAGIC_COMP_V1) {
583                 comp_v1 = (struct lov_comp_md_v1 *)lum;
584                 ent_count = comp_v1->lcm_entry_count;
585                 layout->llot_gen = comp_v1->lcm_layout_gen;
586                 layout->llot_is_composite = true;
587                 layout->llot_mirror_count = comp_v1->lcm_mirror_count + 1;
588                 layout->llot_gen = comp_v1->lcm_layout_gen;
589                 layout->llot_flags = comp_v1->lcm_flags;
590         } else if (lum->lmm_magic == LOV_MAGIC_V1 ||
591                    lum->lmm_magic == LOV_MAGIC_V3) {
592                 ent_count = 1;
593                 layout->llot_is_composite = false;
594
595                 if (lov_xattr_size <= 0) {
596                         errno = EINVAL;
597                         goto out_layout;
598                 }
599         } else {
600                 errno = EOPNOTSUPP;
601                 goto out_layout;
602         }
603
604         if (ent_count == 0) {
605                 errno = EINVAL;
606                 goto out_layout;
607         }
608
609         v1 = (struct lov_user_md *)lum;
610         for (i = 0; i < ent_count; i++) {
611                 if (comp_v1 != NULL) {
612                         ent = &comp_v1->lcm_entries[i];
613                         v1 = (struct lov_user_md *)((char *)comp_v1 +
614                                 ent->lcme_offset);
615                         lov_xattr_size = ent->lcme_size;
616                 } else {
617                         ent = NULL;
618                 }
619
620                 if (v1->lmm_magic == LOV_MAGIC_FOREIGN) {
621                         struct lov_hsm_md *lhm;
622
623                         lhm = (struct lov_hsm_md *)v1;
624                         if (!lov_hsm_type_supported(lhm->lhm_type))
625                                 goto out_layout;
626
627                         if (lhm->lhm_length != sizeof(struct lov_hsm_base))
628                                 goto out_layout;
629
630                         comp = __llapi_comp_hsm_alloc(lhm->lhm_length);
631                         if (comp == NULL)
632                                 goto out_layout;
633
634                         comp->llc_length = lhm->lhm_length;
635                         comp->llc_type = lhm->lhm_type;
636                         comp->llc_hsm_flags = lhm->lhm_flags;
637                         comp->llc_archive_id = lhm->lhm_archive_id;
638                         comp->llc_archive_ver = lhm->lhm_archive_ver;
639                         memcpy(comp->llc_uuid, lhm->lhm_archive_uuid,
640                                sizeof(comp->llc_uuid));
641                 } else {
642                         obj_count = llapi_layout_objects_in_lum(v1,
643                                                                 lov_xattr_size);
644                         comp = __llapi_comp_alloc(obj_count);
645                         if (comp == NULL)
646                                 goto out_layout;
647                 }
648
649                 if (ent != NULL) {
650                         comp->llc_extent.e_start = ent->lcme_extent.e_start;
651                         comp->llc_extent.e_end = ent->lcme_extent.e_end;
652                         comp->llc_id = ent->lcme_id;
653                         comp->llc_flags = ent->lcme_flags;
654                         if (comp->llc_flags & LCME_FL_NOSYNC)
655                                 comp->llc_timestamp = ent->lcme_timestamp;
656                 } else {
657                         comp->llc_extent.e_start = 0;
658                         comp->llc_extent.e_end = LUSTRE_EOF;
659                         comp->llc_id = 0;
660                         comp->llc_flags = 0;
661                 }
662
663                 if (v1->lmm_magic == LOV_MAGIC_FOREIGN) {
664                         comp->llc_pattern = LLAPI_LAYOUT_FOREIGN;
665                         goto comp_add;
666                 }
667
668                 if (v1->lmm_pattern == LOV_PATTERN_RAID0)
669                         comp->llc_pattern = LLAPI_LAYOUT_RAID0;
670                 else if (v1->lmm_pattern == (LOV_PATTERN_RAID0 |
671                                          LOV_PATTERN_OVERSTRIPING))
672                         comp->llc_pattern = LLAPI_LAYOUT_OVERSTRIPING;
673                 else if (v1->lmm_pattern & LOV_PATTERN_MDT)
674                         comp->llc_pattern = LLAPI_LAYOUT_MDT;
675                 else
676                         /* Lustre only supports RAID0, overstripping,
677                          * DoM and FOREIGN/HSM for now.
678                          */
679                         comp->llc_pattern = v1->lmm_pattern;
680
681                 if (v1->lmm_stripe_size == 0)
682                         comp->llc_stripe_size = LLAPI_LAYOUT_DEFAULT;
683                 else
684                         comp->llc_stripe_size = v1->lmm_stripe_size;
685
686                 if (v1->lmm_stripe_count == (typeof(v1->lmm_stripe_count))-1)
687                         comp->llc_stripe_count = LLAPI_LAYOUT_WIDE;
688                 else if (v1->lmm_stripe_count == 0)
689                         comp->llc_stripe_count = LLAPI_LAYOUT_DEFAULT;
690                 else
691                         comp->llc_stripe_count = v1->lmm_stripe_count;
692
693                 if (v1->lmm_stripe_offset ==
694                     (typeof(v1->lmm_stripe_offset))-1)
695                         comp->llc_stripe_offset = LLAPI_LAYOUT_DEFAULT;
696                 else
697                         comp->llc_stripe_offset = v1->lmm_stripe_offset;
698
699                 if (v1->lmm_magic != LOV_USER_MAGIC_V1) {
700                         const struct lov_user_md_v3 *lumv3;
701                         size_t size = sizeof(comp->llc_pool_name);
702                         int rc;
703
704                         lumv3 = (struct lov_user_md_v3 *)v1;
705                         rc = snprintf(comp->llc_pool_name, size,
706                                       "%s", lumv3->lmm_pool_name);
707                         /* Avoid GCC 7 format-truncation warning. */
708                         if (rc > size)
709                                 comp->llc_pool_name[size - 1] = 0;
710
711                         memcpy(comp->llc_objects, lumv3->lmm_objects,
712                                obj_count * sizeof(lumv3->lmm_objects[0]));
713                 } else {
714                         const struct lov_user_md_v1 *lumv1;
715                         lumv1 = (struct lov_user_md_v1 *)v1;
716                         memcpy(comp->llc_objects, lumv1->lmm_objects,
717                                obj_count * sizeof(lumv1->lmm_objects[0]));
718                 }
719
720                 if (obj_count != 0)
721                         comp->llc_stripe_offset =
722                                 comp->llc_objects[0].l_ost_idx;
723 comp_add:
724                 comp->llc_ondisk = true;
725                 list_add_tail(&comp->llc_list, &layout->llot_comp_list);
726                 layout->llot_cur_comp = comp;
727         }
728
729 out:
730         if (lum != lov_xattr)
731                 free(lum);
732         return layout;
733 out_layout:
734         llapi_layout_free(layout);
735         layout = NULL;
736         goto out;
737 }
738
739 __u32 llapi_pattern_to_lov(uint64_t pattern)
740 {
741         __u32 lov_pattern;
742
743         switch (pattern) {
744         case LLAPI_LAYOUT_DEFAULT:
745                 lov_pattern = LOV_PATTERN_RAID0;
746                 break;
747         case LLAPI_LAYOUT_RAID0:
748                 lov_pattern = LOV_PATTERN_RAID0;
749                 break;
750         case LLAPI_LAYOUT_MDT:
751                 lov_pattern = LOV_PATTERN_MDT;
752                 break;
753         case LLAPI_LAYOUT_FOREIGN:
754                 lov_pattern = LOV_PATTERN_FOREIGN;
755                 break;
756         case LLAPI_LAYOUT_OVERSTRIPING:
757                 lov_pattern = LOV_PATTERN_OVERSTRIPING | LOV_PATTERN_RAID0;
758                 break;
759         default:
760                 lov_pattern = EINVAL;
761         }
762
763         return lov_pattern;
764 }
765
766 /**
767  * Convert the data from a llapi_layout to a newly allocated lov_user_md.
768  * The caller is responsible for freeing the returned pointer.
769  *
770  * \param[in] layout    the layout to copy from
771  *
772  * \retval      valid lov_user_md pointer on success
773  * \retval      NULL if memory allocation fails or the layout is invalid
774  */
775 static struct lov_user_md *
776 llapi_layout_to_lum(const struct llapi_layout *layout)
777 {
778         struct llapi_layout_comp *comp;
779         struct lov_comp_md_v1 *comp_v1 = NULL;
780         struct lov_comp_md_entry_v1 *ent;
781         struct lov_user_md *lum = NULL;
782         size_t lum_size = 0;
783         int ent_idx = 0;
784         uint32_t offset = 0;
785
786         if (layout == NULL ||
787             list_empty((struct list_head *)&layout->llot_comp_list)) {
788                 errno = EINVAL;
789                 return NULL;
790         }
791
792         /* Allocate header of lov_comp_md_v1 if necessary */
793         if (layout->llot_is_composite) {
794                 int comp_cnt = 0;
795
796                 list_for_each_entry(comp, &layout->llot_comp_list, llc_list)
797                         comp_cnt++;
798
799                 lum_size = sizeof(*comp_v1) + comp_cnt * sizeof(*ent);
800                 lum = calloc(lum_size, 1);
801                 if (lum == NULL) {
802                         errno = ENOMEM;
803                         return NULL;
804                 }
805                 comp_v1 = (struct lov_comp_md_v1 *)lum;
806                 comp_v1->lcm_magic = LOV_USER_MAGIC_COMP_V1;
807                 comp_v1->lcm_size = lum_size;
808                 comp_v1->lcm_layout_gen = 0;
809                 comp_v1->lcm_flags = layout->llot_flags;
810                 comp_v1->lcm_entry_count = comp_cnt;
811                 comp_v1->lcm_mirror_count = layout->llot_mirror_count - 1;
812                 offset += lum_size;
813         }
814
815         list_for_each_entry(comp, &layout->llot_comp_list, llc_list) {
816                 struct lov_user_md *blob;
817                 size_t blob_size;
818                 uint32_t magic;
819                 int i, obj_count = 0;
820                 struct lov_user_ost_data *lmm_objects;
821                 uint64_t pattern = comp->llc_pattern;
822
823                 if ((pattern & LLAPI_LAYOUT_SPECIFIC) != 0) {
824                         if (comp->llc_objects_count <
825                             comp->llc_stripe_count) {
826                                 errno = EINVAL;
827                                 goto error;
828                         }
829                         magic = LOV_USER_MAGIC_SPECIFIC;
830                         obj_count = comp->llc_stripe_count;
831                         pattern &= ~LLAPI_LAYOUT_SPECIFIC;
832                 } else if (strlen(comp->llc_pool_name) != 0) {
833                         magic = LOV_USER_MAGIC_V3;
834                 } else {
835                         magic = LOV_USER_MAGIC_V1;
836                 }
837                 /* All stripes must be specified when the pattern contains
838                  * LLAPI_LAYOUT_SPECIFIC */
839                 for (i = 0; i < obj_count; i++) {
840                         if (comp->llc_objects[i].l_ost_idx ==
841                             LLAPI_LAYOUT_IDX_MAX) {
842                                 errno = EINVAL;
843                                 goto error;
844                         }
845                 }
846
847                 blob_size = lov_user_md_size(obj_count, magic);
848                 blob = realloc(lum, lum_size + blob_size);
849                 if (blob == NULL) {
850                         errno = ENOMEM;
851                         goto error;
852                 } else {
853                         lum = blob;
854                         comp_v1 = (struct lov_comp_md_v1 *)lum;
855                         blob = (struct lov_user_md *)((char *)lum + lum_size);
856                         lum_size += blob_size;
857                 }
858
859                 blob->lmm_magic = magic;
860                 blob->lmm_pattern = llapi_pattern_to_lov(pattern);
861                 if (blob->lmm_pattern == EINVAL) {
862                         errno = EINVAL;
863                         goto error;
864                 }
865
866                 if (comp->llc_stripe_size == LLAPI_LAYOUT_DEFAULT)
867                         blob->lmm_stripe_size = 0;
868                 else
869                         blob->lmm_stripe_size = comp->llc_stripe_size;
870
871                 if (comp->llc_stripe_count == LLAPI_LAYOUT_DEFAULT)
872                         blob->lmm_stripe_count = 0;
873                 else if (comp->llc_stripe_count == LLAPI_LAYOUT_WIDE)
874                         blob->lmm_stripe_count = LOV_ALL_STRIPES;
875                 else
876                         blob->lmm_stripe_count = comp->llc_stripe_count;
877
878                 if (comp->llc_stripe_offset == LLAPI_LAYOUT_DEFAULT)
879                         blob->lmm_stripe_offset = -1;
880                 else
881                         blob->lmm_stripe_offset = comp->llc_stripe_offset;
882
883                 if (magic == LOV_USER_MAGIC_V3 ||
884                     magic == LOV_USER_MAGIC_SPECIFIC) {
885                         struct lov_user_md_v3 *lumv3 =
886                                 (struct lov_user_md_v3 *)blob;
887
888                         if (comp->llc_pool_name[0] != '\0') {
889                                 strncpy(lumv3->lmm_pool_name,
890                                         comp->llc_pool_name,
891                                         sizeof(lumv3->lmm_pool_name));
892                         } else {
893                                 memset(lumv3->lmm_pool_name, 0,
894                                        sizeof(lumv3->lmm_pool_name));
895                         }
896                         lmm_objects = lumv3->lmm_objects;
897                 } else {
898                         lmm_objects = blob->lmm_objects;
899                 }
900
901                 for (i = 0; i < obj_count; i++)
902                         lmm_objects[i].l_ost_idx =
903                                 comp->llc_objects[i].l_ost_idx;
904
905                 if (layout->llot_is_composite) {
906                         ent = &comp_v1->lcm_entries[ent_idx];
907                         ent->lcme_id = comp->llc_id;
908                         ent->lcme_flags = comp->llc_flags;
909                         if (ent->lcme_flags & LCME_FL_NOSYNC)
910                                 ent->lcme_timestamp = comp->llc_timestamp;
911                         ent->lcme_extent.e_start = comp->llc_extent.e_start;
912                         ent->lcme_extent.e_end = comp->llc_extent.e_end;
913                         ent->lcme_size = blob_size;
914                         ent->lcme_offset = offset;
915                         offset += blob_size;
916                         comp_v1->lcm_size += blob_size;
917                         ent_idx++;
918                 } else {
919                         break;
920                 }
921         }
922
923         return lum;
924 error:
925         free(lum);
926         return NULL;
927 }
928
929 /**
930  * Get the parent directory of a path.
931  *
932  * \param[in] path      path to get parent of
933  * \param[out] buf      buffer in which to store parent path
934  * \param[in] size      size in bytes of buffer \a buf
935  */
936 static void get_parent_dir(const char *path, char *buf, size_t size)
937 {
938         char *p;
939
940         strncpy(buf, path, size - 1);
941         p = strrchr(buf, '/');
942
943         if (p != NULL) {
944                 *p = '\0';
945         } else if (size >= 2) {
946                 strncpy(buf, ".", 2);
947                 buf[size - 1] = '\0';
948         }
949 }
950
951 /**
952  * Substitute unspecified attribute values in \a layout with values
953  * from fs global settings. (lov.stripesize, lov.stripecount,
954  * lov.stripeoffset)
955  *
956  * \param[in] layout    layout to inherit values from
957  * \param[in] path      file path of the filesystem
958  */
959 static void inherit_sys_attributes(struct llapi_layout *layout,
960                                    const char *path)
961 {
962         struct llapi_layout_comp *comp;
963         unsigned int ssize, scount, soffset;
964         int rc;
965
966         rc = sattr_cache_get_defaults(NULL, path, &scount, &ssize, &soffset);
967         if (rc)
968                 return;
969
970         list_for_each_entry(comp, &layout->llot_comp_list, llc_list) {
971                 if (comp->llc_pattern == LLAPI_LAYOUT_DEFAULT)
972                         comp->llc_pattern = LLAPI_LAYOUT_RAID0;
973                 if (comp->llc_stripe_size == LLAPI_LAYOUT_DEFAULT)
974                         comp->llc_stripe_size = ssize;
975                 if (comp->llc_stripe_count == LLAPI_LAYOUT_DEFAULT)
976                         comp->llc_stripe_count = scount;
977                 if (comp->llc_stripe_offset == LLAPI_LAYOUT_DEFAULT)
978                         comp->llc_stripe_offset = soffset;
979         }
980 }
981
982 /**
983  * Get the current component of \a layout.
984  *
985  * \param[in] layout    layout to get current component
986  *
987  * \retval      valid llapi_layout_comp pointer on success
988  * \retval      NULL on error
989  */
990 static struct llapi_layout_comp *
991 __llapi_layout_cur_comp(const struct llapi_layout *layout)
992 {
993         struct llapi_layout_comp *comp;
994
995         if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
996                 errno = EINVAL;
997                 return NULL;
998         }
999         if (layout->llot_cur_comp == NULL) {
1000                 errno = EINVAL;
1001                 return NULL;
1002         }
1003         /* Verify data consistency */
1004         list_for_each_entry(comp, &layout->llot_comp_list, llc_list)
1005                 if (comp == layout->llot_cur_comp)
1006                         return comp;
1007         errno = EFAULT;
1008         return NULL;
1009 }
1010
1011 /**
1012  * Test if any attributes of \a layout are specified.
1013  *
1014  * \param[in] layout    the layout to check
1015  *
1016  * \retval true         any attributes are specified
1017  * \retval false        all attributes are unspecified
1018  */
1019 static bool is_any_specified(const struct llapi_layout *layout)
1020 {
1021         struct llapi_layout_comp *comp;
1022
1023         comp = __llapi_layout_cur_comp(layout);
1024         if (comp == NULL)
1025                 return false;
1026
1027         if (layout->llot_is_composite || layout->llot_mirror_count != 1)
1028                 return true;
1029
1030         return comp->llc_pattern != LLAPI_LAYOUT_DEFAULT ||
1031                comp->llc_stripe_size != LLAPI_LAYOUT_DEFAULT ||
1032                comp->llc_stripe_count != LLAPI_LAYOUT_DEFAULT ||
1033                comp->llc_stripe_offset != LLAPI_LAYOUT_DEFAULT ||
1034                strlen(comp->llc_pool_name);
1035 }
1036
1037 /**
1038  * Get the striping layout for the file referenced by file descriptor \a fd.
1039  *
1040  * If the filesystem does not support the "lustre." xattr namespace, the
1041  * file must be on a non-Lustre filesystem, so set errno to ENOTTY per
1042  * convention.  If the file has no "lustre.lov" data, the file will
1043  * inherit default values, so return a default layout.
1044  *
1045  * If the kernel gives us back less than the expected amount of data,
1046  * we fail with errno set to EINTR.
1047  *
1048  * \param[in] fd        open file descriptor
1049  * \param[in] flags     open file descriptor
1050  *
1051  * \retval      valid llapi_layout pointer on success
1052  * \retval      NULL if an error occurs
1053  */
1054 struct llapi_layout *llapi_layout_get_by_fd(int fd,
1055                                             enum llapi_layout_get_flags flags)
1056 {
1057         size_t lum_len;
1058         struct lov_user_md *lum;
1059         struct llapi_layout *layout = NULL;
1060         ssize_t bytes_read;
1061         struct stat st;
1062
1063         lum_len = XATTR_SIZE_MAX;
1064         lum = malloc(lum_len);
1065         if (lum == NULL)
1066                 return NULL;
1067
1068         bytes_read = fgetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_len);
1069         if (bytes_read < 0) {
1070                 if (errno == EOPNOTSUPP)
1071                         errno = ENOTTY;
1072                 else if (errno == ENODATA)
1073                         layout = llapi_layout_alloc();
1074                 goto out;
1075         }
1076
1077         /* Directories may have a positive non-zero lum->lmm_stripe_count
1078          * yet have an empty lum->lmm_objects array. For non-directories the
1079          * amount of data returned from the kernel must be consistent
1080          * with the stripe count. */
1081         if (fstat(fd, &st) < 0)
1082                 goto out;
1083
1084         layout = llapi_layout_get_by_xattr(lum, bytes_read,
1085                         S_ISDIR(st.st_mode) ? 0 : LLAPI_LAYOUT_GET_CHECK);
1086 out:
1087         free(lum);
1088         return layout;
1089 }
1090
1091 /**
1092  * Get the expected striping layout for a file at \a path.
1093  *
1094  * Substitute expected inherited attribute values for unspecified
1095  * attributes.  Unspecified attributes may belong to directories and
1096  * never-written-to files, and indicate that default values will be
1097  * assigned when files are created or first written to.  A default value
1098  * is inherited from the parent directory if the attribute is specified
1099  * there, otherwise it is inherited from the filesystem root.
1100  * Unspecified attributes normally have the value LLAPI_LAYOUT_DEFAULT.
1101  *
1102  * The complete \a path need not refer to an existing file or directory,
1103  * but some leading portion of it must reside within a lustre filesystem.
1104  * A use case for this interface would be to obtain the literal striping
1105  * values that would be assigned to a new file in a given directory.
1106  *
1107  * \param[in] path      path for which to get the expected layout
1108  *
1109  * \retval      valid llapi_layout pointer on success
1110  * \retval      NULL if an error occurs
1111  */
1112 static struct llapi_layout *llapi_layout_expected(const char *path)
1113 {
1114         struct llapi_layout     *path_layout = NULL;
1115         char                    donor_path[PATH_MAX];
1116         struct stat st;
1117         int fd;
1118         int rc;
1119
1120         fd = open(path, O_RDONLY);
1121         if (fd < 0 && errno != ENOENT)
1122                 return NULL;
1123
1124         if (fd >= 0) {
1125                 int tmp;
1126
1127                 path_layout = llapi_layout_get_by_fd(fd, 0);
1128                 tmp = errno;
1129                 close(fd);
1130                 errno = tmp;
1131         }
1132
1133         if (path_layout == NULL) {
1134                 if (errno != ENODATA && errno != ENOENT)
1135                         return NULL;
1136
1137                 path_layout = llapi_layout_alloc();
1138                 if (path_layout == NULL)
1139                         return NULL;
1140         }
1141
1142         if (is_any_specified(path_layout)) {
1143                 inherit_sys_attributes(path_layout, path);
1144                 return path_layout;
1145         }
1146
1147         llapi_layout_free(path_layout);
1148
1149         rc = stat(path, &st);
1150         if (rc < 0 && errno != ENOENT)
1151                 return NULL;
1152
1153         /* If path is a not a directory or doesn't exist, inherit layout
1154          * from parent directory. */
1155         if ((rc == 0 && !S_ISDIR(st.st_mode)) ||
1156             (rc < 0 && errno == ENOENT)) {
1157                 get_parent_dir(path, donor_path, sizeof(donor_path));
1158                 path_layout = llapi_layout_get_by_path(donor_path, 0);
1159                 if (path_layout != NULL) {
1160                         if (is_any_specified(path_layout)) {
1161                                 inherit_sys_attributes(path_layout, donor_path);
1162                                 return path_layout;
1163                         }
1164                         llapi_layout_free(path_layout);
1165                 }
1166         }
1167
1168         /* Inherit layout from the filesystem root. */
1169         rc = llapi_search_mounts(path, 0, donor_path, NULL);
1170         if (rc < 0)
1171                 return NULL;
1172         path_layout = llapi_layout_get_by_path(donor_path, 0);
1173         if (path_layout == NULL)
1174                 return NULL;
1175
1176         inherit_sys_attributes(path_layout, donor_path);
1177         return path_layout;
1178 }
1179
1180 /**
1181  * Get the striping layout for the file at \a path.
1182  *
1183  * If \a flags contains LLAPI_LAYOUT_GET_EXPECTED, substitute
1184  * expected inherited attribute values for unspecified attributes. See
1185  * llapi_layout_expected().
1186  *
1187  * \param[in] path      path for which to get the layout
1188  * \param[in] flags     flags to control how layout is retrieved
1189  *
1190  * \retval      valid llapi_layout pointer on success
1191  * \retval      NULL if an error occurs
1192  */
1193 struct llapi_layout *llapi_layout_get_by_path(const char *path,
1194                                               enum llapi_layout_get_flags flags)
1195 {
1196         struct llapi_layout *layout = NULL;
1197         bool failed = false;
1198         int open_flags;
1199         int fd;
1200         int tmp;
1201
1202         if (flags & LLAPI_LAYOUT_GET_EXPECTED)
1203                 return llapi_layout_expected(path);
1204
1205         /* Always get layout in O_DIRECT */
1206         /* Allow fetching layout even without the key on encrypted files */
1207         open_flags = O_RDONLY | O_DIRECT | O_CIPHERTEXT;
1208 do_open:
1209         fd = open(path, open_flags);
1210         if (fd < 0) {
1211                 if (errno != EINVAL || failed)
1212                         return layout;
1213                 /* EINVAL is because a directory cannot be opened in O_DIRECT */
1214                 open_flags = O_RDONLY | O_CIPHERTEXT;
1215                 failed = true;
1216                 goto do_open;
1217         }
1218
1219         layout = llapi_layout_get_by_fd(fd, flags);
1220         tmp = errno;
1221         close(fd);
1222         errno = tmp;
1223
1224         return layout;
1225 }
1226
1227 /**
1228  * Get the layout for the file with FID \a fidstr in filesystem \a lustre_dir.
1229  *
1230  * \param[in] lustre_dir        path within Lustre filesystem containing \a fid
1231  * \param[in] fid               Lustre identifier of file to get layout for
1232  *
1233  * \retval      valid llapi_layout pointer on success
1234  * \retval      NULL if an error occurs
1235  */
1236 struct llapi_layout *llapi_layout_get_by_fid(const char *lustre_dir,
1237                                              const struct lu_fid *fid,
1238                                              enum llapi_layout_get_flags flags)
1239 {
1240         int fd;
1241         int tmp;
1242         int saved_msg_level = llapi_msg_get_level();
1243         struct llapi_layout *layout = NULL;
1244
1245         /* Prevent llapi internal routines from writing to console
1246          * while executing this function, then restore previous message
1247          * level. */
1248         llapi_msg_set_level(LLAPI_MSG_OFF);
1249         fd = llapi_open_by_fid(lustre_dir, fid, O_RDONLY);
1250         llapi_msg_set_level(saved_msg_level);
1251
1252         if (fd < 0)
1253                 return NULL;
1254
1255         layout = llapi_layout_get_by_fd(fd, flags);
1256         tmp = errno;
1257         close(fd);
1258         errno = tmp;
1259
1260         return layout;
1261 }
1262
1263 /**
1264  * Get the stripe count of \a layout.
1265  *
1266  * \param[in] layout    layout to get stripe count from
1267  * \param[out] count    integer to store stripe count in
1268  *
1269  * \retval      0 on success
1270  * \retval      -1 if arguments are invalid
1271  */
1272 int llapi_layout_stripe_count_get(const struct llapi_layout *layout,
1273                                   uint64_t *count)
1274 {
1275         struct llapi_layout_comp *comp;
1276
1277         comp = __llapi_layout_cur_comp(layout);
1278         if (comp == NULL)
1279                 return -1;
1280
1281         if (count == NULL) {
1282                 errno = EINVAL;
1283                 return -1;
1284         }
1285
1286         if (comp->llc_pattern == LLAPI_LAYOUT_FOREIGN)
1287                 *count = 0;
1288         else
1289                 *count = comp->llc_stripe_count;
1290
1291         return 0;
1292 }
1293
1294 /*
1295  * The llapi_layout API functions have these extra validity checks since
1296  * they use intuitively named macros to denote special behavior, whereas
1297  * the old API uses 0 and -1.
1298  */
1299
1300 bool llapi_layout_stripe_count_is_valid(int64_t stripe_count)
1301 {
1302         return stripe_count == LLAPI_LAYOUT_DEFAULT ||
1303                 stripe_count == LLAPI_LAYOUT_WIDE ||
1304                 (stripe_count != 0 && stripe_count != -1 &&
1305                  llapi_stripe_count_is_valid(stripe_count));
1306 }
1307
1308 static bool llapi_layout_extension_size_is_valid(uint64_t ext_size)
1309 {
1310         return (ext_size != 0 &&
1311                 llapi_stripe_size_is_aligned(ext_size) &&
1312                 !llapi_stripe_size_is_too_big(ext_size));
1313 }
1314
1315 static bool llapi_layout_stripe_size_is_valid(uint64_t stripe_size)
1316 {
1317         return stripe_size == LLAPI_LAYOUT_DEFAULT ||
1318                 (stripe_size != 0 &&
1319                  llapi_stripe_size_is_aligned(stripe_size) &&
1320                  !llapi_stripe_size_is_too_big(stripe_size));
1321 }
1322
1323 static bool llapi_layout_stripe_index_is_valid(int64_t stripe_index)
1324 {
1325         return stripe_index == LLAPI_LAYOUT_DEFAULT ||
1326                 (stripe_index >= 0 &&
1327                 llapi_stripe_index_is_valid(stripe_index));
1328 }
1329
1330 /**
1331  * Set the stripe count of \a layout.
1332  *
1333  * \param[in] layout    layout to set stripe count in
1334  * \param[in] count     value to be set
1335  *
1336  * \retval      0 on success
1337  * \retval      -1 if arguments are invalid
1338  */
1339 int llapi_layout_stripe_count_set(struct llapi_layout *layout,
1340                                   uint64_t count)
1341 {
1342         struct llapi_layout_comp *comp;
1343
1344         comp = __llapi_layout_cur_comp(layout);
1345         if (comp == NULL)
1346                 return -1;
1347
1348         if (!llapi_layout_stripe_count_is_valid(count)) {
1349                 errno = EINVAL;
1350                 return -1;
1351         }
1352
1353         comp->llc_stripe_count = count;
1354
1355         return 0;
1356 }
1357
1358 /**
1359  * Get the stripe/extension size of \a layout.
1360  *
1361  * \param[in] layout    layout to get stripe size from
1362  * \param[out] size     integer to store stripe size in
1363  * \param[in] extension flag if extenion size is requested
1364  *
1365  * \retval      0 on success
1366  * \retval      -1 if arguments are invalid
1367  */
1368 static int layout_stripe_size_get(const struct llapi_layout *layout,
1369                                   uint64_t *size, bool extension)
1370 {
1371         struct llapi_layout_comp *comp;
1372         int comp_ext;
1373
1374         comp = __llapi_layout_cur_comp(layout);
1375         if (comp == NULL)
1376                 return -1;
1377
1378         if (size == NULL) {
1379                 errno = EINVAL;
1380                 return -1;
1381         }
1382
1383         /* FIXME: return a component rather than FOREIGN/HSM component. */
1384         if (comp->llc_pattern == LLAPI_LAYOUT_FOREIGN) {
1385                 errno = EINVAL;
1386                 return -1;
1387         }
1388
1389         comp_ext = comp->llc_flags & LCME_FL_EXTENSION;
1390         if ((comp_ext && !extension) || (!comp_ext && extension)) {
1391                 errno = EINVAL;
1392                 return -1;
1393         }
1394
1395         *size = comp->llc_stripe_size;
1396         if (comp->llc_flags & LCME_FL_EXTENSION)
1397                 *size *= SEL_UNIT_SIZE;
1398
1399         return 0;
1400 }
1401
1402 int llapi_layout_stripe_size_get(const struct llapi_layout *layout,
1403                                  uint64_t *size)
1404 {
1405         return layout_stripe_size_get(layout, size, false);
1406 }
1407
1408 int llapi_layout_extension_size_get(const struct llapi_layout *layout,
1409                                     uint64_t *size)
1410 {
1411         return layout_stripe_size_get(layout, size, true);
1412 }
1413
1414 /**
1415  * Set the stripe/extension size of \a layout.
1416  *
1417  * \param[in] layout    layout to set stripe size in
1418  * \param[in] size      value to be set
1419  * \param[in] extension flag if extenion size is passed
1420  *
1421  * \retval      0 on success
1422  * \retval      -1 if arguments are invalid
1423  */
1424 static int layout_stripe_size_set(struct llapi_layout *layout,
1425                                   uint64_t size, bool extension)
1426 {
1427         struct llapi_layout_comp *comp;
1428         int comp_ext;
1429
1430         comp = __llapi_layout_cur_comp(layout);
1431         if (comp == NULL)
1432                 return -1;
1433
1434         if (comp->llc_pattern == LLAPI_LAYOUT_FOREIGN) {
1435                 errno = EINVAL;
1436                 return -1;
1437         }
1438
1439         comp_ext = comp->llc_flags & LCME_FL_EXTENSION;
1440         if ((comp_ext && !extension) || (!comp_ext && extension)) {
1441                 errno = EINVAL;
1442                 return -1;
1443         }
1444
1445         if (comp_ext)
1446                 size /= SEL_UNIT_SIZE;
1447
1448         if ((comp_ext && !llapi_layout_extension_size_is_valid(size)) ||
1449             (!comp_ext && !llapi_layout_stripe_size_is_valid(size))) {
1450                 errno = EINVAL;
1451                 return -1;
1452         }
1453
1454         comp->llc_stripe_size = size;
1455         return 0;
1456 }
1457
1458 int llapi_layout_stripe_size_set(struct llapi_layout *layout,
1459                                  uint64_t size)
1460 {
1461         return layout_stripe_size_set(layout, size, false);
1462 }
1463
1464 int llapi_layout_extension_size_set(struct llapi_layout *layout,
1465                                     uint64_t size)
1466 {
1467         return layout_stripe_size_set(layout, size, true);
1468 }
1469
1470 /**
1471  * Get the RAID pattern of \a layout.
1472  *
1473  * \param[in] layout    layout to get pattern from
1474  * \param[out] pattern  integer to store pattern in
1475  *
1476  * \retval      0 on success
1477  * \retval      -1 if arguments are invalid
1478  */
1479 int llapi_layout_pattern_get(const struct llapi_layout *layout,
1480                              uint64_t *pattern)
1481 {
1482         struct llapi_layout_comp *comp;
1483
1484         comp = __llapi_layout_cur_comp(layout);
1485         if (comp == NULL)
1486                 return -1;
1487
1488         if (pattern == NULL) {
1489                 errno = EINVAL;
1490                 return -1;
1491         }
1492
1493         *pattern = comp->llc_pattern;
1494
1495         return 0;
1496 }
1497
1498 /**
1499  * Set the pattern of \a layout.
1500  *
1501  * \param[in] layout    layout to set pattern in
1502  * \param[in] pattern   value to be set
1503  *
1504  * \retval      0 on success
1505  * \retval      -1 if arguments are invalid or RAID pattern
1506  *              is unsupported
1507  */
1508 int llapi_layout_pattern_set(struct llapi_layout *layout, uint64_t pattern)
1509 {
1510         struct llapi_layout_comp *comp;
1511
1512         comp = __llapi_layout_cur_comp(layout);
1513         if (comp == NULL)
1514                 return -1;
1515
1516         if (pattern != LLAPI_LAYOUT_DEFAULT &&
1517             pattern != LLAPI_LAYOUT_RAID0 && pattern != LLAPI_LAYOUT_MDT
1518             && pattern != LLAPI_LAYOUT_OVERSTRIPING &&
1519             pattern != LLAPI_LAYOUT_FOREIGN) {
1520                 errno = EOPNOTSUPP;
1521                 return -1;
1522         }
1523
1524         comp->llc_pattern = pattern |
1525                             (comp->llc_pattern & LLAPI_LAYOUT_SPECIFIC);
1526
1527         return 0;
1528 }
1529
1530 static inline int stripe_number_roundup(int stripe_number)
1531 {
1532         unsigned int round_up = (stripe_number + 8) & ~7;
1533         return round_up > LOV_MAX_STRIPE_COUNT ?
1534                 LOV_MAX_STRIPE_COUNT : round_up;
1535 }
1536
1537 /**
1538  * Set the OST index of stripe number \a stripe_number to \a ost_index.
1539  *
1540  * If only the starting stripe's OST index is specified, then this can use
1541  * the normal LOV_MAGIC_{V1,V3} layout type.  If multiple OST indices are
1542  * given, then allocate an array to hold the list of indices and ensure that
1543  * the LOV_USER_MAGIC_SPECIFIC layout is used when creating the file.
1544  *
1545  * \param[in] layout            layout to set OST index in
1546  * \param[in] stripe_number     stripe number to set index for
1547  * \param[in] ost_index         the index to set
1548  *
1549  * \retval      0 on success
1550  * \retval      -1 if arguments are invalid or an unsupported stripe number
1551  *              was specified, error returned in errno
1552  */
1553 int llapi_layout_ost_index_set(struct llapi_layout *layout, int stripe_number,
1554                                uint64_t ost_index)
1555 {
1556         struct llapi_layout_comp *comp;
1557
1558         comp = __llapi_layout_cur_comp(layout);
1559         if (comp == NULL)
1560                 return -1;
1561
1562         if (comp->llc_pattern == LLAPI_LAYOUT_FOREIGN) {
1563                 errno = EINVAL;
1564                 return -1;
1565         }
1566
1567         if (!llapi_layout_stripe_index_is_valid(ost_index)) {
1568                 errno = EINVAL;
1569                 return -1;
1570         }
1571
1572         if (stripe_number == 0 && ost_index == LLAPI_LAYOUT_DEFAULT) {
1573                 comp->llc_stripe_offset = ost_index;
1574                 comp->llc_pattern &= ~LLAPI_LAYOUT_SPECIFIC;
1575                 __llapi_comp_objects_realloc(comp, 0);
1576         } else if (stripe_number >= 0 &&
1577                    stripe_number < LOV_MAX_STRIPE_COUNT) {
1578                 if (ost_index >= LLAPI_LAYOUT_IDX_MAX) {
1579                         errno = EINVAL;
1580                         return -1;
1581                 }
1582
1583                 /* Preallocate a few more stripes to avoid realloc() overhead.*/
1584                 if (__llapi_comp_objects_realloc(comp,
1585                                 stripe_number_roundup(stripe_number)) < 0)
1586                         return -1;
1587
1588                 comp->llc_objects[stripe_number].l_ost_idx = ost_index;
1589
1590                 if (stripe_number == 0)
1591                         comp->llc_stripe_offset = ost_index;
1592                 else
1593                         comp->llc_pattern |= LLAPI_LAYOUT_SPECIFIC;
1594
1595                 if (comp->llc_stripe_count == LLAPI_LAYOUT_DEFAULT ||
1596                     comp->llc_stripe_count <= stripe_number)
1597                         comp->llc_stripe_count = stripe_number + 1;
1598         } else {
1599                 errno = EINVAL;
1600                 return -1;
1601         }
1602
1603         return 0;
1604 }
1605
1606 static int reset_index_cb(struct llapi_layout *layout, void *cbdata)
1607 {
1608         int *save_errno = (int *)cbdata;
1609         int rc;
1610
1611         rc = llapi_layout_ost_index_set(layout, 0, LLAPI_LAYOUT_DEFAULT);
1612
1613         /* save the first error returned, but try to reset all components */
1614         if (rc && !*save_errno)
1615                 *save_errno = errno;
1616
1617         return LLAPI_LAYOUT_ITER_CONT;
1618 }
1619
1620 /**
1621  * Reset the OST index on all components in \a layout to LLAPI_LAYOUT_DEFAULT.
1622  *
1623  * This is useful when reusing a file layout that was copied from an existing
1624  * file and to be used for a new file (e.g. when mirroring or migrating or
1625  * copying a file), so the objects are allocated on different OSTs.
1626  *
1627  * \retval  0 Success.
1628  * \retval -ve errno Error with errno set to non-zero value.
1629  */
1630 int llapi_layout_ost_index_reset(struct llapi_layout *layout)
1631 {
1632         int save_errno = 0;
1633         int rc;
1634
1635         rc = llapi_layout_comp_iterate(layout, reset_index_cb, &save_errno);
1636
1637         if (save_errno)
1638                 errno = save_errno;
1639         return save_errno ? -save_errno : (rc < 0 ? -errno : 0);
1640 }
1641
1642 /**
1643  * Get the OST index associated with stripe \a stripe_number.
1644  *
1645  * Stripes are indexed starting from zero.
1646  *
1647  * \param[in] layout            layout to get index from
1648  * \param[in] stripe_number     stripe number to get index for
1649  * \param[out] index            integer to store index in
1650  *
1651  * \retval      0 on success
1652  * \retval      -1 if arguments are invalid
1653  */
1654 int llapi_layout_ost_index_get(const struct llapi_layout *layout,
1655                                uint64_t stripe_number, uint64_t *index)
1656 {
1657         struct llapi_layout_comp *comp;
1658
1659         comp = __llapi_layout_cur_comp(layout);
1660         if (comp == NULL)
1661                 return -1;
1662
1663         if (comp->llc_pattern == LLAPI_LAYOUT_FOREIGN) {
1664                 errno = EINVAL;
1665                 return -1;
1666         }
1667
1668         if (index == NULL) {
1669                 errno = EINVAL;
1670                 return -1;
1671         }
1672
1673         if (stripe_number >= comp->llc_stripe_count ||
1674             stripe_number >= comp->llc_objects_count) {
1675                 errno = EINVAL;
1676                 return -1;
1677         }
1678
1679         if (comp->llc_stripe_offset == LLAPI_LAYOUT_DEFAULT)
1680                 *index = LLAPI_LAYOUT_DEFAULT;
1681         else
1682                 *index = comp->llc_objects[stripe_number].l_ost_idx;
1683
1684         return 0;
1685 }
1686
1687 /**
1688  *
1689  * Get the pool name of layout \a layout.
1690  *
1691  * \param[in] layout    layout to get pool name from
1692  * \param[out] dest     buffer to store pool name in
1693  * \param[in] n         size in bytes of buffer \a dest
1694  *
1695  * \retval      0 on success
1696  * \retval      -1 if arguments are invalid
1697  */
1698 int llapi_layout_pool_name_get(const struct llapi_layout *layout, char *dest,
1699                                size_t n)
1700 {
1701         struct llapi_layout_comp *comp;
1702
1703         comp = __llapi_layout_cur_comp(layout);
1704         if (comp == NULL)
1705                 return -1;
1706
1707         if (dest == NULL) {
1708                 errno = EINVAL;
1709                 return -1;
1710         }
1711
1712         if (comp->llc_pattern == LLAPI_LAYOUT_FOREIGN) {
1713                 errno = EINVAL;
1714                 return -1;
1715         }
1716
1717         strncpy(dest, comp->llc_pool_name, n);
1718
1719         return 0;
1720 }
1721
1722 /**
1723  * Set the name of the pool of layout \a layout.
1724  *
1725  * \param[in] layout    layout to set pool name in
1726  * \param[in] pool_name pool name to set
1727  *
1728  * \retval      0 on success
1729  * \retval      -1 if arguments are invalid or pool name is too long
1730  */
1731 int llapi_layout_pool_name_set(struct llapi_layout *layout,
1732                                const char *pool_name)
1733 {
1734         struct llapi_layout_comp *comp;
1735
1736         comp = __llapi_layout_cur_comp(layout);
1737         if (comp == NULL)
1738                 return -1;
1739
1740         if (!llapi_pool_name_is_valid(&pool_name)) {
1741                 errno = EINVAL;
1742                 return -1;
1743         }
1744
1745         if (comp->llc_pattern == LLAPI_LAYOUT_FOREIGN) {
1746                 errno = EINVAL;
1747                 return -1;
1748         }
1749
1750         strncpy(comp->llc_pool_name, pool_name, sizeof(comp->llc_pool_name));
1751         return 0;
1752 }
1753
1754 /**
1755  * Open and possibly create a file with a given \a layout.
1756  *
1757  * If \a layout is NULL this function acts as a simple wrapper for
1758  * open().  By convention, ENOTTY is returned in errno if \a path
1759  * refers to a non-Lustre file.
1760  *
1761  * \param[in] path              name of the file to open
1762  * \param[in] open_flags        open() flags
1763  * \param[in] mode              permissions to create file, filtered by umask
1764  * \param[in] layout            layout to create new file with
1765  *
1766  * \retval              non-negative file descriptor on successful open
1767  * \retval              -1 if an error occurred
1768  */
1769 int llapi_layout_file_open(const char *path, int open_flags, mode_t mode,
1770                            const struct llapi_layout *layout)
1771 {
1772         int fd;
1773         int rc;
1774         int tmp;
1775         struct lov_user_md *lum;
1776         size_t lum_size;
1777         char fsname[MAX_OBD_NAME + 1] = { 0 };
1778
1779         if (path == NULL ||
1780             (layout != NULL && layout->llot_magic != LLAPI_LAYOUT_MAGIC)) {
1781                 errno = EINVAL;
1782                 return -1;
1783         }
1784
1785         if (layout) {
1786                 /* Make sure we are on a Lustre file system */
1787                 rc = llapi_search_fsname(path, fsname);
1788                 if (rc) {
1789                         errno = ENOTTY;
1790                         return -1;
1791                 }
1792                 rc = llapi_layout_v2_sanity((struct llapi_layout *)layout,
1793                                             false,
1794                                             !!(layout->llot_mirror_count > 1),
1795                                             fsname);
1796                 if (rc) {
1797                         llapi_layout_sanity_perror(rc);
1798                         return -1;
1799                 }
1800         }
1801
1802         /* Object creation must be postponed until after layout attributes
1803          * have been applied. */
1804         if (layout != NULL && (open_flags & O_CREAT))
1805                 open_flags |= O_LOV_DELAY_CREATE;
1806
1807         fd = open(path, open_flags, mode);
1808
1809         if (layout == NULL || fd < 0)
1810                 return fd;
1811
1812         lum = llapi_layout_to_lum(layout);
1813
1814         if (lum == NULL) {
1815                 tmp = errno;
1816                 close(fd);
1817                 errno = tmp;
1818                 return -1;
1819         }
1820
1821         if (lum->lmm_magic == LOV_USER_MAGIC_COMP_V1)
1822                 lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
1823         else if (lum->lmm_magic == LOV_USER_MAGIC_SPECIFIC)
1824                 lum_size = lov_user_md_size(lum->lmm_stripe_count,
1825                                             lum->lmm_magic);
1826         else
1827                 lum_size = lov_user_md_size(0, lum->lmm_magic);
1828
1829         rc = fsetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_size, 0);
1830         if (rc < 0) {
1831                 tmp = errno;
1832                 close(fd);
1833                 errno = tmp;
1834                 fd = -1;
1835         }
1836
1837         free(lum);
1838         errno = errno == EOPNOTSUPP ? ENOTTY : errno;
1839
1840         return fd;
1841 }
1842
1843 /**
1844  * Create a file with a given \a layout.
1845  *
1846  * Force O_CREAT and O_EXCL flags on so caller is assured that file was
1847  * created with the given \a layout on successful function return.
1848  *
1849  * \param[in] path              name of the file to open
1850  * \param[in] open_flags        open() flags
1851  * \param[in] mode              permissions to create new file with
1852  * \param[in] layout            layout to create new file with
1853  *
1854  * \retval              non-negative file descriptor on successful open
1855  * \retval              -1 if an error occurred
1856  */
1857 int llapi_layout_file_create(const char *path, int open_flags, int mode,
1858                              const struct llapi_layout *layout)
1859 {
1860         return llapi_layout_file_open(path, open_flags|O_CREAT|O_EXCL, mode,
1861                                       layout);
1862 }
1863
1864 int llapi_layout_flags_get(struct llapi_layout *layout, uint32_t *flags)
1865 {
1866         if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1867                 errno = EINVAL;
1868                 return -1;
1869         }
1870
1871         *flags = layout->llot_flags;
1872         return 0;
1873 }
1874
1875 /**
1876  * Set flags to the header of a component layout.
1877  */
1878 int llapi_layout_flags_set(struct llapi_layout *layout, uint32_t flags)
1879 {
1880         if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1881                 errno = EINVAL;
1882                 return -1;
1883         }
1884
1885         layout->llot_flags = flags;
1886         return 0;
1887 }
1888
1889 const char *llapi_layout_flags_string(uint32_t flags)
1890 {
1891         switch (flags & LCM_FL_FLR_MASK) {
1892         case LCM_FL_RDONLY:
1893                 return "ro";
1894         case LCM_FL_WRITE_PENDING:
1895                 return "wp";
1896         case LCM_FL_SYNC_PENDING:
1897                 return "sp";
1898         case LCM_FL_RDONLY | LCM_FL_PCC_RDONLY:
1899                 return "ro,pccro";
1900         case LCM_FL_WRITE_PENDING | LCM_FL_PCC_RDONLY:
1901                 return "wp,pccro";
1902         case LCM_FL_SYNC_PENDING | LCM_FL_PCC_RDONLY:
1903                 return "sp,pccro";
1904         }
1905
1906         return "0";
1907 }
1908
1909 __u16 llapi_layout_string_flags(char *string)
1910 {
1911         if (strncmp(string, "ro", strlen(string)) == 0)
1912                 return LCM_FL_RDONLY;
1913         if (strncmp(string, "wp", strlen(string)) == 0)
1914                 return LCM_FL_WRITE_PENDING;
1915         if (strncmp(string, "sp", strlen(string)) == 0)
1916                 return LCM_FL_SYNC_PENDING;
1917
1918         return 0;
1919 }
1920
1921 /**
1922  * llapi_layout_mirror_count_is_valid() - Check the validity of mirror count.
1923  * @count: Mirror count value to be checked.
1924  *
1925  * This function checks the validity of mirror count.
1926  *
1927  * Return: true on success or false on failure.
1928  */
1929 static bool llapi_layout_mirror_count_is_valid(uint16_t count)
1930 {
1931         return count >= 0 && count <= LUSTRE_MIRROR_COUNT_MAX;
1932 }
1933
1934 /**
1935  * llapi_layout_mirror_count_get() - Get mirror count from the header of
1936  *                                   a layout.
1937  * @layout: Layout to get mirror count from.
1938  * @count:  Returned mirror count value.
1939  *
1940  * This function gets mirror count from the header of a layout.
1941  *
1942  * Return: 0 on success or -1 on failure.
1943  */
1944 int llapi_layout_mirror_count_get(struct llapi_layout *layout,
1945                                   uint16_t *count)
1946 {
1947         if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1948                 errno = EINVAL;
1949                 return -1;
1950         }
1951
1952         *count = layout->llot_mirror_count;
1953         return 0;
1954 }
1955
1956 /**
1957  * llapi_layout_mirror_count_set() - Set mirror count to the header of a layout.
1958  * @layout: Layout to set mirror count in.
1959  * @count:  Mirror count value to be set.
1960  *
1961  * This function sets mirror count to the header of a layout.
1962  *
1963  * Return: 0 on success or -1 on failure.
1964  */
1965 int llapi_layout_mirror_count_set(struct llapi_layout *layout,
1966                                   uint16_t count)
1967 {
1968         if (layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
1969                 errno = EINVAL;
1970                 return -1;
1971         }
1972
1973         if (!llapi_layout_mirror_count_is_valid(count)) {
1974                 errno = EINVAL;
1975                 return -1;
1976         }
1977
1978         layout->llot_mirror_count = count;
1979         return 0;
1980 }
1981
1982 /**
1983  * Fetch the start and end offset of the current layout component.
1984  *
1985  * \param[in] layout    the layout component
1986  * \param[out] start    extent start, inclusive
1987  * \param[out] end      extent end, exclusive
1988  *
1989  * \retval      0 on success
1990  * \retval      <0 if error occurs
1991  */
1992 int llapi_layout_comp_extent_get(const struct llapi_layout *layout,
1993                                  uint64_t *start, uint64_t *end)
1994 {
1995         struct llapi_layout_comp *comp;
1996
1997         comp = __llapi_layout_cur_comp(layout);
1998         if (comp == NULL)
1999                 return -1;
2000
2001         if (start == NULL || end == NULL) {
2002                 errno = EINVAL;
2003                 return -1;
2004         }
2005
2006         *start = comp->llc_extent.e_start;
2007         *end = comp->llc_extent.e_end;
2008
2009         return 0;
2010 }
2011
2012 /**
2013  * Set the layout extent of a layout.
2014  *
2015  * \param[in] layout    the layout to be set
2016  * \param[in] start     extent start, inclusive
2017  * \param[in] end       extent end, exclusive
2018  *
2019  * \retval      0 on success
2020  * \retval      <0 if error occurs
2021  */
2022 int llapi_layout_comp_extent_set(struct llapi_layout *layout,
2023                                  uint64_t start, uint64_t end)
2024 {
2025         struct llapi_layout_comp *comp;
2026
2027         comp = __llapi_layout_cur_comp(layout);
2028         if (comp == NULL)
2029                 return -1;
2030
2031         if (start > end) {
2032                 errno = EINVAL;
2033                 return -1;
2034         }
2035
2036         comp->llc_extent.e_start = start;
2037         comp->llc_extent.e_end = end;
2038         layout->llot_is_composite = true;
2039
2040         return 0;
2041 }
2042
2043 /**
2044  * Gets the attribute flags of the current component.
2045  *
2046  * \param[in] layout    the layout component
2047  * \param[out] flags    stored the returned component flags
2048  *
2049  * \retval      0 on success
2050  * \retval      <0 if error occurs
2051  */
2052 int llapi_layout_comp_flags_get(const struct llapi_layout *layout,
2053                                 uint32_t *flags)
2054 {
2055         struct llapi_layout_comp *comp;
2056
2057         comp = __llapi_layout_cur_comp(layout);
2058         if (comp == NULL)
2059                 return -1;
2060
2061         if (flags == NULL) {
2062                 errno = EINVAL;
2063                 return -1;
2064         }
2065
2066         *flags = comp->llc_flags;
2067
2068         return 0;
2069 }
2070
2071 /**
2072  * Sets the specified flags of the current component leaving other flags as-is.
2073  *
2074  * \param[in] layout    the layout component
2075  * \param[in] flags     component flags to be set
2076  *
2077  * \retval      0 on success
2078  * \retval      <0 if error occurs
2079  */
2080 int llapi_layout_comp_flags_set(struct llapi_layout *layout, uint32_t flags)
2081 {
2082         struct llapi_layout_comp *comp;
2083
2084         comp = __llapi_layout_cur_comp(layout);
2085         if (comp == NULL)
2086                 return -1;
2087
2088         comp->llc_flags |= flags;
2089
2090         return 0;
2091 }
2092
2093 /**
2094  * Clears the flags specified in the flags leaving other flags as-is.
2095  *
2096  * \param[in] layout    the layout component
2097  * \param[in] flags     component flags to be cleared
2098  *
2099  * \retval      0 on success
2100  * \retval      <0 if error occurs
2101  */
2102 int llapi_layout_comp_flags_clear(struct llapi_layout *layout,
2103                                   uint32_t flags)
2104 {
2105         struct llapi_layout_comp *comp;
2106
2107         comp = __llapi_layout_cur_comp(layout);
2108         if (comp == NULL)
2109                 return -1;
2110
2111         comp->llc_flags &= ~flags;
2112
2113         return 0;
2114 }
2115
2116 /**
2117  * Fetches the file-unique component ID of the current layout component.
2118  *
2119  * \param[in] layout    the layout component
2120  * \param[out] id       stored the returned component ID
2121  *
2122  * \retval      0 on success
2123  * \retval      <0 if error occurs
2124  */
2125 int llapi_layout_comp_id_get(const struct llapi_layout *layout, uint32_t *id)
2126 {
2127         struct llapi_layout_comp *comp;
2128
2129         comp = __llapi_layout_cur_comp(layout);
2130         if (comp == NULL)
2131                 return -1;
2132
2133         if (id == NULL) {
2134                 errno = EINVAL;
2135                 return -1;
2136         }
2137         *id = comp->llc_id;
2138
2139         return 0;
2140 }
2141
2142 /**
2143  * Return the mirror id of the current layout component.
2144  *
2145  * \param[in] layout    the layout component
2146  * \param[out] id       stored the returned mirror ID
2147  *
2148  * \retval      0 on success
2149  * \retval      <0 if error occurs
2150  */
2151 int llapi_layout_mirror_id_get(const struct llapi_layout *layout, uint32_t *id)
2152 {
2153         struct llapi_layout_comp *comp;
2154
2155         comp = __llapi_layout_cur_comp(layout);
2156         if (comp == NULL)
2157                 return -1;
2158
2159         if (id == NULL) {
2160                 errno = EINVAL;
2161                 return -1;
2162         }
2163
2164         *id = mirror_id_of(comp->llc_id);
2165
2166         return 0;
2167 }
2168
2169 /**
2170  * Adds a component to \a layout, the new component will be added to
2171  * the tail of components list and it'll inherit attributes of existing
2172  * ones. The \a layout will change it's current component pointer to
2173  * the newly added component, and it'll be turned into a composite
2174  * layout if it was not before the adding.
2175  *
2176  * \param[in] layout    existing composite or plain layout
2177  *
2178  * \retval      0 on success
2179  * \retval      <0 if error occurs
2180  */
2181 int llapi_layout_comp_add(struct llapi_layout *layout)
2182 {
2183         struct llapi_layout_comp *last, *comp, *new;
2184         bool composite = layout->llot_is_composite;
2185
2186         comp = __llapi_layout_cur_comp(layout);
2187         if (comp == NULL)
2188                 return -1;
2189
2190         new = __llapi_comp_alloc(0);
2191         if (new == NULL)
2192                 return -1;
2193
2194         last = list_last_entry(&layout->llot_comp_list, typeof(*last),
2195                                llc_list);
2196
2197         list_add_tail(&new->llc_list, &layout->llot_comp_list);
2198
2199         /* We must mark the layout composite for the sanity check, but it may
2200          * not stay that way if the check fails */
2201         layout->llot_is_composite = true;
2202         layout->llot_cur_comp = new;
2203
2204         /* We need to set a temporary non-zero value for "end" when we call
2205          * comp_extent_set, so we use LUSTRE_EOF-1, which is > all allowed
2206          * for the end of the previous component.  (If we're adding this
2207          * component, the end of the previous component cannot be EOF.) */
2208         if (llapi_layout_comp_extent_set(layout, last->llc_extent.e_end,
2209                                         LUSTRE_EOF - 1)) {
2210                 llapi_layout_comp_del(layout);
2211                 layout->llot_is_composite = composite;
2212                 return -1;
2213         }
2214
2215         return 0;
2216 }
2217 /**
2218  * Adds a first component of a mirror to \a layout.
2219  * The \a layout will change it's current component pointer to
2220  * the newly added component, and it'll be turned into a composite
2221  * layout if it was not before the adding.
2222  *
2223  * \param[in] layout            existing composite or plain layout
2224  *
2225  * \retval      0 on success
2226  * \retval      <0 if error occurs
2227  */
2228 int llapi_layout_add_first_comp(struct llapi_layout *layout)
2229 {
2230         struct llapi_layout_comp *comp, *new;
2231
2232         comp = __llapi_layout_cur_comp(layout);
2233         if (comp == NULL)
2234                 return -1;
2235
2236         new = __llapi_comp_alloc(0);
2237         if (new == NULL)
2238                 return -1;
2239
2240         new->llc_extent.e_start = 0;
2241
2242         list_add_tail(&new->llc_list, &layout->llot_comp_list);
2243         layout->llot_cur_comp = new;
2244         layout->llot_is_composite = true;
2245
2246         return 0;
2247 }
2248
2249 /**
2250  * Deletes current component from the composite layout. The component
2251  * to be deleted must be the tail of components list, and it can't be
2252  * the only component in the layout.
2253  *
2254  * \param[in] layout    composite layout
2255  *
2256  * \retval      0 on success
2257  * \retval      <0 if error occurs
2258  */
2259 int llapi_layout_comp_del(struct llapi_layout *layout)
2260 {
2261         struct llapi_layout_comp *comp;
2262
2263         comp = __llapi_layout_cur_comp(layout);
2264         if (comp == NULL)
2265                 return -1;
2266
2267         if (!layout->llot_is_composite) {
2268                 errno = EINVAL;
2269                 return -1;
2270         }
2271
2272         /* It must be the tail of the list (for PFL, can be relaxed
2273          * once we get mirrored components) */
2274         if (comp->llc_list.next != &layout->llot_comp_list) {
2275                 errno = EINVAL;
2276                 return -1;
2277         }
2278         layout->llot_cur_comp =
2279                 list_last_entry(&comp->llc_list, typeof(*comp), llc_list);
2280         if (comp->llc_list.prev == &layout->llot_comp_list)
2281                 layout->llot_cur_comp = NULL;
2282
2283         list_del_init(&comp->llc_list);
2284         __llapi_comp_free(comp);
2285
2286         return 0;
2287 }
2288
2289 /**
2290  * Move the current component pointer to the component with
2291  * specified component ID.
2292  *
2293  * \param[in] layout    composite layout
2294  * \param[in] id        component ID
2295  *
2296  * \retval      =0 : moved successfully
2297  * \retval      <0 if error occurs
2298  */
2299 int llapi_layout_comp_use_id(struct llapi_layout *layout, uint32_t comp_id)
2300 {
2301         struct llapi_layout_comp *comp;
2302
2303         comp = __llapi_layout_cur_comp(layout);
2304         if (comp == NULL)
2305                 return -1; /* use previously set errno */
2306
2307         if (!layout->llot_is_composite) {
2308                 errno = EINVAL;
2309                 return -1;
2310         }
2311
2312         if (comp_id == LCME_ID_INVAL) {
2313                 errno = EINVAL;
2314                 return -1;
2315         }
2316
2317         list_for_each_entry(comp, &layout->llot_comp_list, llc_list) {
2318                 if (comp->llc_id == comp_id) {
2319                         layout->llot_cur_comp = comp;
2320                         return 0;
2321                 }
2322         }
2323         errno = ENOENT;
2324         return -1;
2325 }
2326
2327 /**
2328  * Move the current component pointer to a specified position.
2329  *
2330  * \param[in] layout    composite layout
2331  * \param[in] pos       the position to be moved, it can be:
2332  *                      LLAPI_LAYOUT_COMP_USE_FIRST: use first component
2333  *                      LLAPI_LAYOUT_COMP_USE_LAST: use last component
2334  *                      LLAPI_LAYOUT_COMP_USE_NEXT: use component after current
2335  *                      LLAPI_LAYOUT_COMP_USE_PREV: use component before current
2336  *
2337  * \retval      =0 : moved successfully
2338  * \retval      =1 : at last component with NEXT, at first component with PREV
2339  * \retval      <0 if error occurs
2340  */
2341 int llapi_layout_comp_use(struct llapi_layout *layout,
2342                           enum llapi_layout_comp_use pos)
2343 {
2344         struct llapi_layout_comp *comp, *head, *tail;
2345
2346         comp = __llapi_layout_cur_comp(layout);
2347         if (comp == NULL)
2348                 return -1;
2349
2350         if (!layout->llot_is_composite) {
2351                 if (pos == LLAPI_LAYOUT_COMP_USE_FIRST ||
2352                     pos == LLAPI_LAYOUT_COMP_USE_LAST)
2353                         return 0;
2354                 errno = ENOENT;
2355                 return 1;
2356         }
2357
2358         head = list_first_entry(&layout->llot_comp_list, typeof(*head),
2359                                 llc_list);
2360         tail = list_last_entry(&layout->llot_comp_list, typeof(*tail),
2361                                llc_list);
2362         switch (pos) {
2363         case LLAPI_LAYOUT_COMP_USE_FIRST:
2364                 layout->llot_cur_comp = head;
2365                 break;
2366         case LLAPI_LAYOUT_COMP_USE_NEXT:
2367                 if (comp == tail) {
2368                         errno = ENOENT;
2369                         return 1;
2370                 }
2371                 layout->llot_cur_comp = list_first_entry(&comp->llc_list,
2372                                                          typeof(*comp),
2373                                                          llc_list);
2374                 break;
2375         case LLAPI_LAYOUT_COMP_USE_LAST:
2376                 layout->llot_cur_comp = tail;
2377                 break;
2378         case LLAPI_LAYOUT_COMP_USE_PREV:
2379                 if (comp == head) {
2380                         errno = ENOENT;
2381                         return 1;
2382                 }
2383                 layout->llot_cur_comp = list_last_entry(&comp->llc_list,
2384                                                         typeof(*comp),
2385                                                         llc_list);
2386                 break;
2387         default:
2388                 errno = EINVAL;
2389                 return -1;
2390         }
2391
2392         return 0;
2393 }
2394
2395 /**
2396  * Add layout component(s) to an existing file.
2397  *
2398  * \param[in] path      The path name of the file
2399  * \param[in] layout    The layout component(s) to be added
2400  */
2401 int llapi_layout_file_comp_add(const char *path,
2402                                const struct llapi_layout *layout)
2403 {
2404         int rc, fd = -1, lum_size, tmp_errno = 0;
2405         struct llapi_layout *existing_layout = NULL;
2406         struct lov_user_md *lum = NULL;
2407         char fsname[MAX_OBD_NAME + 1] = { 0 };
2408
2409         if (path == NULL || layout == NULL ||
2410             layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
2411                 errno = EINVAL;
2412                 return -1;
2413         }
2414
2415         fd = open(path, O_RDWR);
2416         if (fd < 0) {
2417                 tmp_errno = errno;
2418                 rc = -1;
2419                 goto out;
2420         }
2421
2422         existing_layout = llapi_layout_get_by_fd(fd, 0);
2423         if (existing_layout == NULL) {
2424                 tmp_errno = errno;
2425                 rc = -1;
2426                 goto out;
2427         }
2428
2429         rc = llapi_layout_merge(&existing_layout, layout);
2430         if (rc) {
2431                 tmp_errno = errno;
2432                 rc = -1;
2433                 goto out;
2434         }
2435
2436         rc = llapi_search_fsname(path, fsname);
2437         if (rc) {
2438                 tmp_errno = -rc;
2439                 rc = -1;
2440                 goto out;
2441         }
2442
2443         rc = llapi_layout_v2_sanity(existing_layout, false, false, fsname);
2444         if (rc) {
2445                 tmp_errno = errno;
2446                 llapi_layout_sanity_perror(rc);
2447                 rc = -1;
2448                 goto out;
2449         }
2450
2451         lum = llapi_layout_to_lum(layout);
2452         if (lum == NULL) {
2453                 tmp_errno = errno;
2454                 rc = -1;
2455                 goto out;
2456         }
2457
2458         if (lum->lmm_magic != LOV_USER_MAGIC_COMP_V1) {
2459                 tmp_errno = EINVAL;
2460                 rc = -1;
2461                 goto out;
2462         }
2463         lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
2464
2465         rc = fsetxattr(fd, XATTR_LUSTRE_LOV".add", lum, lum_size, 0);
2466         if (rc < 0) {
2467                 tmp_errno = errno;
2468                 rc = -1;
2469                 goto out;
2470         }
2471 out:
2472         if (fd >= 0)
2473                 close(fd);
2474         free(lum);
2475         llapi_layout_free(existing_layout);
2476         errno = tmp_errno;
2477         return rc;
2478 }
2479
2480 /**
2481  * Delete component(s) by the specified component id or component flags
2482  * from an existing file.
2483  *
2484  * \param[in] path      path name of the file
2485  * \param[in] id        unique component ID
2486  * \param[in] flags     flags: LCME_FL_* or;
2487  *                      negative flags: (LCME_FL_NEG|LCME_FL_*)
2488  */
2489 int llapi_layout_file_comp_del(const char *path, uint32_t id, uint32_t flags)
2490 {
2491         int rc = 0, fd = -1, lum_size, tmp_errno = 0;
2492         struct llapi_layout *layout;
2493         struct llapi_layout_comp *comp, *next;
2494         struct llapi_layout *existing_layout = NULL;
2495         struct lov_user_md *lum = NULL;
2496
2497         if (path == NULL || id > LCME_ID_MAX || (flags & ~LCME_KNOWN_FLAGS)) {
2498                 errno = EINVAL;
2499                 return -1;
2500         }
2501
2502         /* Can only specify ID or flags, not both, not none. */
2503         if ((id != LCME_ID_INVAL && flags != 0) ||
2504             (id == LCME_ID_INVAL && flags == 0)) {
2505                 errno = EINVAL;
2506                 return -1;
2507         }
2508
2509         layout = llapi_layout_alloc();
2510         if (layout == NULL)
2511                 return -1;
2512
2513         llapi_layout_comp_extent_set(layout, 0, LUSTRE_EOF);
2514         comp = __llapi_layout_cur_comp(layout);
2515         if (comp == NULL) {
2516                 tmp_errno = errno;
2517                 rc = -1;
2518                 goto out;
2519         }
2520
2521         comp->llc_id = id;
2522         comp->llc_flags = flags;
2523
2524         lum = llapi_layout_to_lum(layout);
2525         if (lum == NULL) {
2526                 tmp_errno = errno;
2527                 rc = -1;
2528                 goto out;
2529         }
2530         lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
2531
2532         fd = open(path, O_RDWR);
2533         if (fd < 0) {
2534                 tmp_errno = errno;
2535                 rc = -1;
2536                 goto out;
2537         }
2538
2539         existing_layout = llapi_layout_get_by_fd(fd, 0);
2540         if (existing_layout == NULL) {
2541                 tmp_errno = errno;
2542                 rc = -1;
2543                 goto out;
2544         }
2545
2546         comp = NULL;
2547         next = NULL;
2548         while (rc == 0 && existing_layout->llot_cur_comp != NULL) {
2549                 rc = llapi_layout_comp_use(existing_layout, comp ?
2550                                            LLAPI_LAYOUT_COMP_USE_PREV :
2551                                            LLAPI_LAYOUT_COMP_USE_LAST);
2552                 if (rc != 0)
2553                         break;
2554
2555                 next = comp;
2556                 comp = __llapi_layout_cur_comp(existing_layout);
2557                 if (comp == NULL) {
2558                         rc = -1;
2559                         break;
2560                 }
2561
2562                 if (id != LCME_ID_INVAL && id != comp->llc_id)
2563                         continue;
2564                 else if ((flags & LCME_FL_NEG) && (flags & comp->llc_flags))
2565                         continue;
2566                 else if (flags && !(flags & comp->llc_flags))
2567                         continue;
2568
2569                 rc = llapi_layout_comp_del(existing_layout);
2570                 /* the layout position is moved to previous one, adjust */
2571                 comp = next;
2572         }
2573         if (rc < 0) {
2574                 tmp_errno = errno;
2575                 goto out;
2576         }
2577
2578         rc = llapi_layout_sanity(existing_layout, false, false);
2579         if (rc) {
2580                 tmp_errno = errno;
2581                 llapi_layout_sanity_perror(rc);
2582                 rc = -1;
2583                 goto out;
2584         }
2585
2586         rc = fsetxattr(fd, XATTR_LUSTRE_LOV".del", lum, lum_size, 0);
2587         if (rc < 0) {
2588                 tmp_errno = errno;
2589                 rc = -1;
2590                 goto out;
2591         }
2592
2593 out:
2594         if (fd >= 0)
2595                 close(fd);
2596         free(lum);
2597         llapi_layout_free(layout);
2598         llapi_layout_free(existing_layout);
2599         errno = tmp_errno;
2600
2601         return rc;
2602 }
2603
2604 /* Internal utility function to apply flags for sanity checking */
2605 static void llapi_layout_comp_apply_flags(struct llapi_layout_comp *comp,
2606                                           uint32_t flags)
2607 {
2608         if (flags & LCME_FL_NEG)
2609                 comp->llc_flags &= ~flags;
2610         else
2611                 comp->llc_flags |= flags;
2612 }
2613
2614 struct llapi_layout_apply_flags_args {
2615         uint32_t *lfa_ids;
2616         uint32_t *lfa_flags;
2617         int lfa_count;
2618         int lfa_rc;
2619 };
2620
2621
2622 static int llapi_layout_apply_flags_cb(struct llapi_layout *layout,
2623                                        void *arg)
2624 {
2625         struct llapi_layout_apply_flags_args *args = arg;
2626         struct llapi_layout_comp *comp;
2627         int i = 0;
2628
2629         comp = __llapi_layout_cur_comp(layout);
2630         if (comp == NULL) {
2631                 args->lfa_rc = -1;
2632                 return LLAPI_LAYOUT_ITER_STOP;
2633         }
2634
2635         for (i = 0; i < args->lfa_count; i++) {
2636                 if (comp->llc_id == args->lfa_ids[i])
2637                         llapi_layout_comp_apply_flags(comp, args->lfa_flags[i]);
2638         }
2639
2640         return LLAPI_LAYOUT_ITER_CONT;
2641 }
2642
2643 /* Apply flags to the layout for sanity checking */
2644 static int llapi_layout_apply_flags(struct llapi_layout *layout, uint32_t *ids,
2645                                     uint32_t *flags, int count)
2646 {
2647         struct llapi_layout_apply_flags_args args;
2648         int rc = 0;
2649
2650         if (!ids || !flags || count == 0) {
2651                 errno = EINVAL;
2652                 return -1;
2653         }
2654
2655         args.lfa_ids = ids;
2656         args.lfa_flags = flags;
2657         args.lfa_count = count;
2658         args.lfa_rc = 0;
2659
2660         rc = llapi_layout_comp_iterate(layout,
2661                                        llapi_layout_apply_flags_cb,
2662                                        &args);
2663         if (errno == ENOENT)
2664                 errno = 0;
2665
2666         if (rc != LLAPI_LAYOUT_ITER_CONT)
2667                 rc = args.lfa_rc;
2668
2669         return rc;
2670 }
2671 /**
2672  * Change flags by component ID of components of an existing file.
2673  * The component to be modified is specified by the comp->lcme_id value,
2674  * which must be a unique component ID.
2675  *
2676  * \param[in] path      path name of the file
2677  * \param[in] ids       An array of component IDs
2678  * \param[in] flags     flags: LCME_FL_* or;
2679  *                      negative flags: (LCME_FL_NEG|LCME_FL_*)
2680  * \param[in] count     Number of elements in ids and flags array
2681  */
2682 int llapi_layout_file_comp_set(const char *path, uint32_t *ids, uint32_t *flags,
2683                                size_t count)
2684 {
2685         int rc = -1, fd = -1, i, tmp_errno = 0;
2686         size_t lum_size;
2687         struct llapi_layout *existing_layout = NULL;
2688         struct llapi_layout *layout = NULL;
2689         struct llapi_layout_comp *comp;
2690         struct lov_user_md *lum = NULL;
2691         char fsname[MAX_OBD_NAME + 1] = { 0 };
2692
2693         if (path == NULL) {
2694                 errno = EINVAL;
2695                 return -1;
2696         }
2697
2698         if (!count)
2699                 return 0;
2700
2701         for (i = 0; i < count; i++) {
2702                 if (!ids[i] || !flags[i]) {
2703                         errno = EINVAL;
2704                         return -1;
2705                 }
2706
2707                 if (ids[i] > LCME_ID_MAX || (flags[i] & ~LCME_KNOWN_FLAGS)) {
2708                         errno = EINVAL;
2709                         return -1;
2710                 }
2711
2712                 /* do not allow to set or clear INIT flag */
2713                 if (flags[i] & LCME_FL_INIT) {
2714                         errno = EINVAL;
2715                         return -1;
2716                 }
2717         }
2718
2719         fd = open(path, O_RDWR);
2720         if (fd < 0) {
2721                 tmp_errno = errno;
2722                 rc = -1;
2723                 goto out;
2724         }
2725
2726         existing_layout = llapi_layout_get_by_fd(fd, 0);
2727         if (existing_layout == NULL) {
2728                 tmp_errno = errno;
2729                 rc = -1;
2730                 goto out;
2731         }
2732
2733         if (llapi_layout_apply_flags(existing_layout, ids, flags, count)) {
2734                 tmp_errno = errno;
2735                 rc = -1;
2736                 goto out;
2737         }
2738
2739         rc = llapi_search_fsname(path, fsname);
2740         if (rc) {
2741                 tmp_errno = -rc;
2742                 rc = -1;
2743                 goto out;
2744         }
2745
2746         rc = llapi_layout_v2_sanity(existing_layout, false, false, fsname);
2747         if (rc) {
2748                 tmp_errno = errno;
2749                 llapi_layout_sanity_perror(rc);
2750                 rc = -1;
2751                 goto out;
2752         }
2753
2754         layout = __llapi_layout_alloc();
2755         if (layout == NULL) {
2756                 tmp_errno = errno;
2757                 rc = -1;
2758                 goto out;
2759         }
2760
2761         layout->llot_is_composite = true;
2762         for (i = 0; i < count; i++) {
2763                 comp = __llapi_comp_alloc(0);
2764                 if (comp == NULL) {
2765                         tmp_errno = errno;
2766                         rc = -1;
2767                         goto out;
2768                 }
2769
2770                 comp->llc_id = ids[i];
2771                 comp->llc_flags = flags[i];
2772
2773                 list_add_tail(&comp->llc_list, &layout->llot_comp_list);
2774                 layout->llot_cur_comp = comp;
2775         }
2776
2777         lum = llapi_layout_to_lum(layout);
2778         if (lum == NULL) {
2779                 tmp_errno = errno;
2780                 rc = -1;
2781                 goto out;
2782         }
2783
2784         lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
2785
2786         /* flush cached pages from clients */
2787         rc = llapi_file_flush(fd);
2788         if (rc) {
2789                 tmp_errno = -rc;
2790                 rc = -1;
2791                 goto out;
2792         }
2793
2794         rc = fsetxattr(fd, XATTR_LUSTRE_LOV".set.flags", lum, lum_size, 0);
2795         if (rc < 0) {
2796                 tmp_errno = errno;
2797                 goto out;
2798         }
2799
2800         rc = 0;
2801
2802 out:
2803         if (fd >= 0)
2804                 close(fd);
2805
2806         free(lum);
2807         llapi_layout_free(existing_layout);
2808         llapi_layout_free(layout);
2809         errno = tmp_errno;
2810         return rc;
2811 }
2812
2813 /**
2814  * Check if the file layout is composite.
2815  *
2816  * \param[in] layout    the file layout to check
2817  *
2818  * \retval true         composite
2819  * \retval false        not composite
2820  */
2821 bool llapi_layout_is_composite(struct llapi_layout *layout)
2822 {
2823         return layout->llot_is_composite;
2824 }
2825
2826 /**
2827  * Iterate every components in the @layout and call callback function @cb.
2828  *
2829  * \param[in] layout    component layout list.
2830  * \param[in] cb        callback function called for each component
2831  * \param[in] cbdata    callback data passed to the callback function
2832  *
2833  * \retval < 0                          error happens during the iteration
2834  * \retval LLAPI_LAYOUT_ITER_CONT       finished the iteration w/o error
2835  * \retval LLAPI_LAYOUT_ITER_STOP       got something, stop the iteration
2836  */
2837 int llapi_layout_comp_iterate(struct llapi_layout *layout,
2838                               llapi_layout_iter_cb cb, void *cbdata)
2839 {
2840         int rc;
2841
2842         rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
2843         if (rc < 0)
2844                 return rc;
2845
2846         /**
2847          * make sure on success llapi_layout_comp_use() API returns 0 with
2848          * USE_FIRST.
2849          */
2850         assert(rc == 0);
2851
2852         while (1) {
2853                 rc = cb(layout, cbdata);
2854                 if (rc != LLAPI_LAYOUT_ITER_CONT)
2855                         break;
2856
2857                 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
2858                 if (rc < 0)
2859                         return rc;
2860                 else if (rc == 1)       /* reached the last comp */
2861                         return LLAPI_LAYOUT_ITER_CONT;
2862         }
2863
2864         return rc;
2865 }
2866
2867 /**
2868  * llapi_layout_merge() - Merge a composite layout into another one.
2869  * @dst_layout: Destination composite layout.
2870  * @src_layout: Source composite layout.
2871  *
2872  * This function copies all of the components from @src_layout and
2873  * appends them to @dst_layout.
2874  *
2875  * Return: 0 on success or -1 on failure.
2876  */
2877 int llapi_layout_merge(struct llapi_layout **dst_layout,
2878                        const struct llapi_layout *src_layout)
2879 {
2880         struct llapi_layout *new_layout = *dst_layout;
2881         struct llapi_layout_comp *new = NULL;
2882         struct llapi_layout_comp *comp = NULL;
2883         int i = 0;
2884
2885         if (src_layout == NULL ||
2886             list_empty((struct list_head *)&src_layout->llot_comp_list))
2887                 return 0;
2888
2889         if (new_layout == NULL) {
2890                 new_layout = __llapi_layout_alloc();
2891                 if (new_layout == NULL) {
2892                         errno = ENOMEM;
2893                         return -1;
2894                 }
2895         }
2896
2897         list_for_each_entry(comp, &src_layout->llot_comp_list, llc_list) {
2898                 new = __llapi_comp_alloc(0);
2899                 if (new == NULL) {
2900                         errno = ENOMEM;
2901                         goto error;
2902                 }
2903
2904                 new->llc_pattern = comp->llc_pattern;
2905                 new->llc_stripe_size = comp->llc_stripe_size;
2906                 new->llc_stripe_count = comp->llc_stripe_count;
2907                 new->llc_stripe_offset = comp->llc_stripe_offset;
2908
2909                 if (comp->llc_pool_name[0] != '\0')
2910                         strncpy(new->llc_pool_name, comp->llc_pool_name,
2911                                 sizeof(new->llc_pool_name));
2912
2913                 for (i = 0; i < comp->llc_objects_count; i++) {
2914                         if (__llapi_comp_objects_realloc(new,
2915                             stripe_number_roundup(i)) < 0) {
2916                                 errno = EINVAL;
2917                                 __llapi_comp_free(new);
2918                                 goto error;
2919                         }
2920                         new->llc_objects[i].l_ost_idx = \
2921                                 comp->llc_objects[i].l_ost_idx;
2922                 }
2923
2924                 new->llc_objects_count = comp->llc_objects_count;
2925                 new->llc_extent.e_start = comp->llc_extent.e_start;
2926                 new->llc_extent.e_end = comp->llc_extent.e_end;
2927                 new->llc_id = comp->llc_id;
2928                 new->llc_flags = comp->llc_flags;
2929
2930                 list_add_tail(&new->llc_list, &new_layout->llot_comp_list);
2931                 new_layout->llot_cur_comp = new;
2932         }
2933         new_layout->llot_is_composite = true;
2934
2935         *dst_layout = new_layout;
2936         return 0;
2937 error:
2938         llapi_layout_free(new_layout);
2939         return -1;
2940 }
2941
2942 /**
2943  * Get the last initialized component
2944  *
2945  * \param[in] layout    component layout list.
2946  *
2947  * \retval 0            found
2948  * \retval -EINVAL      not found
2949  * \retval -EISDIR      directory layout
2950  */
2951 int llapi_layout_get_last_init_comp(struct llapi_layout *layout)
2952 {
2953         struct llapi_layout_comp *comp = NULL, *head = NULL;
2954
2955         if (!layout->llot_is_composite)
2956                 return 0;
2957
2958         head = list_first_entry(&layout->llot_comp_list, typeof(*comp),
2959                                 llc_list);
2960         if (head == NULL)
2961                 return -EINVAL;
2962         if (head->llc_id == 0 && !(head->llc_flags & LCME_FL_INIT))
2963                 /* a directory */
2964                 return -EISDIR;
2965
2966         /* traverse the components from the tail to find the last init one */
2967         comp = list_last_entry(&layout->llot_comp_list, typeof(*comp),
2968                                llc_list);
2969         while (comp != head) {
2970                 if (comp->llc_flags & LCME_FL_INIT)
2971                         break;
2972                 comp = list_last_entry(&comp->llc_list, typeof(*comp),
2973                                        llc_list);
2974         }
2975
2976         layout->llot_cur_comp = comp;
2977
2978         return comp->llc_flags & LCME_FL_INIT ? 0 : -EINVAL;
2979 }
2980
2981 /**
2982  * Interit stripe info from the file's component to the mirror
2983  *
2984  * \param[in] layout    file component layout list.
2985  * \param[in] layout    mirro component layout list.
2986  *
2987  * \retval 0            on success
2988  * \retval -EINVAL      on error
2989  */
2990 int llapi_layout_mirror_inherit(struct llapi_layout *f_layout,
2991                                 struct llapi_layout *m_layout)
2992 {
2993         struct llapi_layout_comp *m_comp = NULL;
2994         struct llapi_layout_comp *f_comp = NULL;
2995         int rc = 0;
2996
2997         f_comp = __llapi_layout_cur_comp(f_layout);
2998         if (f_comp == NULL)
2999                 return -EINVAL;
3000         m_comp = __llapi_layout_cur_comp(m_layout);
3001         if (m_comp == NULL)
3002                 return -EINVAL;
3003
3004         /* DoM component does not inherit stripe size */
3005         if (m_comp->llc_pattern != LLAPI_LAYOUT_MDT)
3006                 m_comp->llc_stripe_size = f_comp->llc_stripe_size;
3007         m_comp->llc_stripe_count = f_comp->llc_stripe_count;
3008
3009         return rc;
3010 }
3011
3012 /**
3013  * Find all stale components.
3014  *
3015  * \param[in] layout            component layout list.
3016  * \param[out] comp             array of stale component info.
3017  * \param[in] comp_size         array size of @comp.
3018  * \param[in] mirror_ids        array of mirror id that only components
3019  *                              belonging to these mirror will be collected.
3020  * \param[in] ids_nr            number of mirror ids array.
3021  *
3022  * \retval              number of component info collected on success or
3023  *                      an error code on failure.
3024  */
3025 int llapi_mirror_find_stale(struct llapi_layout *layout,
3026                 struct llapi_resync_comp *comp, size_t comp_size,
3027                 __u16 *mirror_ids, int ids_nr)
3028 {
3029         int idx = 0;
3030         int rc;
3031
3032         rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
3033         if (rc < 0)
3034                 goto error;
3035
3036         while (rc == 0) {
3037                 uint32_t id;
3038                 uint32_t mirror_id;
3039                 uint32_t flags;
3040                 uint64_t start, end;
3041
3042                 rc = llapi_layout_comp_flags_get(layout, &flags);
3043                 if (rc < 0)
3044                         goto error;
3045
3046                 if (!(flags & LCME_FL_STALE))
3047                         goto next;
3048
3049                 rc = llapi_layout_mirror_id_get(layout, &mirror_id);
3050                 if (rc < 0)
3051                         goto error;
3052
3053                 /* the caller only wants stale components from specific
3054                  * mirrors */
3055                 if (ids_nr > 0) {
3056                         int j;
3057
3058                         for (j = 0; j < ids_nr; j++) {
3059                                 if (mirror_ids[j] == mirror_id)
3060                                         break;
3061                         }
3062
3063                         /* not in the specified mirror */
3064                         if (j == ids_nr)
3065                                 goto next;
3066                 } else if (flags & LCME_FL_NOSYNC) {
3067                         /* if not specified mirrors, do not resync "nosync"
3068                          * mirrors */
3069                         goto next;
3070                 }
3071
3072                 rc = llapi_layout_comp_id_get(layout, &id);
3073                 if (rc < 0)
3074                         goto error;
3075
3076                 rc = llapi_layout_comp_extent_get(layout, &start, &end);
3077                 if (rc < 0)
3078                         goto error;
3079
3080                 /* pack this component into @comp array */
3081                 comp[idx].lrc_id = id;
3082                 comp[idx].lrc_mirror_id = mirror_id;
3083                 comp[idx].lrc_start = start;
3084                 comp[idx].lrc_end = end;
3085                 idx++;
3086
3087                 if (idx >= comp_size) {
3088                         rc = -EINVAL;
3089                         goto error;
3090                 }
3091
3092         next:
3093                 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
3094                 if (rc < 0) {
3095                         rc = -EINVAL;
3096                         goto error;
3097                 }
3098         }
3099 error:
3100         return rc < 0 ? rc : idx;
3101 }
3102
3103 /* locate @layout to a valid component covering file [file_start, file_end) */
3104 int llapi_mirror_find(struct llapi_layout *layout, uint64_t file_start,
3105                       uint64_t file_end, uint64_t *endp)
3106 {
3107         uint32_t mirror_id = 0;
3108         int rc;
3109
3110         rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
3111         if (rc < 0)
3112                 return rc;
3113
3114         *endp = 0;
3115         while (rc == 0) {
3116                 uint64_t start, end;
3117                 uint32_t flags, id, rid;
3118
3119                 rc = llapi_layout_comp_flags_get(layout, &flags);
3120                 if (rc < 0)
3121                         return rc;
3122
3123                 if (flags & LCME_FL_STALE)
3124                         goto next;
3125
3126                 rc = llapi_layout_mirror_id_get(layout, &rid);
3127                 if (rc < 0)
3128                         return rc;
3129
3130                 rc = llapi_layout_comp_id_get(layout, &id);
3131                 if (rc < 0)
3132                         return rc;
3133
3134                 rc = llapi_layout_comp_extent_get(layout, &start, &end);
3135                 if (rc < 0)
3136                         return rc;
3137
3138                 if (file_start >= start && file_start < end) {
3139                         if (!mirror_id)
3140                                 mirror_id = rid;
3141                         else if (mirror_id != rid || *endp != start)
3142                                 break;
3143
3144                         file_start = *endp = end;
3145                         if (end >= file_end)
3146                                 break;
3147                 }
3148
3149         next:
3150                 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
3151                 if (rc < 0)
3152                         return rc;
3153         }
3154         if (!mirror_id)
3155                 return -ENOENT;
3156
3157         return mirror_id;
3158 }
3159
3160 #ifndef NSEC_PER_SEC
3161 # define NSEC_PER_SEC 1000000000UL
3162 #endif
3163 #define ONE_MB 0x100000
3164 static struct timespec timespec_sub(struct timespec *before,
3165                                     struct timespec *after)
3166 {
3167         struct timespec ret;
3168
3169         ret.tv_sec = after->tv_sec - before->tv_sec;
3170         if (after->tv_nsec < before->tv_nsec) {
3171                 ret.tv_sec--;
3172                 ret.tv_nsec = NSEC_PER_SEC + after->tv_nsec - before->tv_nsec;
3173         } else {
3174                 ret.tv_nsec = after->tv_nsec - before->tv_nsec;
3175         }
3176
3177         return ret;
3178 }
3179
3180 static void stats_log(struct timespec *now, struct timespec *start_time,
3181                       ssize_t read_bytes, size_t write_bytes,
3182                       off_t file_size_bytes)
3183 {
3184         struct timespec diff = timespec_sub(start_time, now);
3185
3186         if (file_size_bytes == 0)
3187                 return;
3188
3189         if (diff.tv_sec == 0 && diff.tv_nsec == 0)
3190                 return;
3191
3192         llapi_printf(LLAPI_MSG_NORMAL,
3193                      "- { seconds: %li, rmbps: %5.2g, wmbps: %5.2g, copied: %lu, size: %lu, pct: %lu%% }\n",
3194                      diff.tv_sec,
3195                      (double) read_bytes/((ONE_MB * diff.tv_sec) +
3196                              ((ONE_MB * diff.tv_nsec)/NSEC_PER_SEC)),
3197                      (double) write_bytes/((ONE_MB * diff.tv_sec) +
3198                              ((ONE_MB * diff.tv_nsec)/NSEC_PER_SEC)),
3199                      write_bytes/ONE_MB,
3200                      file_size_bytes/ONE_MB,
3201                      ((write_bytes*100)/file_size_bytes));
3202 }
3203
3204 int llapi_mirror_resync_many_params(int fd, struct llapi_layout *layout,
3205                                     struct llapi_resync_comp *comp_array,
3206                                     int comp_size,  uint64_t start,
3207                                     uint64_t end,
3208                                     unsigned long stats_interval_sec,
3209                                     unsigned long bandwidth_bytes_sec)
3210 {
3211         size_t buflen = 64 << 20; /* 64M */
3212         ssize_t page_size;
3213         void *buf;
3214         uint64_t pos = start;
3215         uint64_t data_off = pos, data_end = pos;
3216         uint64_t mirror_end = LUSTRE_EOF;
3217         uint32_t src = 0;
3218         int i;
3219         int rc;
3220         int rc2 = 0;
3221         struct timespec start_time;
3222         struct timespec now;
3223         struct timespec last_bw_print;
3224         size_t total_bytes_read = 0;
3225         size_t total_bytes_written = 0;
3226         off_t write_estimation_bytes = 0;
3227
3228         if (bandwidth_bytes_sec > 0 || stats_interval_sec) {
3229                 struct stat st;
3230
3231                 rc = fstat(fd, &st);
3232                 if (rc < 0)
3233                         return -errno;
3234                 write_estimation_bytes = st.st_size * comp_size;
3235         }
3236
3237         /* limit transfer size to what can be sent in one second */
3238         if (bandwidth_bytes_sec && bandwidth_bytes_sec < buflen)
3239                 buflen = (bandwidth_bytes_sec + ONE_MB - 1) & ~(ONE_MB - 1);
3240
3241         page_size = sysconf(_SC_PAGESIZE);
3242         if (page_size < 0) {
3243                 rc = -errno;
3244                 return rc;
3245         }
3246
3247         rc = posix_memalign(&buf, page_size, buflen);
3248         if (rc)
3249                 return -rc;
3250
3251         clock_gettime(CLOCK_MONOTONIC, &start_time);
3252         now = last_bw_print = start_time;
3253
3254         while (pos < end) {
3255                 ssize_t bytes_read;
3256                 size_t to_read;
3257                 size_t to_write;
3258                 size_t data_size;
3259
3260                 if (pos >= data_end) {
3261                         off_t tmp_off;
3262
3263                         if (pos >= mirror_end || !src) {
3264                                 rc = llapi_mirror_find(layout, pos, end,
3265                                                         &mirror_end);
3266                                 if (rc < 0) {
3267                                         free(buf);
3268                                         return rc;
3269                                 }
3270                                 src = rc;
3271                                 /* restrict mirror end by resync end */
3272                                 mirror_end = MIN(end, mirror_end);
3273                         }
3274
3275                         tmp_off = llapi_mirror_data_seek(fd, src, pos,
3276                                                          &data_size);
3277                         if (tmp_off < 0) {
3278                                 /* switch to full copy */
3279                                 to_read = mirror_end - pos;
3280                                 goto do_read;
3281                         }
3282                         data_off = tmp_off;
3283                         data_end = data_off + data_size;
3284
3285                         data_off = MIN(data_off, mirror_end);
3286                         data_end = MIN(data_end, mirror_end);
3287
3288                         /* align by page, if there is data block to copy */
3289                         if (data_size)
3290                                 data_off &= ~(page_size - 1);
3291                 }
3292
3293                 if (pos < data_off) {
3294                         for (i = 0; i < comp_size; i++) {
3295                                 uint64_t cur_pos;
3296                                 size_t to_punch;
3297                                 uint32_t mid = comp_array[i].lrc_mirror_id;
3298
3299                                 /* skip non-overlapped component */
3300                                 if (pos >= comp_array[i].lrc_end ||
3301                                     data_off <= comp_array[i].lrc_start)
3302                                         continue;
3303
3304                                 if (pos < comp_array[i].lrc_start)
3305                                         cur_pos = comp_array[i].lrc_start;
3306                                 else
3307                                         cur_pos = pos;
3308
3309                                 if (data_off > comp_array[i].lrc_end)
3310                                         to_punch = comp_array[i].lrc_end -
3311                                                    cur_pos;
3312                                 else
3313                                         to_punch = data_off - cur_pos;
3314
3315                                 if (comp_array[i].lrc_end == OBD_OBJECT_EOF)
3316                                         /* the last component can be truncated
3317                                          * safely
3318                                          */
3319                                         rc = llapi_mirror_truncate(fd, mid,
3320                                                                    cur_pos);
3321                                 else if (to_punch)
3322                                         rc = llapi_mirror_punch(fd, mid,
3323                                                         cur_pos, to_punch);
3324                                 /**
3325                                  * hole at the end of file, so just truncate up
3326                                  * to set size.
3327                                  */
3328                                 if (!rc && data_off == data_end && !data_size)
3329                                         rc = llapi_mirror_truncate(fd,
3330                                                                 mid, data_end);
3331                                 /* if failed then read failed hole range */
3332                                 if (rc < 0) {
3333                                         rc = 0;
3334                                         pos = cur_pos;
3335                                         if (pos + to_punch == data_off)
3336                                                 to_read = data_end - pos;
3337                                         else
3338                                                 to_read = to_punch;
3339                                         goto do_read;
3340                                 }
3341                         }
3342                         pos = data_off;
3343                 }
3344                 if (pos == mirror_end)
3345                         continue;
3346                 to_read = data_end - pos;
3347 do_read:
3348                 if (!to_read)
3349                         break;
3350
3351                 assert(data_end <= mirror_end);
3352
3353                 to_read = MIN(buflen, to_read);
3354                 to_read = ((to_read - 1) | (page_size - 1)) + 1;
3355                 bytes_read = llapi_mirror_read(fd, src, buf, to_read, pos);
3356                 if (bytes_read == 0) {
3357                         /* end of file */
3358                         break;
3359                 }
3360                 if (bytes_read < 0) {
3361                         rc = bytes_read;
3362                         break;
3363                 }
3364                 total_bytes_read += bytes_read;
3365
3366                 /* round up to page align to make direct IO happy. */
3367                 to_write = ((bytes_read - 1) | (page_size - 1)) + 1;
3368
3369                 for (i = 0; i < comp_size; i++) {
3370                         unsigned long long write_target;
3371                         struct timespec diff;
3372                         ssize_t written;
3373                         off_t pos2 = pos;
3374                         size_t to_write2 = to_write;
3375
3376                         /* skip non-overlapped component */
3377                         if (pos >= comp_array[i].lrc_end ||
3378                             pos + to_write <= comp_array[i].lrc_start)
3379                                 continue;
3380
3381                         if (pos < comp_array[i].lrc_start)
3382                                 pos2 = comp_array[i].lrc_start;
3383
3384                         to_write2 -= pos2 - pos;
3385
3386                         if ((pos + to_write) > comp_array[i].lrc_end)
3387                                 to_write2 -= pos + to_write -
3388                                              comp_array[i].lrc_end;
3389
3390                         written = llapi_mirror_write(fd,
3391                                         comp_array[i].lrc_mirror_id,
3392                                         buf + pos2 - pos,
3393                                         to_write2, pos2);
3394                         if (written < 0) {
3395                                 /**
3396                                  * this component is not written successfully,
3397                                  * mark it using its lrc_synced, it is supposed
3398                                  * to be false before getting here.
3399                                  *
3400                                  * And before this function returns, all
3401                                  * elements of comp_array will reverse their
3402                                  * lrc_synced flag to reflect their true
3403                                  * meanings.
3404                                  */
3405                                 comp_array[i].lrc_synced = true;
3406                                 llapi_error(LLAPI_MSG_ERROR, written,
3407                                             "component %u not synced",
3408                                             comp_array[i].lrc_id);
3409                                 if (rc2 == 0)
3410                                         rc2 = (int)written;
3411                                 continue;
3412                         }
3413                         assert(written == to_write2);
3414                         total_bytes_written += written;
3415
3416                         if (bandwidth_bytes_sec == 0)
3417                                 continue;
3418
3419                         clock_gettime(CLOCK_MONOTONIC, &now);
3420                         diff = timespec_sub(&start_time, &now);
3421                         write_target = ((bandwidth_bytes_sec * diff.tv_sec) +
3422                                 ((bandwidth_bytes_sec *
3423                                 diff.tv_nsec)/NSEC_PER_SEC));
3424
3425                         if (write_target < total_bytes_written) {
3426                                 unsigned long long excess;
3427                                 struct timespec delay = { 0, 0 };
3428
3429                                 excess = total_bytes_written - write_target;
3430
3431                                 if (excess == 0)
3432                                         continue;
3433
3434                                 delay.tv_sec = excess / bandwidth_bytes_sec;
3435                                 delay.tv_nsec = (excess % bandwidth_bytes_sec) *
3436                                         NSEC_PER_SEC / bandwidth_bytes_sec;
3437
3438                                 do {
3439                                         rc = clock_nanosleep(CLOCK_MONOTONIC, 0,
3440                                                              &delay, &delay);
3441                                 } while (rc < 0 && errno == EINTR);
3442
3443                                 if (rc < 0) {
3444                                         llapi_error(LLAPI_MSG_ERROR, rc,
3445                                                 "errors: delay for bandwidth control failed: %s\n",
3446                                                 strerror(-rc));
3447                                         rc = 0;
3448                                 }
3449                         }
3450
3451                         if (stats_interval_sec) {
3452                                 clock_gettime(CLOCK_MONOTONIC, &now);
3453                                 if ((total_bytes_written != end - start) &&
3454                                      (now.tv_sec >= last_bw_print.tv_sec +
3455                                                  stats_interval_sec)) {
3456                                         stats_log(&now, &start_time,
3457                                                   total_bytes_read,
3458                                                   total_bytes_written,
3459                                                   write_estimation_bytes);
3460                                         last_bw_print = now;
3461                                 }
3462                         }
3463                 }
3464                 pos += bytes_read;
3465         }
3466
3467         free(buf);
3468
3469         if (rc < 0) {
3470                 /* fatal error happens */
3471                 for (i = 0; i < comp_size; i++)
3472                         comp_array[i].lrc_synced = false;
3473                 return rc;
3474         }
3475
3476         /* Output at least one log, regardless of stats_interval */
3477         if (stats_interval_sec) {
3478                 clock_gettime(CLOCK_MONOTONIC, &now);
3479                 stats_log(&now, &start_time, total_bytes_read,
3480                           total_bytes_written,
3481                           write_estimation_bytes);
3482         }
3483
3484         /**
3485          * no fatal error happens, each lrc_synced tells whether the component
3486          * has been resync successfully (note: we'd reverse the value to
3487          * reflect its true meaning.
3488          */
3489         for (i = 0; i < comp_size; i++) {
3490                 comp_array[i].lrc_synced = !comp_array[i].lrc_synced;
3491                 if (comp_array[i].lrc_synced && pos & (page_size - 1)) {
3492                         rc = llapi_mirror_truncate(fd,
3493                                         comp_array[i].lrc_mirror_id, pos);
3494                         /* Ignore truncate error on encrypted file without the
3495                          * key if tried on LUSTRE_ENCRYPTION_UNIT_SIZE boundary.
3496                          */
3497                         if (rc < 0 && (rc != -ENOKEY ||
3498                                        pos & ~LUSTRE_ENCRYPTION_MASK))
3499                                 comp_array[i].lrc_synced = false;
3500                 }
3501         }
3502
3503         /**
3504          * returns the first error code for partially successful resync if
3505          * possible.
3506          */
3507         return rc2;
3508 }
3509
3510 int llapi_mirror_resync_many(int fd, struct llapi_layout *layout,
3511                              struct llapi_resync_comp *comp_array,
3512                              int comp_size,  uint64_t start, uint64_t end)
3513 {
3514         return llapi_mirror_resync_many_params(fd, layout, comp_array,
3515                                                comp_size, start, end, 0, 0);
3516 }
3517
3518 enum llapi_layout_comp_sanity_error {
3519         LSE_OK,
3520         LSE_INCOMPLETE_MIRROR,
3521         LSE_ADJACENT_EXTENSION,
3522         LSE_INIT_EXTENSION,
3523         LSE_FLAGS,
3524         LSE_DOM_EXTENSION,
3525         LSE_DOM_EXTENSION_FOLLOWING,
3526         LSE_DOM_FIRST,
3527         LSE_SET_COMP_START,
3528         LSE_NOT_ZERO_LENGTH_EXTENDABLE,
3529         LSE_END_NOT_GREATER,
3530         LSE_ZERO_LENGTH_NORMAL,
3531         LSE_NOT_ADJACENT_PREV,
3532         LSE_START_GT_END,
3533         LSE_ALIGN_END,
3534         LSE_ALIGN_EXT,
3535         LSE_FOREIGN_EXTENSION,
3536         LSE_LAST,
3537 };
3538
3539 const char *const llapi_layout_strerror[] =
3540 {
3541         [LSE_OK] = "",
3542         [LSE_INCOMPLETE_MIRROR] =
3543                 "Incomplete mirror - must go to EOF",
3544         [LSE_ADJACENT_EXTENSION] =
3545                 "No adjacent extension space components",
3546         [LSE_INIT_EXTENSION] =
3547                 "Cannot apply extension flag to init components",
3548         [LSE_FLAGS] =
3549                 "Wrong flags",
3550         [LSE_DOM_EXTENSION] =
3551                 "DoM components can't be extension space",
3552         [LSE_DOM_EXTENSION_FOLLOWING] =
3553                 "DoM components cannot be followed by extension space",
3554         [LSE_DOM_FIRST] =
3555                 "DoM component should be the first one in a file/mirror",
3556         [LSE_SET_COMP_START] =
3557                 "Must set previous component extent before adding next",
3558         [LSE_NOT_ZERO_LENGTH_EXTENDABLE] =
3559                 "Extendable component must start out zero-length",
3560         [LSE_END_NOT_GREATER] =
3561                 "Component end is before end of previous component",
3562         [LSE_ZERO_LENGTH_NORMAL] =
3563                 "Zero length components must be followed by extension",
3564         [LSE_NOT_ADJACENT_PREV] =
3565                 "Components not adjacent (end != next->start",
3566         [LSE_START_GT_END] =
3567                 "Component start is > end",
3568         [LSE_ALIGN_END] =
3569                 "The component end must be aligned by the stripe size",
3570         [LSE_ALIGN_EXT] =
3571                 "The extension size must be aligned by the stripe size",
3572         [LSE_FOREIGN_EXTENSION] =
3573                 "FOREIGN components can't be extension space",
3574 };
3575
3576 struct llapi_layout_sanity_args {
3577         bool lsa_incomplete;
3578         bool lsa_flr;
3579         bool lsa_ondisk;
3580         int lsa_rc;
3581         char *fsname;
3582 };
3583
3584 /* The component flags can be set by users at creation/modification time. */
3585 #define LCME_USER_COMP_FLAGS    (LCME_FL_PREF_RW | LCME_FL_NOSYNC | \
3586                                  LCME_FL_EXTENSION)
3587
3588 /* Inline function to verify the pool name */
3589 static inline int verify_pool_name(char *fsname, struct llapi_layout *layout)
3590 {
3591         struct llapi_layout_comp *comp;
3592
3593         if (!fsname || fsname[0] == '\0')
3594                 return 0;
3595
3596         comp = __llapi_layout_cur_comp(layout);
3597         if (!comp)
3598                 return 0;
3599         if (comp->llc_pool_name[0] == '\0')
3600                 return 0;
3601         /* check if the pool name exist */
3602         if (llapi_search_ost(fsname, comp->llc_pool_name, NULL) < 0)
3603                 return -1;
3604         return 0;
3605 }
3606
3607 /**
3608  * When modified, adjust llapi_stripe_param_verify() if needed as well.
3609  */
3610 static int llapi_layout_sanity_cb(struct llapi_layout *layout,
3611                                   void *arg)
3612 {
3613         struct llapi_layout_comp *comp, *next, *prev;
3614         struct llapi_layout_sanity_args *args = arg;
3615         bool first_comp = false;
3616
3617         comp = __llapi_layout_cur_comp(layout);
3618         if (comp == NULL) {
3619                 args->lsa_rc = -1;
3620                 goto out_err;
3621         }
3622
3623         if (verify_pool_name(args->fsname, layout) != 0) {
3624                 args->lsa_rc = -1;
3625                 goto out_err;
3626         }
3627
3628         if (comp->llc_list.prev != &layout->llot_comp_list)
3629                 prev = list_last_entry(&comp->llc_list, typeof(*prev),
3630                                        llc_list);
3631         else
3632                 prev = NULL;
3633
3634         if (comp->llc_list.next != &layout->llot_comp_list)
3635                 next = list_first_entry(&comp->llc_list, typeof(*next),
3636                                         llc_list);
3637         else
3638                 next = NULL;
3639
3640         /* Start of zero implies a new mirror */
3641         if (comp->llc_extent.e_start == 0) {
3642                 first_comp = true;
3643                 /* Most checks apply only within one mirror, this is an
3644                  * exception. */
3645                 if (prev && prev->llc_extent.e_end != LUSTRE_EOF) {
3646                         args->lsa_rc = LSE_INCOMPLETE_MIRROR;
3647                         goto out_err;
3648                 }
3649
3650                 prev = NULL;
3651         }
3652
3653         if (next && next->llc_extent.e_start == 0)
3654                 next = NULL;
3655
3656         /* Flag sanity checks */
3657         /* No adjacent extension components */
3658         if ((comp->llc_flags & LCME_FL_EXTENSION) && next &&
3659             (next->llc_flags & LCME_FL_EXTENSION)) {
3660                 args->lsa_rc = LSE_ADJACENT_EXTENSION;
3661                 goto out_err;
3662         }
3663
3664         /* Extension flag cannot be applied to init components and the first
3665          * component of each mirror is automatically init */
3666         if ((comp->llc_flags & LCME_FL_EXTENSION) &&
3667             (comp->llc_flags & LCME_FL_INIT || first_comp)) {
3668                 args->lsa_rc = LSE_INIT_EXTENSION;
3669                 goto out_err;
3670         }
3671
3672         if (comp->llc_ondisk) {
3673                 if (comp->llc_flags & LCME_FL_NEG)
3674                         args->lsa_rc = LSE_FLAGS;
3675         } else if (!args->lsa_incomplete) {
3676                 if (args->lsa_flr) {
3677                         if (comp->llc_flags & ~LCME_USER_COMP_FLAGS)
3678                                 args->lsa_rc = LSE_FLAGS;
3679                 } else {
3680                         if (comp->llc_flags &
3681                             ~(LCME_FL_EXTENSION | LCME_FL_PREF_RW |
3682                               LCME_FL_NOCOMPR))
3683                                 args->lsa_rc = LSE_FLAGS;
3684                 }
3685         }
3686         if (args->lsa_rc)
3687                 goto out_err;
3688
3689         /* DoM sanity checks */
3690         if (!(comp->llc_pattern & LLAPI_LAYOUT_INVALID) &&
3691             (comp->llc_pattern & (LLAPI_LAYOUT_MDT | LOV_PATTERN_MDT))) {
3692                 /* DoM components can't be extension components */
3693                 if (comp->llc_flags & LCME_FL_EXTENSION) {
3694                         args->lsa_rc = LSE_DOM_EXTENSION;
3695                         goto out_err;
3696                 }
3697                 /* DoM components cannot be followed by an extension comp */
3698                 if (next && (next->llc_flags & LCME_FL_EXTENSION)) {
3699                         args->lsa_rc = LSE_DOM_EXTENSION_FOLLOWING;
3700                         goto out_err;
3701                 }
3702
3703                 /* DoM should be the first component in a mirror */
3704                 if (!first_comp) {
3705                         args->lsa_rc = LSE_DOM_FIRST;
3706                         errno = EINVAL;
3707                         goto out_err;
3708                 }
3709         }
3710
3711         if (comp->llc_pattern == LLAPI_LAYOUT_FOREIGN ||
3712             comp->llc_pattern == LOV_PATTERN_FOREIGN) {
3713                 /* FOREING/HSM components can't be extension components */
3714                 if (comp->llc_flags & LCME_FL_EXTENSION) {
3715                         args->lsa_rc = LSE_FOREIGN_EXTENSION;
3716                         goto out_err;
3717                 }
3718         }
3719
3720         /* Extent sanity checks */
3721         /* Must set previous component extent before adding another */
3722         if (prev && prev->llc_extent.e_start == 0 &&
3723             prev->llc_extent.e_end == 0) {
3724                 args->lsa_rc = LSE_SET_COMP_START;
3725                 goto out_err;
3726         }
3727
3728         if (!args->lsa_incomplete) {
3729                 /* Components followed by extension space (extendable
3730                  * components) must be zero length before initialization.
3731                  * (Except for first comp, which will be initialized on
3732                  * creation). */
3733                 if (next && (next->llc_flags & LCME_FL_EXTENSION) &&
3734                     !first_comp && !(comp->llc_flags & LCME_FL_INIT) &&
3735                     comp->llc_extent.e_start != comp->llc_extent.e_end) {
3736                         args->lsa_rc = LSE_NOT_ZERO_LENGTH_EXTENDABLE;
3737                         goto out_err;
3738                 }
3739
3740                 /* End must come after end of previous comp */
3741                 if (prev && comp->llc_extent.e_end < prev->llc_extent.e_end) {
3742                         args->lsa_rc = LSE_END_NOT_GREATER;
3743                         goto out_err;
3744                 }
3745
3746                 /* Components not followed by ext space must have length > 0. */
3747                 if (comp->llc_extent.e_start == comp->llc_extent.e_end &&
3748                     (next == NULL || !(next->llc_flags & LCME_FL_EXTENSION))) {
3749                         args->lsa_rc = LSE_ZERO_LENGTH_NORMAL;
3750                         goto out_err;
3751                 }
3752
3753                 /* The component end must be aligned by the stripe size */
3754                 if ((comp->llc_flags & LCME_FL_EXTENSION) &&
3755                     (prev->llc_stripe_size != LLAPI_LAYOUT_DEFAULT)) {
3756                         if (comp->llc_extent.e_end != LUSTRE_EOF &&
3757                             comp->llc_extent.e_end % prev->llc_stripe_size) {
3758                                 args->lsa_rc = LSE_ALIGN_END;
3759                                 goto out_err;
3760                         }
3761                         if ((comp->llc_stripe_size * SEL_UNIT_SIZE) %
3762                             prev->llc_stripe_size) {
3763                                 args->lsa_rc = LSE_ALIGN_EXT;
3764                                 goto out_err;
3765                         }
3766                 } else if (!(comp->llc_flags & LCME_FL_EXTENSION) &&
3767                            (comp->llc_stripe_size != LLAPI_LAYOUT_DEFAULT)) {
3768                         if (comp->llc_extent.e_end != LUSTRE_EOF &&
3769                             comp->llc_extent.e_end !=
3770                             comp->llc_extent.e_start &&
3771                             comp->llc_extent.e_end % comp->llc_stripe_size) {
3772                                 args->lsa_rc = LSE_ALIGN_END;
3773                                 goto out_err;
3774                         }
3775                 }
3776         }
3777
3778         /* Components must have start == prev->end */
3779         if (prev && comp->llc_extent.e_start != 0 &&
3780             comp->llc_extent.e_start != prev->llc_extent.e_end) {
3781                 args->lsa_rc = LSE_NOT_ADJACENT_PREV;
3782                 goto out_err;
3783         }
3784
3785         /* Components must have start <= end */
3786         if (comp->llc_extent.e_start > comp->llc_extent.e_end) {
3787                 args->lsa_rc = LSE_START_GT_END;
3788                 goto out_err;
3789         }
3790
3791         return LLAPI_LAYOUT_ITER_CONT;
3792
3793 out_err:
3794         errno = errno ? errno : EINVAL;
3795         return LLAPI_LAYOUT_ITER_STOP;
3796 }
3797
3798 /* Print explanation of layout error */
3799 void llapi_layout_sanity_perror(int error)
3800 {
3801         if (error >= LSE_LAST || error < 0) {
3802                 fprintf(stdout, "Invalid layout, unrecognized error: %d\n",
3803                         error);
3804         } else {
3805                 fprintf(stdout, "Invalid layout: %s\n",
3806                         llapi_layout_strerror[error]);
3807         }
3808 }
3809
3810 /* Walk a layout and enforce sanity checks that apply to > 1 component
3811  *
3812  * The core idea here is that of sanity checking individual tokens vs semantic
3813  * checking.
3814  * We cannot check everything at the individual component level ('token'),
3815  * instead we must check whether or not the full layout has a valid meaning.
3816  *
3817  * An example of a component level check is "is stripe size valid?".  That is
3818  * handled when setting stripe size.
3819  *
3820  * An example of a layout level check is "are the extents of these components
3821  * valid when adjacent to one another", or "can we set these flags on adjacent
3822  * components"?
3823  *
3824  * \param[in] layout            component layout list.
3825  * \param[in] fname             file the layout to be checked for
3826  * \param[in] incomplete        if layout is complete or not - some checks can
3827  *                              only be done on complete layouts.
3828  * \param[in] flr               set when this is called from FLR mirror create
3829  *
3830  * \retval                      0, success, positive: various errors, see
3831  *                              llapi_layout_sanity_perror, -1, failure
3832  */
3833
3834 int llapi_layout_sanity(struct llapi_layout *layout,
3835                         bool incomplete, bool flr)
3836 {
3837         return llapi_layout_v2_sanity(layout, incomplete, flr, NULL);
3838 }
3839
3840 /* This function has been introduced to do pool name checking
3841  * on top of llapi_layout_sanity, the file name passed in this
3842  * function is used later to verify if pool exist. The older version
3843  * of the sanity function is passing NULL for the filename
3844  * Input arguments ---
3845  * \param[in] layout            component layout list.
3846  * \param[in] fname             file the layout to be checked for
3847  * \param[in] incomplete        if layout is complete or not - some checks can
3848  *                              only be done on complete layouts.
3849  * \param[in] flr               set when this is called from FLR mirror create
3850  * \param[in] fsname            filesystem name is used to check pool name, if
3851  *                              NULL no pool name check is performed
3852  *
3853  * \retval                      0, success, positive: various errors, see
3854  */
3855
3856 int llapi_layout_v2_sanity(struct llapi_layout *layout,
3857                         bool incomplete, bool flr, char *fsname)
3858 {
3859         struct llapi_layout_sanity_args args = { 0 };
3860         struct llapi_layout_comp *curr;
3861         int rc = 0;
3862
3863         if (!layout)
3864                 return 0;
3865
3866         curr = layout->llot_cur_comp;
3867         if (!curr)
3868                 return 0;
3869
3870         /* Set up args */
3871         args.lsa_rc = 0;
3872         args.lsa_flr = flr;
3873         args.lsa_incomplete = incomplete;
3874         args.fsname = fsname;
3875
3876         /* When we modify an existing layout, this tells us if it's FLR */
3877         if (mirror_id_of(curr->llc_id) > 0)
3878                 args.lsa_flr = true;
3879
3880         errno = 0;
3881         rc = llapi_layout_comp_iterate(layout,
3882                                        llapi_layout_sanity_cb,
3883                                        &args);
3884         if (errno == ENOENT)
3885                 errno = 0;
3886
3887         if (rc != LLAPI_LAYOUT_ITER_CONT)
3888                 rc = args.lsa_rc;
3889
3890         layout->llot_cur_comp = curr;
3891
3892         return rc;
3893 }
3894
3895 int llapi_layout_dom_size(struct llapi_layout *layout, uint64_t *size)
3896 {
3897         uint64_t pattern, start;
3898         int rc;
3899
3900         if (!layout || !llapi_layout_is_composite(layout)) {
3901                 *size = 0;
3902                 return 0;
3903         }
3904
3905         rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
3906         if (rc)
3907                 return -errno;
3908
3909         rc = llapi_layout_pattern_get(layout, &pattern);
3910         if (rc)
3911                 return -errno;
3912
3913         if ((pattern & LLAPI_LAYOUT_INVALID) ||
3914             !(pattern & (LOV_PATTERN_MDT | LLAPI_LAYOUT_MDT))) {
3915                 *size = 0;
3916                 return 0;
3917         }
3918
3919         rc = llapi_layout_comp_extent_get(layout, &start, size);
3920         if (rc)
3921                 return -errno;
3922         if (start)
3923                 return -ERANGE;
3924         return 0;
3925 }
3926
3927 int lov_comp_md_size(struct lov_comp_md_v1 *lcm)
3928 {
3929         if (lcm->lcm_magic == LOV_MAGIC_V1 || lcm->lcm_magic == LOV_MAGIC_V3) {
3930                 struct lov_user_md *lum = (void *)lcm;
3931
3932                 return lov_user_md_size(lum->lmm_stripe_count, lum->lmm_magic);
3933         }
3934
3935         if (lcm->lcm_magic == LOV_MAGIC_FOREIGN) {
3936                 struct lov_foreign_md *lfm = (void *)lcm;
3937
3938                 return lfm->lfm_length;
3939         }
3940
3941         if (lcm->lcm_magic != LOV_MAGIC_COMP_V1)
3942                 return -EOPNOTSUPP;
3943
3944         return lcm->lcm_size;
3945 }
3946
3947 int llapi_get_lum_file_fd(int dir_fd, const char *fname, __u64 *valid,
3948                           lstatx_t *statx, struct lov_user_md *lum,
3949                           size_t lumsize)
3950 {
3951         struct lov_user_mds_data *lmd;
3952         char buf[65536 + offsetof(typeof(*lmd), lmd_lmm)];
3953         int parent_fd = -1;
3954         int rc;
3955
3956         if (lum && lumsize < sizeof(*lum))
3957                 return -EINVAL;
3958
3959         /* If a file name is provided, it is relative to the parent directory */
3960         if (fname) {
3961                 parent_fd = dir_fd;
3962                 dir_fd = -1;
3963         }
3964
3965         lmd = (struct lov_user_mds_data *)buf;
3966         rc = get_lmd_info_fd(fname, parent_fd, dir_fd, buf, sizeof(buf),
3967                              GET_LMD_INFO);
3968         if (rc)
3969                 return rc;
3970
3971         if (valid)
3972                 *valid = lmd->lmd_flags;
3973
3974         if (statx)
3975                 memcpy(statx, &lmd->lmd_stx, sizeof(*statx));
3976
3977         if (lum) {
3978                 if (lmd->lmd_lmmsize > lumsize)
3979                         return -EOVERFLOW;
3980                 memcpy(lum, &lmd->lmd_lmm, lmd->lmd_lmmsize);
3981         }
3982
3983         return 0;
3984 }
3985
3986 int llapi_get_lum_dir_fd(int dir_fd, __u64 *valid, lstatx_t *statx,
3987                          struct lov_user_md *lum, size_t lumsize)
3988 {
3989         return llapi_get_lum_file_fd(dir_fd, NULL, valid, statx, lum, lumsize);
3990 }
3991
3992 int llapi_get_lum_file(const char *path, __u64 *valid, lstatx_t *statx,
3993                        struct lov_user_md *lum, size_t lumsize)
3994 {
3995         char parent[PATH_MAX];
3996         const char *fname;
3997         char *tmp;
3998         int offset;
3999         int dir_fd;
4000         int rc;
4001
4002         tmp = strrchr(path, '/');
4003         if (!tmp) {
4004                 strncpy(parent, ".", sizeof(parent) - 1);
4005                 offset = -1;
4006         } else {
4007                 strncpy(parent, path, tmp - path);
4008                 offset = tmp - path - 1;
4009                 parent[tmp - path] = 0;
4010         }
4011
4012         fname = path;
4013         if (offset >= 0)
4014                 fname += offset + 2;
4015
4016         dir_fd = open(parent, O_RDONLY);
4017         if (dir_fd < 0) {
4018                 rc = -errno;
4019                 llapi_error(LLAPI_MSG_ERROR, rc, "cannot open '%s'", path);
4020                 return rc;
4021         }
4022
4023         rc = llapi_get_lum_file_fd(dir_fd, fname, valid, statx, lum, lumsize);
4024         close(dir_fd);
4025         return rc;
4026 }
4027
4028 int llapi_get_lum_dir(const char *path, __u64 *valid, lstatx_t *statx,
4029                       struct lov_user_md *lum, size_t lumsize)
4030 {
4031         int dir_fd;
4032         int rc;
4033
4034         dir_fd = open(path, O_RDONLY);
4035         if (dir_fd < 0) {
4036                 rc = -errno;
4037                 llapi_error(LLAPI_MSG_ERROR, rc, "cannot open '%s'", path);
4038                 return rc;
4039         }
4040
4041         rc = llapi_get_lum_dir_fd(dir_fd, valid, statx, lum, lumsize);
4042         close(dir_fd);
4043         return rc;
4044 }