4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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
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.
20 * lustre/utils/liblustreapi_layout.c
22 * lustreapi library for layout calls for interacting with the layout of
23 * Lustre files while hiding details of the internal data structures
26 * Copyright (c) 2016, Intel Corporation.
28 * Author: Ned Bass <bass6@llnl.gov>
37 #include <sys/xattr.h>
39 #include <lustre/lustreapi.h>
40 #include <lustre/lustre_idl.h>
41 #include "lustreapi_internal.h"
44 * An Opaque data type abstracting the layout of a Lustre file.
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
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;
64 * Byte-swap the fields of struct lov_user_md.
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.
71 llapi_layout_swab_lov_user_md(struct lov_user_md *lum, int object_count)
74 struct lov_user_md_v3 *lumv3 = (struct lov_user_md_v3 *)lum;
75 struct lov_user_ost_data *lod;
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);
83 if (lum->lmm_magic != LOV_MAGIC_V1)
84 lod = lumv3->lmm_objects;
86 lod = lum->lmm_objects;
88 for (i = 0; i < object_count; i++)
89 __swab32s(&lod[i].l_ost_idx);
93 * (Re-)allocate llot_objects[] to \a num_stripes stripes.
95 * Copy over existing llot_objects[], if any, to the new llot_objects[].
97 * \param[in] layout existing layout to be modified
98 * \param[in] num_stripes number of stripes in new layout
100 * \retval 0 if the objects are re-allocated successfully
101 * \retval -1 on error with errno set
103 static int __llapi_layout_objects_realloc(struct llapi_layout *layout,
104 unsigned int new_stripes)
106 struct lov_user_ost_data_v1 *new_objects;
109 if (new_stripes > LOV_MAX_STRIPE_COUNT) {
114 if (new_stripes == 0 && layout->llot_objects_count == 0)
117 if (new_stripes != 0 && new_stripes <= layout->llot_objects_count)
120 new_objects = realloc(layout->llot_objects,
121 sizeof(*new_objects) * new_stripes);
122 if (new_objects == NULL && new_stripes != 0) {
127 for (i = layout->llot_objects_count; i < new_stripes; i++)
128 new_objects[i].l_ost_idx = LLAPI_LAYOUT_IDX_MAX;
130 if (new_stripes == 0)
131 layout->llot_objects = NULL;
133 layout->llot_objects = new_objects;
134 layout->llot_objects_count = new_stripes;
140 * Allocate storage for a llapi_layout with \a num_stripes stripes.
142 * \param[in] num_stripes number of stripes in new layout
144 * \retval valid pointer if allocation succeeds
145 * \retval NULL if allocation fails
147 static struct llapi_layout *__llapi_layout_alloc(unsigned int num_stripes)
149 struct llapi_layout *layout;
151 if (num_stripes > LOV_MAX_STRIPE_COUNT) {
156 layout = calloc(1, sizeof(*layout));
157 if (layout == NULL) {
162 layout->llot_objects = NULL;
163 layout->llot_objects_count = 0;
165 if (__llapi_layout_objects_realloc(layout, num_stripes) < 0) {
174 * Copy the data from a lov_user_md to a newly allocated llapi_layout.
176 * The caller is responsible for freeing the returned pointer.
178 * \param[in] lum LOV user metadata structure to copy data from
180 * \retval valid llapi_layout pointer on success
181 * \retval NULL if memory allocation fails
183 static struct llapi_layout *
184 llapi_layout_from_lum(const struct lov_user_md *lum, size_t object_count)
186 struct llapi_layout *layout;
189 objects_sz = object_count * sizeof(lum->lmm_objects[0]);
191 layout = __llapi_layout_alloc(object_count);
195 layout->llot_magic = LLAPI_LAYOUT_MAGIC;
197 if (lum->lmm_pattern == LOV_PATTERN_RAID0)
198 layout->llot_pattern = LLAPI_LAYOUT_RAID0;
200 /* Lustre only supports RAID0 for now. */
201 layout->llot_pattern = lum->lmm_pattern;
203 if (lum->lmm_stripe_size == 0)
204 layout->llot_stripe_size = LLAPI_LAYOUT_DEFAULT;
206 layout->llot_stripe_size = lum->lmm_stripe_size;
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;
213 layout->llot_stripe_count = lum->lmm_stripe_count;
215 if (lum->lmm_stripe_offset == (typeof(lum->lmm_stripe_offset))-1)
216 layout->llot_stripe_offset = LLAPI_LAYOUT_DEFAULT;
218 layout->llot_stripe_offset = lum->lmm_stripe_offset;
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);
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);
232 if (object_count != 0)
233 layout->llot_stripe_offset = layout->llot_objects[0].l_ost_idx;
239 * Copy the data from a llapi_layout to a newly allocated lov_user_md.
241 * The caller is responsible for freeing the returned pointer.
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.
247 * \param[in] layout the layout to copy from
249 * \retval valid lov_user_md pointer on success
250 * \retval NULL if memory allocation fails or the layout is invalid
252 static struct lov_user_md *
253 llapi_layout_to_lum(const struct llapi_layout *layout)
255 struct lov_user_md *lum;
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;
262 if ((pattern & LLAPI_LAYOUT_SPECIFIC) != 0) {
263 if (layout->llot_objects_count < layout->llot_stripe_count) {
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;
275 * All stripes must be specified when the pattern contains
276 * LLAPI_LAYOUT_SPECIFIC
278 for (i = 0; i < obj_count; i++) {
279 if (layout->llot_objects[i].l_ost_idx ==
280 LLAPI_LAYOUT_IDX_MAX) {
286 lum_size = lov_user_md_size(obj_count, magic);
287 lum = malloc(lum_size);
291 lum->lmm_magic = magic;
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;
298 lum->lmm_pattern = pattern;
300 if (layout->llot_stripe_size == LLAPI_LAYOUT_DEFAULT)
301 lum->lmm_stripe_size = 0;
303 lum->lmm_stripe_size = layout->llot_stripe_size;
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;
310 lum->lmm_stripe_count = layout->llot_stripe_count;
312 if (layout->llot_stripe_offset == LLAPI_LAYOUT_DEFAULT)
313 lum->lmm_stripe_offset = -1;
315 lum->lmm_stripe_offset = layout->llot_stripe_offset;
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;
320 if (strlen(layout->llot_pool_name)) {
321 strncpy(lumv3->lmm_pool_name, layout->llot_pool_name,
322 sizeof(lumv3->lmm_pool_name));
324 memset(lumv3->lmm_pool_name, 0, LOV_MAXPOOLNAME);
326 lmm_objects = lumv3->lmm_objects;
328 lmm_objects = lum->lmm_objects;
331 for (i = 0; i < obj_count; i++)
332 lmm_objects[i].l_ost_idx = layout->llot_objects[i].l_ost_idx;
338 * Get the parent directory of a path.
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
344 static void get_parent_dir(const char *path, char *buf, size_t size)
348 strncpy(buf, path, size);
349 p = strrchr(buf, '/');
354 strncpy(buf, ".", 2);
358 * Substitute unspecified attribute values in \a dest with
359 * values from \a src.
361 * \param[in] src layout to inherit values from
362 * \param[in] dest layout to receive inherited values
364 static void inherit_layout_attributes(const struct llapi_layout *src,
365 struct llapi_layout *dest)
367 if (dest->llot_pattern == LLAPI_LAYOUT_DEFAULT)
368 dest->llot_pattern = src->llot_pattern;
370 if (dest->llot_stripe_size == LLAPI_LAYOUT_DEFAULT)
371 dest->llot_stripe_size = src->llot_stripe_size;
373 if (dest->llot_stripe_count == LLAPI_LAYOUT_DEFAULT)
374 dest->llot_stripe_count = src->llot_stripe_count;
376 if (dest->llot_stripe_offset == LLAPI_LAYOUT_DEFAULT)
377 dest->llot_stripe_offset = src->llot_stripe_offset;
381 * Test if all attributes of \a layout are specified.
383 * \param[in] layout the layout to check
385 * \retval true all attributes are specified
386 * \retval false at least one attribute is unspecified
388 static bool is_fully_specified(const struct llapi_layout *layout)
390 return layout->llot_pattern != LLAPI_LAYOUT_DEFAULT &&
391 layout->llot_stripe_size != LLAPI_LAYOUT_DEFAULT &&
392 layout->llot_stripe_count != LLAPI_LAYOUT_DEFAULT;
396 * Allocate and initialize a new layout.
398 * \retval valid llapi_layout pointer on success
399 * \retval NULL if memory allocation fails
401 struct llapi_layout *llapi_layout_alloc(void)
403 struct llapi_layout *layout;
405 layout = __llapi_layout_alloc(0);
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';
421 * Check if the given \a lum_size is large enough to hold the required
424 * \param[in] lum the struct lov_user_md to check
425 * \param[in] lum_size the number of bytes in \a lum
427 * \retval true the \a lum_size is too small
428 * \retval false the \a lum_size is large enough
430 static bool llapi_layout_lum_truncated(struct lov_user_md *lum, size_t lum_size)
434 if (lum_size < lov_user_md_size(0, LOV_MAGIC_V1))
437 if (lum->lmm_magic == __swab32(LOV_MAGIC_V1) ||
438 lum->lmm_magic == __swab32(LOV_MAGIC_V3))
439 magic = __swab32(lum->lmm_magic);
441 magic = lum->lmm_magic;
443 return lum_size < lov_user_md_size(0, magic);
447 * Compute the number of elements in the lmm_objects array of \a lum
448 * with size \a lum_size.
450 * \param[in] lum the struct lov_user_md to check
451 * \param[in] lum_size the number of bytes in \a lum
453 * \retval number of elements in array lum->lmm_objects
455 static int llapi_layout_objects_in_lum(struct lov_user_md *lum, size_t lum_size)
460 if (lum_size < lov_user_md_size(0, LOV_MAGIC_V1))
463 if (lum->lmm_magic == __swab32(LOV_MAGIC_V1) ||
464 lum->lmm_magic == __swab32(LOV_MAGIC_V3))
465 magic = __swab32(lum->lmm_magic);
467 magic = lum->lmm_magic;
469 base_size = lov_user_md_size(0, magic);
471 if (lum_size <= base_size)
474 return (lum_size - base_size) / sizeof(lum->lmm_objects[0]);
478 * Get the striping layout for the file referenced by file descriptor \a fd.
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.
485 * If the kernel gives us back less than the expected amount of data,
486 * we fail with errno set to EINTR.
488 * \param[in] fd open file descriptor
489 * \param[in] flags open file descriptor
491 * \retval valid llapi_layout pointer on success
492 * \retval NULL if an error occurs
494 struct llapi_layout *llapi_layout_get_by_fd(int fd, uint32_t flags)
497 struct lov_user_md *lum;
498 struct llapi_layout *layout = NULL;
501 int lum_stripe_count;
505 lum_len = XATTR_SIZE_MAX;
506 lum = malloc(lum_len);
510 bytes_read = fgetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_len);
511 if (bytes_read < 0) {
512 if (errno == EOPNOTSUPP)
514 else if (errno == ENODATA)
515 layout = llapi_layout_alloc();
519 /* Return an error if we got back a partial layout. */
520 if (llapi_layout_lum_truncated(lum, bytes_read)) {
525 object_count = llapi_layout_objects_in_lum(lum, bytes_read);
527 need_swab = lum->lmm_magic == __swab32(LOV_MAGIC_V1) ||
528 lum->lmm_magic == __swab32(LOV_MAGIC_V3);
531 lum_stripe_count = __swab16(lum->lmm_stripe_count);
533 lum_stripe_count = lum->lmm_stripe_count;
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)
542 if (!S_ISDIR(st.st_mode) && object_count != lum_stripe_count) {
548 llapi_layout_swab_lov_user_md(lum, object_count);
550 layout = llapi_layout_from_lum(lum, object_count);
558 * Get the expected striping layout for a file at \a path.
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.
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.
573 * \param[in] path path for which to get the expected layout
575 * \retval valid llapi_layout pointer on success
576 * \retval NULL if an error occurs
578 static struct llapi_layout *llapi_layout_expected(const char *path)
580 struct llapi_layout *path_layout = NULL;
581 struct llapi_layout *donor_layout;
582 char donor_path[PATH_MAX];
587 fd = open(path, O_RDONLY);
588 if (fd < 0 && errno != ENOENT)
594 path_layout = llapi_layout_get_by_fd(fd, 0);
600 if (path_layout == NULL) {
601 if (errno != ENODATA && errno != ENOENT)
604 path_layout = llapi_layout_alloc();
605 if (path_layout == NULL)
609 if (is_fully_specified(path_layout))
612 rc = stat(path, &st);
613 if (rc < 0 && errno != ENOENT) {
614 llapi_layout_free(path_layout);
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))
632 /* Inherit remaining unspecified attributes from the filesystem root. */
633 rc = llapi_search_mounts(path, 0, donor_path, NULL);
635 llapi_layout_free(path_layout);
638 donor_layout = llapi_layout_get_by_path(donor_path, 0);
639 if (donor_layout == NULL) {
640 llapi_layout_free(path_layout);
644 inherit_layout_attributes(donor_layout, path_layout);
645 llapi_layout_free(donor_layout);
651 * Get the striping layout for the file at \a path.
653 * If \a flags contains LAYOUT_GET_EXPECTED, substitute
654 * expected inherited attribute values for unspecified attributes. See
655 * llapi_layout_expected().
657 * \param[in] path path for which to get the layout
658 * \param[in] flags flags to control how layout is retrieved
660 * \retval valid llapi_layout pointer on success
661 * \retval NULL if an error occurs
663 struct llapi_layout *llapi_layout_get_by_path(const char *path, uint32_t flags)
665 struct llapi_layout *layout = NULL;
669 if (flags & LAYOUT_GET_EXPECTED)
670 return llapi_layout_expected(path);
672 fd = open(path, O_RDONLY);
676 layout = llapi_layout_get_by_fd(fd, flags);
685 * Get the layout for the file with FID \a fidstr in filesystem \a lustre_dir.
687 * \param[in] lustre_dir path within Lustre filesystem containing \a fid
688 * \param[in] fid Lustre identifier of file to get layout for
690 * \retval valid llapi_layout pointer on success
691 * \retval NULL if an error occurs
693 struct llapi_layout *llapi_layout_get_by_fid(const char *lustre_dir,
694 const lustre_fid *fid,
699 int saved_msg_level = llapi_msg_get_level();
700 struct llapi_layout *layout = NULL;
702 /* Prevent llapi internal routines from writing to console
703 * while executing this function, then restore previous message
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);
712 layout = llapi_layout_get_by_fd(fd, flags);
721 * Free memory allocated for \a layout.
723 * \param[in] layout previously allocated by llapi_layout_alloc()
725 void llapi_layout_free(struct llapi_layout *layout)
727 if (layout->llot_objects != NULL)
728 free(layout->llot_objects);
733 * Get the stripe count of \a layout.
735 * \param[in] layout layout to get stripe count from
736 * \param[out] count integer to store stripe count in
738 * \retval 0 on success
739 * \retval -1 if arguments are invalid
741 int llapi_layout_stripe_count_get(const struct llapi_layout *layout,
744 if (layout == NULL || count == NULL ||
745 layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
749 *count = layout->llot_stripe_count;
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.
759 static bool llapi_layout_stripe_count_is_valid(int64_t stripe_count)
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));
767 static bool llapi_layout_stripe_size_is_valid(uint64_t stripe_size)
769 return stripe_size == LLAPI_LAYOUT_DEFAULT ||
771 llapi_stripe_size_is_aligned(stripe_size) &&
772 !llapi_stripe_size_is_too_big(stripe_size));
775 static bool llapi_layout_stripe_index_is_valid(int64_t stripe_index)
777 return stripe_index == LLAPI_LAYOUT_DEFAULT ||
778 (stripe_index >= 0 &&
779 llapi_stripe_index_is_valid(stripe_index));
783 * Set the stripe count of \a layout.
785 * \param[in] layout layout to set stripe count in
786 * \param[in] count value to be set
788 * \retval 0 on success
789 * \retval -1 if arguments are invalid
791 int llapi_layout_stripe_count_set(struct llapi_layout *layout,
794 if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC ||
795 !llapi_layout_stripe_count_is_valid(count)) {
800 layout->llot_stripe_count = count;
806 * Get the stripe size of \a layout.
808 * \param[in] layout layout to get stripe size from
809 * \param[out] size integer to store stripe size in
811 * \retval 0 on success
812 * \retval -1 if arguments are invalid
814 int llapi_layout_stripe_size_get(const struct llapi_layout *layout,
817 if (layout == NULL || size == NULL ||
818 layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
823 *size = layout->llot_stripe_size;
829 * Set the stripe size of \a layout.
831 * \param[in] layout layout to set stripe size in
832 * \param[in] size value to be set
834 * \retval 0 on success
835 * \retval -1 if arguments are invalid
837 int llapi_layout_stripe_size_set(struct llapi_layout *layout,
840 if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC ||
841 !llapi_layout_stripe_size_is_valid(size)) {
846 layout->llot_stripe_size = size;
852 * Get the RAID pattern of \a layout.
854 * \param[in] layout layout to get pattern from
855 * \param[out] pattern integer to store pattern in
857 * \retval 0 on success
858 * \retval -1 if arguments are invalid
860 int llapi_layout_pattern_get(const struct llapi_layout *layout,
863 if (layout == NULL || pattern == NULL ||
864 layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
869 *pattern = layout->llot_pattern;
875 * Set the RAID pattern of \a layout.
877 * \param[in] layout layout to set pattern in
878 * \param[in] pattern value to be set
880 * \retval 0 on success
881 * \retval -1 if arguments are invalid or RAID pattern
884 int llapi_layout_pattern_set(struct llapi_layout *layout, uint64_t pattern)
886 if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
891 if (pattern != LLAPI_LAYOUT_DEFAULT &&
892 pattern != LLAPI_LAYOUT_RAID0) {
897 layout->llot_pattern = pattern |
898 (layout->llot_pattern & LLAPI_LAYOUT_SPECIFIC);
903 static inline int stripe_number_roundup(int stripe_number)
905 unsigned int round_up = (stripe_number + 8) & ~7;
906 return round_up > LOV_MAX_STRIPE_COUNT ?
907 LOV_MAX_STRIPE_COUNT : round_up;
911 * Set the OST index of stripe number \a stripe_number to \a ost_index.
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.
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
922 * \retval 0 on success
923 * \retval -1 if arguments are invalid or an unsupported stripe number
924 * was specified, error returned in errno
926 int llapi_layout_ost_index_set(struct llapi_layout *layout, int stripe_number,
929 if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
933 if (!llapi_layout_stripe_index_is_valid(ost_index)) {
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) {
949 /* Preallocate a few more stripes to avoid realloc() overhead.*/
950 if (__llapi_layout_objects_realloc(layout,
951 stripe_number_roundup(stripe_number)) < 0)
954 layout->llot_objects[stripe_number].l_ost_idx = ost_index;
956 if (stripe_number == 0)
957 layout->llot_stripe_offset = ost_index;
959 layout->llot_pattern |= LLAPI_LAYOUT_SPECIFIC;
961 if (layout->llot_stripe_count == LLAPI_LAYOUT_DEFAULT ||
962 layout->llot_stripe_count <= stripe_number)
963 layout->llot_stripe_count = stripe_number + 1;
973 * Get the OST index associated with stripe \a stripe_number.
975 * Stripes are indexed starting from zero.
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
981 * \retval 0 on success
982 * \retval -1 if arguments are invalid
984 int llapi_layout_ost_index_get(const struct llapi_layout *layout,
985 uint64_t stripe_number, uint64_t *index)
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) {
994 if (layout->llot_stripe_offset == LLAPI_LAYOUT_DEFAULT)
995 *index = LLAPI_LAYOUT_DEFAULT;
997 *index = layout->llot_objects[stripe_number].l_ost_idx;
1004 * Get the pool name of layout \a layout.
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
1010 * \retval 0 on success
1011 * \retval -1 if arguments are invalid
1013 int llapi_layout_pool_name_get(const struct llapi_layout *layout, char *dest,
1016 if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC ||
1022 strncpy(dest, layout->llot_pool_name, n);
1028 * Set the name of the pool of layout \a layout.
1030 * \param[in] layout layout to set pool name in
1031 * \param[in] pool_name pool name to set
1033 * \retval 0 on success
1034 * \retval -1 if arguments are invalid or pool name is too long
1036 int llapi_layout_pool_name_set(struct llapi_layout *layout,
1037 const char *pool_name)
1041 if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC ||
1042 pool_name == NULL) {
1047 /* Strip off any 'fsname.' portion. */
1048 ptr = strchr(pool_name, '.');
1050 pool_name = ptr + 1;
1052 if (strlen(pool_name) > LOV_MAXPOOLNAME) {
1057 strncpy(layout->llot_pool_name, pool_name,
1058 sizeof(layout->llot_pool_name));
1064 * Open and possibly create a file with a given \a layout.
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.
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
1075 * \retval non-negative file descriptor on successful open
1076 * \retval -1 if an error occurred
1078 int llapi_layout_file_open(const char *path, int open_flags, mode_t mode,
1079 const struct llapi_layout *layout)
1084 struct lov_user_md *lum;
1088 (layout != NULL && layout->llot_magic != LLAPI_LAYOUT_MAGIC)) {
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;
1098 fd = open(path, open_flags, mode);
1100 if (layout == NULL || fd < 0)
1103 lum = llapi_layout_to_lum(layout);
1112 if (lum->lmm_magic == LOV_USER_MAGIC_SPECIFIC)
1113 lum_size = lov_user_md_size(lum->lmm_stripe_count,
1116 lum_size = lov_user_md_size(0, lum->lmm_magic);
1118 rc = fsetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_size, 0);
1127 errno = errno == EOPNOTSUPP ? ENOTTY : errno;
1133 * Create a file with a given \a layout.
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.
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
1143 * \retval non-negative file descriptor on successful open
1144 * \retval -1 if an error occurred
1146 int llapi_layout_file_create(const char *path, int open_flags, int mode,
1147 const struct llapi_layout *layout)
1149 return llapi_layout_file_open(path, open_flags|O_CREAT|O_EXCL, mode,