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