Whamcloud - gitweb
LU-8901 misc: update Intel copyright messages for 2016
[fs/lustre-release.git] / lustre / utils / liblustreapi_layout.c
1 /*
2  * LGPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * All rights reserved. This program and the accompanying materials
7  * are made available under the terms of the GNU Lesser General Public License
8  * (LGPL) version 2.1 or (at your discretion) any later version.
9  * (LGPL) version 2.1 accompanies this distribution, and is available at
10  * http://www.gnu.org/licenses/lgpl-2.1.html
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * LGPL HEADER END
18  */
19 /*
20  * lustre/utils/liblustreapi_layout.c
21  *
22  * lustreapi library for layout calls for interacting with the layout of
23  * Lustre files while hiding details of the internal data structures
24  * from the user.
25  *
26  * Copyright (c) 2016, Intel Corporation.
27  *
28  * Author: Ned Bass <bass6@llnl.gov>
29  */
30
31 #include <stdio.h>
32 #include <fcntl.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <errno.h>
36 #include <limits.h>
37 #include <sys/xattr.h>
38
39 #include <lustre/lustreapi.h>
40 #include <lustre/lustre_idl.h>
41 #include "lustreapi_internal.h"
42
43 /**
44  * An Opaque data type abstracting the layout of a Lustre file.
45  *
46  * Duplicate the fields we care about from struct lov_user_md_v3.
47  * Deal with v1 versus v3 format issues only when we read or write
48  * files.
49  */
50 struct llapi_layout {
51         uint32_t        llot_magic;
52         uint64_t        llot_pattern;
53         uint64_t        llot_stripe_size;
54         uint64_t        llot_stripe_count;
55         uint64_t        llot_stripe_offset;
56         /* Add 1 so user always gets back a null terminated string. */
57         char            llot_pool_name[LOV_MAXPOOLNAME + 1];
58         /** Number of objects in llot_objects array if was initialized. */
59         uint32_t        llot_objects_count;
60         struct          lov_user_ost_data_v1 *llot_objects;
61 };
62
63 /**
64  * Byte-swap the fields of struct lov_user_md.
65  *
66  * XXX Rather than duplicating swabbing code here, we should eventually
67  * refactor the needed functions in lustre/ptlrpc/pack_generic.c
68  * into a library that can be shared between kernel and user code.
69  */
70 static void
71 llapi_layout_swab_lov_user_md(struct lov_user_md *lum, int object_count)
72 {
73         int i;
74         struct lov_user_md_v3 *lumv3 = (struct lov_user_md_v3 *)lum;
75         struct lov_user_ost_data *lod;
76
77         __swab32s(&lum->lmm_magic);
78         __swab32s(&lum->lmm_pattern);
79         __swab32s(&lum->lmm_stripe_size);
80         __swab16s(&lum->lmm_stripe_count);
81         __swab16s(&lum->lmm_stripe_offset);
82
83         if (lum->lmm_magic != LOV_MAGIC_V1)
84                 lod = lumv3->lmm_objects;
85         else
86                 lod = lum->lmm_objects;
87
88         for (i = 0; i < object_count; i++)
89                 __swab32s(&lod[i].l_ost_idx);
90 }
91
92 /**
93  * (Re-)allocate llot_objects[] to \a num_stripes stripes.
94  *
95  * Copy over existing llot_objects[], if any, to the new llot_objects[].
96  *
97  * \param[in] layout            existing layout to be modified
98  * \param[in] num_stripes       number of stripes in new layout
99  *
100  * \retval      0 if the objects are re-allocated successfully
101  * \retval      -1 on error with errno set
102  */
103 static int __llapi_layout_objects_realloc(struct llapi_layout *layout,
104                                           unsigned int new_stripes)
105 {
106         struct lov_user_ost_data_v1 *new_objects;
107         unsigned int i;
108
109         if (new_stripes > LOV_MAX_STRIPE_COUNT) {
110                 errno = EINVAL;
111                 return -1;
112         }
113
114         if (new_stripes == 0 && layout->llot_objects_count == 0)
115                 return 0;
116
117         if (new_stripes != 0 && new_stripes <= layout->llot_objects_count)
118                 return 0;
119
120         new_objects = realloc(layout->llot_objects,
121                               sizeof(*new_objects) * new_stripes);
122         if (new_objects == NULL && new_stripes != 0) {
123                 errno = ENOMEM;
124                 return -1;
125         }
126
127         for (i = layout->llot_objects_count; i < new_stripes; i++)
128                 new_objects[i].l_ost_idx = LLAPI_LAYOUT_IDX_MAX;
129
130         if (new_stripes == 0)
131                 layout->llot_objects = NULL;
132         else
133                 layout->llot_objects = new_objects;
134         layout->llot_objects_count = new_stripes;
135
136         return 0;
137 }
138
139 /**
140  * Allocate storage for a llapi_layout with \a num_stripes stripes.
141  *
142  * \param[in] num_stripes       number of stripes in new layout
143  *
144  * \retval      valid pointer if allocation succeeds
145  * \retval      NULL if allocation fails
146  */
147 static struct llapi_layout *__llapi_layout_alloc(unsigned int num_stripes)
148 {
149         struct llapi_layout *layout;
150
151         if (num_stripes > LOV_MAX_STRIPE_COUNT) {
152                 errno = EINVAL;
153                 return NULL;
154         }
155
156         layout = calloc(1, sizeof(*layout));
157         if (layout == NULL) {
158                 errno = ENOMEM;
159                 return NULL;
160         }
161
162         layout->llot_objects = NULL;
163         layout->llot_objects_count = 0;
164
165         if (__llapi_layout_objects_realloc(layout, num_stripes) < 0) {
166                 free(layout);
167                 layout = NULL;
168         }
169
170         return layout;
171 }
172
173 /**
174  * Copy the data from a lov_user_md to a newly allocated llapi_layout.
175  *
176  * The caller is responsible for freeing the returned pointer.
177  *
178  * \param[in] lum       LOV user metadata structure to copy data from
179  *
180  * \retval              valid llapi_layout pointer on success
181  * \retval              NULL if memory allocation fails
182  */
183 static struct llapi_layout *
184 llapi_layout_from_lum(const struct lov_user_md *lum, size_t object_count)
185 {
186         struct llapi_layout *layout;
187         size_t objects_sz;
188
189         objects_sz = object_count * sizeof(lum->lmm_objects[0]);
190
191         layout = __llapi_layout_alloc(object_count);
192         if (layout == NULL)
193                 return NULL;
194
195         layout->llot_magic = LLAPI_LAYOUT_MAGIC;
196
197         if (lum->lmm_pattern == LOV_PATTERN_RAID0)
198                 layout->llot_pattern = LLAPI_LAYOUT_RAID0;
199         else
200                 /* Lustre only supports RAID0 for now. */
201                 layout->llot_pattern = lum->lmm_pattern;
202
203         if (lum->lmm_stripe_size == 0)
204                 layout->llot_stripe_size = LLAPI_LAYOUT_DEFAULT;
205         else
206                 layout->llot_stripe_size = lum->lmm_stripe_size;
207
208         if (lum->lmm_stripe_count == (typeof(lum->lmm_stripe_count))-1)
209                 layout->llot_stripe_count = LLAPI_LAYOUT_WIDE;
210         else if (lum->lmm_stripe_count == 0)
211                 layout->llot_stripe_count = LLAPI_LAYOUT_DEFAULT;
212         else
213                 layout->llot_stripe_count = lum->lmm_stripe_count;
214
215         if (lum->lmm_stripe_offset == (typeof(lum->lmm_stripe_offset))-1)
216                 layout->llot_stripe_offset = LLAPI_LAYOUT_DEFAULT;
217         else
218                 layout->llot_stripe_offset = lum->lmm_stripe_offset;
219
220         if (lum->lmm_magic != LOV_USER_MAGIC_V1) {
221                 const struct lov_user_md_v3 *lumv3;
222                 lumv3 = (struct lov_user_md_v3 *)lum;
223                 snprintf(layout->llot_pool_name, sizeof(layout->llot_pool_name),
224                          "%s", lumv3->lmm_pool_name);
225                 memcpy(layout->llot_objects, lumv3->lmm_objects, objects_sz);
226         } else {
227                 const struct lov_user_md_v1 *lumv1;
228                 lumv1 = (struct lov_user_md_v1 *)lum;
229                 memcpy(layout->llot_objects, lumv1->lmm_objects, objects_sz);
230         }
231
232         if (object_count != 0)
233                 layout->llot_stripe_offset = layout->llot_objects[0].l_ost_idx;
234
235         return layout;
236 }
237
238 /**
239  * Copy the data from a llapi_layout to a newly allocated lov_user_md.
240  *
241  * The caller is responsible for freeing the returned pointer.
242  *
243  * The current version of this API doesn't support specifying the OST
244  * index of arbitrary stripes, only stripe 0 via lmm_stripe_offset.
245  * There is therefore no need to copy the lmm_objects array.
246  *
247  * \param[in] layout    the layout to copy from
248  *
249  * \retval      valid lov_user_md pointer on success
250  * \retval      NULL if memory allocation fails or the layout is invalid
251  */
252 static struct lov_user_md *
253 llapi_layout_to_lum(const struct llapi_layout *layout)
254 {
255         struct lov_user_md *lum;
256         size_t lum_size;
257         uint32_t magic = LOV_USER_MAGIC_V1;
258         uint64_t pattern = layout->llot_pattern;
259         struct lov_user_ost_data *lmm_objects;
260         int obj_count = 0, i;
261
262         if ((pattern & LLAPI_LAYOUT_SPECIFIC) != 0) {
263                 if (layout->llot_objects_count < layout->llot_stripe_count) {
264                         errno = EINVAL;
265                         return NULL;
266                 }
267                 magic = LOV_USER_MAGIC_SPECIFIC;
268                 obj_count = layout->llot_stripe_count;
269                 pattern &= ~LLAPI_LAYOUT_SPECIFIC;
270         } else if (strlen(layout->llot_pool_name) != 0) {
271                 magic = LOV_USER_MAGIC_V3;
272         }
273
274         /*
275          * All stripes must be specified when the pattern contains
276          * LLAPI_LAYOUT_SPECIFIC
277          */
278         for (i = 0; i < obj_count; i++) {
279                 if (layout->llot_objects[i].l_ost_idx ==
280                     LLAPI_LAYOUT_IDX_MAX) {
281                         errno = EINVAL;
282                         return NULL;
283                 }
284         }
285
286         lum_size = lov_user_md_size(obj_count, magic);
287         lum = malloc(lum_size);
288         if (lum == NULL)
289                 return NULL;
290
291         lum->lmm_magic = magic;
292
293         if (pattern == LLAPI_LAYOUT_DEFAULT)
294                 lum->lmm_pattern = 0;
295         else if (pattern == LLAPI_LAYOUT_RAID0)
296                 lum->lmm_pattern = LOV_PATTERN_RAID0;
297         else
298                 lum->lmm_pattern = pattern;
299
300         if (layout->llot_stripe_size == LLAPI_LAYOUT_DEFAULT)
301                 lum->lmm_stripe_size = 0;
302         else
303                 lum->lmm_stripe_size = layout->llot_stripe_size;
304
305         if (layout->llot_stripe_count == LLAPI_LAYOUT_DEFAULT)
306                 lum->lmm_stripe_count = 0;
307         else if (layout->llot_stripe_count == LLAPI_LAYOUT_WIDE)
308                 lum->lmm_stripe_count = LOV_ALL_STRIPES;
309         else
310                 lum->lmm_stripe_count = layout->llot_stripe_count;
311
312         if (layout->llot_stripe_offset == LLAPI_LAYOUT_DEFAULT)
313                 lum->lmm_stripe_offset = -1;
314         else
315                 lum->lmm_stripe_offset = layout->llot_stripe_offset;
316
317         if (magic == LOV_USER_MAGIC_V3 || magic == LOV_USER_MAGIC_SPECIFIC) {
318                 struct lov_user_md_v3 *lumv3 = (struct lov_user_md_v3 *)lum;
319
320                 if (strlen(layout->llot_pool_name)) {
321                         strncpy(lumv3->lmm_pool_name, layout->llot_pool_name,
322                                 sizeof(lumv3->lmm_pool_name));
323                 } else {
324                         memset(lumv3->lmm_pool_name, 0, LOV_MAXPOOLNAME);
325                 }
326                 lmm_objects = lumv3->lmm_objects;
327         } else {
328                 lmm_objects = lum->lmm_objects;
329         }
330
331         for (i = 0; i < obj_count; i++)
332                 lmm_objects[i].l_ost_idx = layout->llot_objects[i].l_ost_idx;
333
334         return lum;
335 }
336
337 /**
338  * Get the parent directory of a path.
339  *
340  * \param[in] path      path to get parent of
341  * \param[out] buf      buffer in which to store parent path
342  * \param[in] size      size in bytes of buffer \a buf
343  */
344 static void get_parent_dir(const char *path, char *buf, size_t size)
345 {
346         char *p;
347
348         strncpy(buf, path, size);
349         p = strrchr(buf, '/');
350
351         if (p != NULL)
352                 *p = '\0';
353         else if (size >= 2)
354                 strncpy(buf, ".", 2);
355 }
356
357 /**
358  * Substitute unspecified attribute values in \a dest with
359  * values from \a src.
360  *
361  * \param[in] src       layout to inherit values from
362  * \param[in] dest      layout to receive inherited values
363  */
364 static void inherit_layout_attributes(const struct llapi_layout *src,
365                                         struct llapi_layout *dest)
366 {
367         if (dest->llot_pattern == LLAPI_LAYOUT_DEFAULT)
368                 dest->llot_pattern = src->llot_pattern;
369
370         if (dest->llot_stripe_size == LLAPI_LAYOUT_DEFAULT)
371                 dest->llot_stripe_size = src->llot_stripe_size;
372
373         if (dest->llot_stripe_count == LLAPI_LAYOUT_DEFAULT)
374                 dest->llot_stripe_count = src->llot_stripe_count;
375
376         if (dest->llot_stripe_offset == LLAPI_LAYOUT_DEFAULT)
377                 dest->llot_stripe_offset = src->llot_stripe_offset;
378 }
379
380 /**
381  * Test if all attributes of \a layout are specified.
382  *
383  * \param[in] layout    the layout to check
384  *
385  * \retval true         all attributes are specified
386  * \retval false        at least one attribute is unspecified
387  */
388 static bool is_fully_specified(const struct llapi_layout *layout)
389 {
390         return  layout->llot_pattern != LLAPI_LAYOUT_DEFAULT &&
391                 layout->llot_stripe_size != LLAPI_LAYOUT_DEFAULT &&
392                 layout->llot_stripe_count != LLAPI_LAYOUT_DEFAULT;
393 }
394
395 /**
396  * Allocate and initialize a new layout.
397  *
398  * \retval      valid llapi_layout pointer on success
399  * \retval      NULL if memory allocation fails
400  */
401 struct llapi_layout *llapi_layout_alloc(void)
402 {
403         struct llapi_layout *layout;
404
405         layout = __llapi_layout_alloc(0);
406         if (layout == NULL)
407                 return layout;
408
409         /* Set defaults. */
410         layout->llot_magic = LLAPI_LAYOUT_MAGIC;
411         layout->llot_pattern = LLAPI_LAYOUT_DEFAULT;
412         layout->llot_stripe_size = LLAPI_LAYOUT_DEFAULT;
413         layout->llot_stripe_count = LLAPI_LAYOUT_DEFAULT;
414         layout->llot_stripe_offset = LLAPI_LAYOUT_DEFAULT;
415         layout->llot_pool_name[0] = '\0';
416
417         return layout;
418 }
419
420 /**
421  * Check if the given \a lum_size is large enough to hold the required
422  * fields in \a lum.
423  *
424  * \param[in] lum       the struct lov_user_md to check
425  * \param[in] lum_size  the number of bytes in \a lum
426  *
427  * \retval true         the \a lum_size is too small
428  * \retval false        the \a lum_size is large enough
429  */
430 static bool llapi_layout_lum_truncated(struct lov_user_md *lum, size_t lum_size)
431 {
432         uint32_t magic;
433
434         if (lum_size < lov_user_md_size(0, LOV_MAGIC_V1))
435                 return false;
436
437         if (lum->lmm_magic == __swab32(LOV_MAGIC_V1) ||
438             lum->lmm_magic == __swab32(LOV_MAGIC_V3))
439                 magic = __swab32(lum->lmm_magic);
440         else
441                 magic = lum->lmm_magic;
442
443         return lum_size < lov_user_md_size(0, magic);
444 }
445
446 /**
447  * Compute the number of elements in the lmm_objects array of \a lum
448  * with size \a lum_size.
449  *
450  * \param[in] lum       the struct lov_user_md to check
451  * \param[in] lum_size  the number of bytes in \a lum
452  *
453  * \retval              number of elements in array lum->lmm_objects
454  */
455 static int llapi_layout_objects_in_lum(struct lov_user_md *lum, size_t lum_size)
456 {
457         uint32_t magic;
458         size_t base_size;
459
460         if (lum_size < lov_user_md_size(0, LOV_MAGIC_V1))
461                 return 0;
462
463         if (lum->lmm_magic == __swab32(LOV_MAGIC_V1) ||
464             lum->lmm_magic == __swab32(LOV_MAGIC_V3))
465                 magic = __swab32(lum->lmm_magic);
466         else
467                 magic = lum->lmm_magic;
468
469         base_size = lov_user_md_size(0, magic);
470
471         if (lum_size <= base_size)
472                 return 0;
473         else
474                 return (lum_size - base_size) / sizeof(lum->lmm_objects[0]);
475 }
476
477 /**
478  * Get the striping layout for the file referenced by file descriptor \a fd.
479  *
480  * If the filesystem does not support the "lustre." xattr namespace, the
481  * file must be on a non-Lustre filesystem, so set errno to ENOTTY per
482  * convention.  If the file has no "lustre.lov" data, the file will
483  * inherit default values, so return a default layout.
484  *
485  * If the kernel gives us back less than the expected amount of data,
486  * we fail with errno set to EINTR.
487  *
488  * \param[in] fd        open file descriptor
489  * \param[in] flags     open file descriptor
490  *
491  * \retval      valid llapi_layout pointer on success
492  * \retval      NULL if an error occurs
493  */
494 struct llapi_layout *llapi_layout_get_by_fd(int fd, uint32_t flags)
495 {
496         size_t lum_len;
497         struct lov_user_md *lum;
498         struct llapi_layout *layout = NULL;
499         ssize_t bytes_read;
500         int object_count;
501         int lum_stripe_count;
502         struct stat st;
503         bool need_swab;
504
505         lum_len = XATTR_SIZE_MAX;
506         lum = malloc(lum_len);
507         if (lum == NULL)
508                 return NULL;
509
510         bytes_read = fgetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_len);
511         if (bytes_read < 0) {
512                 if (errno == EOPNOTSUPP)
513                         errno = ENOTTY;
514                 else if (errno == ENODATA)
515                         layout = llapi_layout_alloc();
516                 goto out;
517         }
518
519         /* Return an error if we got back a partial layout. */
520         if (llapi_layout_lum_truncated(lum, bytes_read)) {
521                 errno = EINTR;
522                 goto out;
523         }
524
525         object_count = llapi_layout_objects_in_lum(lum, bytes_read);
526
527         need_swab = lum->lmm_magic == __swab32(LOV_MAGIC_V1) ||
528                     lum->lmm_magic == __swab32(LOV_MAGIC_V3);
529
530         if (need_swab)
531                 lum_stripe_count = __swab16(lum->lmm_stripe_count);
532         else
533                 lum_stripe_count = lum->lmm_stripe_count;
534
535         /* Directories may have a positive non-zero lum->lmm_stripe_count
536          * yet have an empty lum->lmm_objects array. For non-directories the
537          * amount of data returned from the kernel must be consistent
538          * with the stripe count. */
539         if (fstat(fd, &st) < 0)
540                 goto out;
541
542         if (!S_ISDIR(st.st_mode) && object_count != lum_stripe_count) {
543                 errno = EINTR;
544                 goto out;
545         }
546
547         if (need_swab)
548                 llapi_layout_swab_lov_user_md(lum, object_count);
549
550         layout = llapi_layout_from_lum(lum, object_count);
551
552 out:
553         free(lum);
554         return layout;
555 }
556
557 /**
558  * Get the expected striping layout for a file at \a path.
559  *
560  * Substitute expected inherited attribute values for unspecified
561  * attributes.  Unspecified attributes may belong to directories and
562  * never-written-to files, and indicate that default values will be
563  * assigned when files are created or first written to.  A default value
564  * is inherited from the parent directory if the attribute is specified
565  * there, otherwise it is inherited from the filesystem root.
566  * Unspecified attributes normally have the value LLAPI_LAYOUT_DEFAULT.
567  *
568  * The complete \a path need not refer to an existing file or directory,
569  * but some leading portion of it must reside within a lustre filesystem.
570  * A use case for this interface would be to obtain the literal striping
571  * values that would be assigned to a new file in a given directory.
572  *
573  * \param[in] path      path for which to get the expected layout
574  *
575  * \retval      valid llapi_layout pointer on success
576  * \retval      NULL if an error occurs
577  */
578 static struct llapi_layout *llapi_layout_expected(const char *path)
579 {
580         struct llapi_layout     *path_layout = NULL;
581         struct llapi_layout     *donor_layout;
582         char                    donor_path[PATH_MAX];
583         struct stat st;
584         int fd;
585         int rc;
586
587         fd = open(path, O_RDONLY);
588         if (fd < 0 && errno != ENOENT)
589                 return NULL;
590
591         if (fd >= 0) {
592                 int tmp;
593
594                 path_layout = llapi_layout_get_by_fd(fd, 0);
595                 tmp = errno;
596                 close(fd);
597                 errno = tmp;
598         }
599
600         if (path_layout == NULL) {
601                 if (errno != ENODATA && errno != ENOENT)
602                         return NULL;
603
604                 path_layout = llapi_layout_alloc();
605                 if (path_layout == NULL)
606                         return NULL;
607         }
608
609         if (is_fully_specified(path_layout))
610                 return path_layout;
611
612         rc = stat(path, &st);
613         if (rc < 0 && errno != ENOENT) {
614                 llapi_layout_free(path_layout);
615                 return NULL;
616         }
617
618         /* If path is a not a directory or doesn't exist, inherit unspecified
619          * attributes from parent directory. */
620         if ((rc == 0 && !S_ISDIR(st.st_mode)) ||
621             (rc < 0 && errno == ENOENT)) {
622                 get_parent_dir(path, donor_path, sizeof(donor_path));
623                 donor_layout = llapi_layout_get_by_path(donor_path, 0);
624                 if (donor_layout != NULL) {
625                         inherit_layout_attributes(donor_layout, path_layout);
626                         llapi_layout_free(donor_layout);
627                         if (is_fully_specified(path_layout))
628                                 return path_layout;
629                 }
630         }
631
632         /* Inherit remaining unspecified attributes from the filesystem root. */
633         rc = llapi_search_mounts(path, 0, donor_path, NULL);
634         if (rc < 0) {
635                 llapi_layout_free(path_layout);
636                 return NULL;
637         }
638         donor_layout = llapi_layout_get_by_path(donor_path, 0);
639         if (donor_layout == NULL) {
640                 llapi_layout_free(path_layout);
641                 return NULL;
642         }
643
644         inherit_layout_attributes(donor_layout, path_layout);
645         llapi_layout_free(donor_layout);
646
647         return path_layout;
648 }
649
650 /**
651  * Get the striping layout for the file at \a path.
652  *
653  * If \a flags contains LAYOUT_GET_EXPECTED, substitute
654  * expected inherited attribute values for unspecified attributes. See
655  * llapi_layout_expected().
656  *
657  * \param[in] path      path for which to get the layout
658  * \param[in] flags     flags to control how layout is retrieved
659  *
660  * \retval      valid llapi_layout pointer on success
661  * \retval      NULL if an error occurs
662  */
663 struct llapi_layout *llapi_layout_get_by_path(const char *path, uint32_t flags)
664 {
665         struct llapi_layout *layout = NULL;
666         int fd;
667         int tmp;
668
669         if (flags & LAYOUT_GET_EXPECTED)
670                 return llapi_layout_expected(path);
671
672         fd = open(path, O_RDONLY);
673         if (fd < 0)
674                 return layout;
675
676         layout = llapi_layout_get_by_fd(fd, flags);
677         tmp = errno;
678         close(fd);
679         errno = tmp;
680
681         return layout;
682 }
683
684 /**
685  * Get the layout for the file with FID \a fidstr in filesystem \a lustre_dir.
686  *
687  * \param[in] lustre_dir        path within Lustre filesystem containing \a fid
688  * \param[in] fid               Lustre identifier of file to get layout for
689  *
690  * \retval      valid llapi_layout pointer on success
691  * \retval      NULL if an error occurs
692  */
693 struct llapi_layout *llapi_layout_get_by_fid(const char *lustre_dir,
694                                              const lustre_fid *fid,
695                                              uint32_t flags)
696 {
697         int fd;
698         int tmp;
699         int saved_msg_level = llapi_msg_get_level();
700         struct llapi_layout *layout = NULL;
701
702         /* Prevent llapi internal routines from writing to console
703          * while executing this function, then restore previous message
704          * level. */
705         llapi_msg_set_level(LLAPI_MSG_OFF);
706         fd = llapi_open_by_fid(lustre_dir, fid, O_RDONLY);
707         llapi_msg_set_level(saved_msg_level);
708
709         if (fd < 0)
710                 return NULL;
711
712         layout = llapi_layout_get_by_fd(fd, flags);
713         tmp = errno;
714         close(fd);
715         errno = tmp;
716
717         return layout;
718 }
719
720 /**
721  * Free memory allocated for \a layout.
722  *
723  * \param[in] layout    previously allocated by llapi_layout_alloc()
724  */
725 void llapi_layout_free(struct llapi_layout *layout)
726 {
727         if (layout->llot_objects != NULL)
728                 free(layout->llot_objects);
729         free(layout);
730 }
731
732 /**
733  * Get the stripe count of \a layout.
734  *
735  * \param[in] layout    layout to get stripe count from
736  * \param[out] count    integer to store stripe count in
737  *
738  * \retval      0 on success
739  * \retval      -1 if arguments are invalid
740  */
741 int llapi_layout_stripe_count_get(const struct llapi_layout *layout,
742                                   uint64_t *count)
743 {
744         if (layout == NULL || count == NULL ||
745             layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
746                 errno = EINVAL;
747                 return -1;
748         }
749         *count = layout->llot_stripe_count;
750         return 0;
751 }
752
753 /*
754  * The llapi_layout API functions have these extra validity checks since
755  * they use intuitively named macros to denote special behavior, whereas
756  * the old API uses 0 and -1.
757  */
758
759 static bool llapi_layout_stripe_count_is_valid(int64_t stripe_count)
760 {
761         return stripe_count == LLAPI_LAYOUT_DEFAULT ||
762                 stripe_count == LLAPI_LAYOUT_WIDE ||
763                 (stripe_count != 0 && stripe_count != -1 &&
764                  llapi_stripe_count_is_valid(stripe_count));
765 }
766
767 static bool llapi_layout_stripe_size_is_valid(uint64_t stripe_size)
768 {
769         return stripe_size == LLAPI_LAYOUT_DEFAULT ||
770                 (stripe_size != 0 &&
771                  llapi_stripe_size_is_aligned(stripe_size) &&
772                  !llapi_stripe_size_is_too_big(stripe_size));
773 }
774
775 static bool llapi_layout_stripe_index_is_valid(int64_t stripe_index)
776 {
777         return stripe_index == LLAPI_LAYOUT_DEFAULT ||
778                 (stripe_index >= 0 &&
779                 llapi_stripe_index_is_valid(stripe_index));
780 }
781
782 /**
783  * Set the stripe count of \a layout.
784  *
785  * \param[in] layout    layout to set stripe count in
786  * \param[in] count     value to be set
787  *
788  * \retval      0 on success
789  * \retval      -1 if arguments are invalid
790  */
791 int llapi_layout_stripe_count_set(struct llapi_layout *layout,
792                                   uint64_t count)
793 {
794         if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC ||
795             !llapi_layout_stripe_count_is_valid(count)) {
796                 errno = EINVAL;
797                 return -1;
798         }
799
800         layout->llot_stripe_count = count;
801
802         return 0;
803 }
804
805 /**
806  * Get the stripe size of \a layout.
807  *
808  * \param[in] layout    layout to get stripe size from
809  * \param[out] size     integer to store stripe size in
810  *
811  * \retval      0 on success
812  * \retval      -1 if arguments are invalid
813  */
814 int llapi_layout_stripe_size_get(const struct llapi_layout *layout,
815                                  uint64_t *size)
816 {
817         if (layout == NULL || size == NULL ||
818             layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
819                 errno = EINVAL;
820                 return -1;
821         }
822
823         *size = layout->llot_stripe_size;
824
825         return 0;
826 }
827
828 /**
829  * Set the stripe size of \a layout.
830  *
831  * \param[in] layout    layout to set stripe size in
832  * \param[in] size      value to be set
833  *
834  * \retval      0 on success
835  * \retval      -1 if arguments are invalid
836  */
837 int llapi_layout_stripe_size_set(struct llapi_layout *layout,
838                                  uint64_t size)
839 {
840         if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC ||
841             !llapi_layout_stripe_size_is_valid(size)) {
842                 errno = EINVAL;
843                 return -1;
844         }
845
846         layout->llot_stripe_size = size;
847
848         return 0;
849 }
850
851 /**
852  * Get the RAID pattern of \a layout.
853  *
854  * \param[in] layout    layout to get pattern from
855  * \param[out] pattern  integer to store pattern in
856  *
857  * \retval      0 on success
858  * \retval      -1 if arguments are invalid
859  */
860 int llapi_layout_pattern_get(const struct llapi_layout *layout,
861                              uint64_t *pattern)
862 {
863         if (layout == NULL || pattern == NULL ||
864             layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
865                 errno = EINVAL;
866                 return -1;
867         }
868
869         *pattern = layout->llot_pattern;
870
871         return 0;
872 }
873
874 /**
875  * Set the RAID pattern of \a layout.
876  *
877  * \param[in] layout    layout to set pattern in
878  * \param[in] pattern   value to be set
879  *
880  * \retval      0 on success
881  * \retval      -1 if arguments are invalid or RAID pattern
882  *              is unsupported
883  */
884 int llapi_layout_pattern_set(struct llapi_layout *layout, uint64_t pattern)
885 {
886         if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
887                 errno = EINVAL;
888                 return -1;
889         }
890
891         if (pattern != LLAPI_LAYOUT_DEFAULT &&
892             pattern != LLAPI_LAYOUT_RAID0) {
893                 errno = EOPNOTSUPP;
894                 return -1;
895         }
896
897         layout->llot_pattern = pattern |
898                                 (layout->llot_pattern & LLAPI_LAYOUT_SPECIFIC);
899
900         return 0;
901 }
902
903 static inline int stripe_number_roundup(int stripe_number)
904 {
905         unsigned int round_up = (stripe_number + 8) & ~7;
906         return round_up > LOV_MAX_STRIPE_COUNT ?
907                 LOV_MAX_STRIPE_COUNT : round_up;
908 }
909
910 /**
911  * Set the OST index of stripe number \a stripe_number to \a ost_index.
912  *
913  * If only the starting stripe's OST index is specified, then this can use
914  * the normal LOV_MAGIC_{V1,V3} layout type.  If multiple OST indices are
915  * given, then allocate an array to hold the list of indices and ensure that
916  * the LOV_USER_MAGIC_SPECIFIC layout is used when creating the file.
917  *
918  * \param[in] layout            layout to set OST index in
919  * \param[in] stripe_number     stripe number to set index for
920  * \param[in] ost_index         the index to set
921  *
922  * \retval      0 on success
923  * \retval      -1 if arguments are invalid or an unsupported stripe number
924  *              was specified, error returned in errno
925  */
926 int llapi_layout_ost_index_set(struct llapi_layout *layout, int stripe_number,
927                                uint64_t ost_index)
928 {
929         if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
930                 errno = EINVAL;
931                 return -1;
932         }
933         if (!llapi_layout_stripe_index_is_valid(ost_index)) {
934                 errno = EINVAL;
935                 return -1;
936         }
937
938         if (stripe_number == 0 && ost_index == LLAPI_LAYOUT_DEFAULT) {
939                 layout->llot_stripe_offset = ost_index;
940                 layout->llot_pattern &= ~LLAPI_LAYOUT_SPECIFIC;
941                 __llapi_layout_objects_realloc(layout, 0);
942         } else if (stripe_number >= 0 &&
943                    stripe_number < LOV_MAX_STRIPE_COUNT) {
944                 if (ost_index >= LLAPI_LAYOUT_IDX_MAX) {
945                         errno = EINVAL;
946                         return -1;
947                 }
948
949                 /* Preallocate a few more stripes to avoid realloc() overhead.*/
950                 if (__llapi_layout_objects_realloc(layout,
951                                 stripe_number_roundup(stripe_number)) < 0)
952                         return -1;
953
954                 layout->llot_objects[stripe_number].l_ost_idx = ost_index;
955
956                 if (stripe_number == 0)
957                         layout->llot_stripe_offset = ost_index;
958                 else
959                         layout->llot_pattern |= LLAPI_LAYOUT_SPECIFIC;
960
961                 if (layout->llot_stripe_count == LLAPI_LAYOUT_DEFAULT ||
962                     layout->llot_stripe_count <= stripe_number)
963                         layout->llot_stripe_count = stripe_number + 1;
964         } else {
965                 errno = EINVAL;
966                 return -1;
967         }
968
969         return 0;
970 }
971
972 /**
973  * Get the OST index associated with stripe \a stripe_number.
974  *
975  * Stripes are indexed starting from zero.
976  *
977  * \param[in] layout            layout to get index from
978  * \param[in] stripe_number     stripe number to get index for
979  * \param[out] index            integer to store index in
980  *
981  * \retval      0 on success
982  * \retval      -1 if arguments are invalid
983  */
984 int llapi_layout_ost_index_get(const struct llapi_layout *layout,
985                                uint64_t stripe_number, uint64_t *index)
986 {
987         if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC ||
988             stripe_number >= layout->llot_stripe_count ||
989             stripe_number >= layout->llot_objects_count || index == NULL) {
990                 errno = EINVAL;
991                 return -1;
992         }
993
994         if (layout->llot_stripe_offset == LLAPI_LAYOUT_DEFAULT)
995                 *index = LLAPI_LAYOUT_DEFAULT;
996         else
997                 *index = layout->llot_objects[stripe_number].l_ost_idx;
998
999         return 0;
1000 }
1001
1002 /**
1003  *
1004  * Get the pool name of layout \a layout.
1005  *
1006  * \param[in] layout    layout to get pool name from
1007  * \param[out] dest     buffer to store pool name in
1008  * \param[in] n         size in bytes of buffer \a dest
1009  *
1010  * \retval      0 on success
1011  * \retval      -1 if arguments are invalid
1012  */
1013 int llapi_layout_pool_name_get(const struct llapi_layout *layout, char *dest,
1014                                size_t n)
1015 {
1016         if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC ||
1017             dest == NULL) {
1018                 errno = EINVAL;
1019                 return -1;
1020         }
1021
1022         strncpy(dest, layout->llot_pool_name, n);
1023
1024         return 0;
1025 }
1026
1027 /**
1028  * Set the name of the pool of layout \a layout.
1029  *
1030  * \param[in] layout    layout to set pool name in
1031  * \param[in] pool_name pool name to set
1032  *
1033  * \retval      0 on success
1034  * \retval      -1 if arguments are invalid or pool name is too long
1035  */
1036 int llapi_layout_pool_name_set(struct llapi_layout *layout,
1037                                const char *pool_name)
1038 {
1039         char *ptr;
1040
1041         if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC ||
1042             pool_name == NULL) {
1043                 errno = EINVAL;
1044                 return -1;
1045         }
1046
1047         /* Strip off any 'fsname.' portion. */
1048         ptr = strchr(pool_name, '.');
1049         if (ptr != NULL)
1050                 pool_name = ptr + 1;
1051
1052         if (strlen(pool_name) > LOV_MAXPOOLNAME) {
1053                 errno = EINVAL;
1054                 return -1;
1055         }
1056
1057         strncpy(layout->llot_pool_name, pool_name,
1058                 sizeof(layout->llot_pool_name));
1059
1060         return 0;
1061 }
1062
1063 /**
1064  * Open and possibly create a file with a given \a layout.
1065  *
1066  * If \a layout is NULL this function acts as a simple wrapper for
1067  * open().  By convention, ENOTTY is returned in errno if \a path
1068  * refers to a non-Lustre file.
1069  *
1070  * \param[in] path              name of the file to open
1071  * \param[in] open_flags        open() flags
1072  * \param[in] mode              permissions to create new file with
1073  * \param[in] layout            layout to create new file with
1074  *
1075  * \retval              non-negative file descriptor on successful open
1076  * \retval              -1 if an error occurred
1077  */
1078 int llapi_layout_file_open(const char *path, int open_flags, mode_t mode,
1079                            const struct llapi_layout *layout)
1080 {
1081         int fd;
1082         int rc;
1083         int tmp;
1084         struct lov_user_md *lum;
1085         size_t lum_size;
1086
1087         if (path == NULL ||
1088             (layout != NULL && layout->llot_magic != LLAPI_LAYOUT_MAGIC)) {
1089                 errno = EINVAL;
1090                 return -1;
1091         }
1092
1093         /* Object creation must be postponed until after layout attributes
1094          * have been applied. */
1095         if (layout != NULL && (open_flags & O_CREAT))
1096                 open_flags |= O_LOV_DELAY_CREATE;
1097
1098         fd = open(path, open_flags, mode);
1099
1100         if (layout == NULL || fd < 0)
1101                 return fd;
1102
1103         lum = llapi_layout_to_lum(layout);
1104
1105         if (lum == NULL) {
1106                 tmp = errno;
1107                 close(fd);
1108                 errno = tmp;
1109                 return -1;
1110         }
1111
1112         if (lum->lmm_magic == LOV_USER_MAGIC_SPECIFIC)
1113                 lum_size = lov_user_md_size(lum->lmm_stripe_count,
1114                                             lum->lmm_magic);
1115         else
1116                 lum_size = lov_user_md_size(0, lum->lmm_magic);
1117
1118         rc = fsetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_size, 0);
1119         if (rc < 0) {
1120                 tmp = errno;
1121                 close(fd);
1122                 errno = tmp;
1123                 fd = -1;
1124         }
1125
1126         free(lum);
1127         errno = errno == EOPNOTSUPP ? ENOTTY : errno;
1128
1129         return fd;
1130 }
1131
1132 /**
1133  * Create a file with a given \a layout.
1134  *
1135  * Force O_CREAT and O_EXCL flags on so caller is assured that file was
1136  * created with the given \a layout on successful function return.
1137  *
1138  * \param[in] path              name of the file to open
1139  * \param[in] open_flags        open() flags
1140  * \param[in] mode              permissions to create new file with
1141  * \param[in] layout            layout to create new file with
1142  *
1143  * \retval              non-negative file descriptor on successful open
1144  * \retval              -1 if an error occurred
1145  */
1146 int llapi_layout_file_create(const char *path, int open_flags, int mode,
1147                              const struct llapi_layout *layout)
1148 {
1149         return llapi_layout_file_open(path, open_flags|O_CREAT|O_EXCL, mode,
1150                                       layout);
1151 }