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 * Author: Ned Bass <bass6@llnl.gov>
35 #include <sys/xattr.h>
37 #include <lustre/lustreapi.h>
38 #include <lustre/lustre_idl.h>
39 #include "lustreapi_internal.h"
42 * An Opaque data type abstracting the layout of a Lustre file.
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
50 uint64_t llot_pattern;
51 uint64_t llot_stripe_size;
52 uint64_t llot_stripe_count;
53 uint64_t llot_stripe_offset;
54 /** Indicates if llot_objects array has been initialized. */
55 bool llot_objects_are_valid;
56 /* Add 1 so user always gets back a null terminated string. */
57 char llot_pool_name[LOV_MAXPOOLNAME + 1];
58 struct lov_user_ost_data_v1 llot_objects[0];
62 * Byte-swap the fields of struct lov_user_md.
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.
69 llapi_layout_swab_lov_user_md(struct lov_user_md *lum, int object_count)
72 struct lov_user_md_v3 *lumv3 = (struct lov_user_md_v3 *)lum;
73 struct lov_user_ost_data *lod;
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);
81 if (lum->lmm_magic != LOV_MAGIC_V1)
82 lod = lumv3->lmm_objects;
84 lod = lum->lmm_objects;
86 for (i = 0; i < object_count; i++)
87 __swab32s(&lod[i].l_ost_idx);
91 * Allocate storage for a llapi_layout with \a num_stripes stripes.
93 * \param[in] num_stripes number of stripes in new layout
95 * \retval valid pointer if allocation succeeds
96 * \retval NULL if allocation fails
98 static struct llapi_layout *__llapi_layout_alloc(unsigned int num_stripes)
100 struct llapi_layout *layout = NULL;
101 size_t size = sizeof(*layout) +
102 (num_stripes * sizeof(layout->llot_objects[0]));
104 if (num_stripes > LOV_MAX_STRIPE_COUNT)
107 layout = calloc(1, size);
113 * Copy the data from a lov_user_md to a newly allocated llapi_layout.
115 * The caller is responsible for freeing the returned pointer.
117 * \param[in] lum LOV user metadata structure to copy data from
119 * \retval valid llapi_layout pointer on success
120 * \retval NULL if memory allocation fails
122 static struct llapi_layout *
123 llapi_layout_from_lum(const struct lov_user_md *lum, size_t object_count)
125 struct llapi_layout *layout;
128 objects_sz = object_count * sizeof(lum->lmm_objects[0]);
130 layout = __llapi_layout_alloc(object_count);
134 layout->llot_magic = LLAPI_LAYOUT_MAGIC;
136 if (lum->lmm_pattern == LOV_PATTERN_RAID0)
137 layout->llot_pattern = LLAPI_LAYOUT_RAID0;
139 /* Lustre only supports RAID0 for now. */
140 layout->llot_pattern = lum->lmm_pattern;
142 if (lum->lmm_stripe_size == 0)
143 layout->llot_stripe_size = LLAPI_LAYOUT_DEFAULT;
145 layout->llot_stripe_size = lum->lmm_stripe_size;
147 if (lum->lmm_stripe_count == (typeof(lum->lmm_stripe_count))-1)
148 layout->llot_stripe_count = LLAPI_LAYOUT_WIDE;
149 else if (lum->lmm_stripe_count == 0)
150 layout->llot_stripe_count = LLAPI_LAYOUT_DEFAULT;
152 layout->llot_stripe_count = lum->lmm_stripe_count;
154 /* Don't copy lmm_stripe_offset: it is always zero
155 * when reading attributes. */
157 if (lum->lmm_magic != LOV_USER_MAGIC_V1) {
158 const struct lov_user_md_v3 *lumv3;
159 lumv3 = (struct lov_user_md_v3 *)lum;
160 snprintf(layout->llot_pool_name, sizeof(layout->llot_pool_name),
161 "%s", lumv3->lmm_pool_name);
162 memcpy(layout->llot_objects, lumv3->lmm_objects, objects_sz);
164 const struct lov_user_md_v1 *lumv1;
165 lumv1 = (struct lov_user_md_v1 *)lum;
166 memcpy(layout->llot_objects, lumv1->lmm_objects, objects_sz);
168 if (object_count > 0)
169 layout->llot_objects_are_valid = true;
175 * Copy the data from a llapi_layout to a newly allocated lov_user_md.
177 * The caller is responsible for freeing the returned pointer.
179 * The current version of this API doesn't support specifying the OST
180 * index of arbitrary stripes, only stripe 0 via lmm_stripe_offset.
181 * There is therefore no need to copy the lmm_objects array.
183 * \param[in] layout the layout to copy from
185 * \retval valid lov_user_md pointer on success
186 * \retval NULL if memory allocation fails
188 static struct lov_user_md *
189 llapi_layout_to_lum(const struct llapi_layout *layout)
191 struct lov_user_md *lum;
193 uint32_t magic = LOV_USER_MAGIC_V1;
195 if (strlen(layout->llot_pool_name) != 0)
196 magic = LOV_USER_MAGIC_V3;
198 /* The lum->lmm_objects array won't be
199 * sent to the kernel when we write the lum, so
200 * we don't allocate storage for it.
202 lum_size = lov_user_md_size(0, magic);
203 lum = malloc(lum_size);
207 lum->lmm_magic = magic;
209 if (layout->llot_pattern == LLAPI_LAYOUT_DEFAULT)
210 lum->lmm_pattern = 0;
211 else if (layout->llot_pattern == LLAPI_LAYOUT_RAID0)
212 lum->lmm_pattern = 1;
214 lum->lmm_pattern = layout->llot_pattern;
216 if (layout->llot_stripe_size == LLAPI_LAYOUT_DEFAULT)
217 lum->lmm_stripe_size = 0;
219 lum->lmm_stripe_size = layout->llot_stripe_size;
221 if (layout->llot_stripe_count == LLAPI_LAYOUT_DEFAULT)
222 lum->lmm_stripe_count = 0;
223 else if (layout->llot_stripe_count == LLAPI_LAYOUT_WIDE)
224 lum->lmm_stripe_count = -1;
226 lum->lmm_stripe_count = layout->llot_stripe_count;
228 if (layout->llot_stripe_offset == LLAPI_LAYOUT_DEFAULT)
229 lum->lmm_stripe_offset = -1;
231 lum->lmm_stripe_offset = layout->llot_stripe_offset;
233 if (lum->lmm_magic != LOV_USER_MAGIC_V1) {
234 struct lov_user_md_v3 *lumv3 = (struct lov_user_md_v3 *)lum;
236 strncpy(lumv3->lmm_pool_name, layout->llot_pool_name,
237 sizeof(lumv3->lmm_pool_name));
244 * Get the parent directory of a path.
246 * \param[in] path path to get parent of
247 * \param[out] buf buffer in which to store parent path
248 * \param[in] size size in bytes of buffer \a buf
250 static void get_parent_dir(const char *path, char *buf, size_t size)
254 strncpy(buf, path, size);
255 p = strrchr(buf, '/');
260 strncpy(buf, ".", 2);
264 * Substitute unspecified attribute values in \a dest with
265 * values from \a src.
267 * \param[in] src layout to inherit values from
268 * \param[in] dest layout to receive inherited values
270 static void inherit_layout_attributes(const struct llapi_layout *src,
271 struct llapi_layout *dest)
273 if (dest->llot_pattern == LLAPI_LAYOUT_DEFAULT)
274 dest->llot_pattern = src->llot_pattern;
276 if (dest->llot_stripe_size == LLAPI_LAYOUT_DEFAULT)
277 dest->llot_stripe_size = src->llot_stripe_size;
279 if (dest->llot_stripe_count == LLAPI_LAYOUT_DEFAULT)
280 dest->llot_stripe_count = src->llot_stripe_count;
284 * Test if all attributes of \a layout are specified.
286 * \param[in] layout the layout to check
288 * \retval true all attributes are specified
289 * \retval false at least one attribute is unspecified
291 static bool is_fully_specified(const struct llapi_layout *layout)
293 return layout->llot_pattern != LLAPI_LAYOUT_DEFAULT &&
294 layout->llot_stripe_size != LLAPI_LAYOUT_DEFAULT &&
295 layout->llot_stripe_count != LLAPI_LAYOUT_DEFAULT;
299 * Allocate and initialize a new layout.
301 * \retval valid llapi_layout pointer on success
302 * \retval NULL if memory allocation fails
304 struct llapi_layout *llapi_layout_alloc(void)
306 struct llapi_layout *layout;
308 layout = __llapi_layout_alloc(0);
313 layout->llot_magic = LLAPI_LAYOUT_MAGIC;
314 layout->llot_pattern = LLAPI_LAYOUT_DEFAULT;
315 layout->llot_stripe_size = LLAPI_LAYOUT_DEFAULT;
316 layout->llot_stripe_count = LLAPI_LAYOUT_DEFAULT;
317 layout->llot_stripe_offset = LLAPI_LAYOUT_DEFAULT;
318 layout->llot_objects_are_valid = false;
319 layout->llot_pool_name[0] = '\0';
325 * Check if the given \a lum_size is large enough to hold the required
328 * \param[in] lum the struct lov_user_md to check
329 * \param[in] lum_size the number of bytes in \a lum
331 * \retval true the \a lum_size is too small
332 * \retval false the \a lum_size is large enough
334 static bool llapi_layout_lum_truncated(struct lov_user_md *lum, size_t lum_size)
338 if (lum_size < lov_user_md_size(0, LOV_MAGIC_V1))
341 if (lum->lmm_magic == __swab32(LOV_MAGIC_V1) ||
342 lum->lmm_magic == __swab32(LOV_MAGIC_V3))
343 magic = __swab32(lum->lmm_magic);
345 magic = lum->lmm_magic;
347 return lum_size < lov_user_md_size(0, magic);
351 * Compute the number of elements in the lmm_objects array of \a lum
352 * with size \a lum_size.
354 * \param[in] lum the struct lov_user_md to check
355 * \param[in] lum_size the number of bytes in \a lum
357 * \retval number of elements in array lum->lmm_objects
359 static int llapi_layout_objects_in_lum(struct lov_user_md *lum, size_t lum_size)
364 if (lum_size < lov_user_md_size(0, LOV_MAGIC_V1))
367 if (lum->lmm_magic == __swab32(LOV_MAGIC_V1) ||
368 lum->lmm_magic == __swab32(LOV_MAGIC_V3))
369 magic = __swab32(lum->lmm_magic);
371 magic = lum->lmm_magic;
373 base_size = lov_user_md_size(0, magic);
375 if (lum_size <= base_size)
378 return (lum_size - base_size) / sizeof(lum->lmm_objects[0]);
382 * Get the striping layout for the file referenced by file descriptor \a fd.
384 * If the filesystem does not support the "lustre." xattr namespace, the
385 * file must be on a non-Lustre filesystem, so set errno to ENOTTY per
386 * convention. If the file has no "lustre.lov" data, the file will
387 * inherit default values, so return a default layout.
389 * If the kernel gives us back less than the expected amount of data,
390 * we fail with errno set to EINTR.
392 * \param[in] fd open file descriptor
393 * \param[in] flags open file descriptor
395 * \retval valid llapi_layout pointer on success
396 * \retval NULL if an error occurs
398 struct llapi_layout *llapi_layout_get_by_fd(int fd, uint32_t flags)
401 struct lov_user_md *lum;
402 struct llapi_layout *layout = NULL;
405 int lum_stripe_count;
409 lum_len = XATTR_SIZE_MAX;
410 lum = malloc(lum_len);
414 bytes_read = fgetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_len);
415 if (bytes_read < 0) {
416 if (errno == EOPNOTSUPP)
418 else if (errno == ENODATA)
419 layout = llapi_layout_alloc();
423 /* Return an error if we got back a partial layout. */
424 if (llapi_layout_lum_truncated(lum, bytes_read)) {
429 object_count = llapi_layout_objects_in_lum(lum, bytes_read);
431 need_swab = lum->lmm_magic == __swab32(LOV_MAGIC_V1) ||
432 lum->lmm_magic == __swab32(LOV_MAGIC_V3);
435 lum_stripe_count = __swab16(lum->lmm_stripe_count);
437 lum_stripe_count = lum->lmm_stripe_count;
439 /* Directories may have a positive non-zero lum->lmm_stripe_count
440 * yet have an empty lum->lmm_objects array. For non-directories the
441 * amount of data returned from the kernel must be consistent
442 * with the stripe count. */
443 if (fstat(fd, &st) < 0)
446 if (!S_ISDIR(st.st_mode) && object_count != lum_stripe_count) {
452 llapi_layout_swab_lov_user_md(lum, object_count);
454 layout = llapi_layout_from_lum(lum, object_count);
462 * Get the expected striping layout for a file at \a path.
464 * Substitute expected inherited attribute values for unspecified
465 * attributes. Unspecified attributes may belong to directories and
466 * never-written-to files, and indicate that default values will be
467 * assigned when files are created or first written to. A default value
468 * is inherited from the parent directory if the attribute is specified
469 * there, otherwise it is inherited from the filesystem root.
470 * Unspecified attributes normally have the value LLAPI_LAYOUT_DEFAULT.
472 * The complete \a path need not refer to an existing file or directory,
473 * but some leading portion of it must reside within a lustre filesystem.
474 * A use case for this interface would be to obtain the literal striping
475 * values that would be assigned to a new file in a given directory.
477 * \param[in] path path for which to get the expected layout
479 * \retval valid llapi_layout pointer on success
480 * \retval NULL if an error occurs
482 static struct llapi_layout *llapi_layout_expected(const char *path)
484 struct llapi_layout *path_layout = NULL;
485 struct llapi_layout *donor_layout;
486 char donor_path[PATH_MAX];
491 fd = open(path, O_RDONLY);
492 if (fd < 0 && errno != ENOENT)
498 path_layout = llapi_layout_get_by_fd(fd, 0);
504 if (path_layout == NULL) {
505 if (errno != ENODATA && errno != ENOENT)
508 path_layout = llapi_layout_alloc();
509 if (path_layout == NULL)
513 if (is_fully_specified(path_layout))
516 rc = stat(path, &st);
517 if (rc < 0 && errno != ENOENT) {
518 llapi_layout_free(path_layout);
522 /* If path is a not a directory or doesn't exist, inherit unspecified
523 * attributes from parent directory. */
524 if ((rc == 0 && !S_ISDIR(st.st_mode)) ||
525 (rc < 0 && errno == ENOENT)) {
526 get_parent_dir(path, donor_path, sizeof(donor_path));
527 donor_layout = llapi_layout_get_by_path(donor_path, 0);
528 if (donor_layout != NULL) {
529 inherit_layout_attributes(donor_layout, path_layout);
530 llapi_layout_free(donor_layout);
531 if (is_fully_specified(path_layout))
536 /* Inherit remaining unspecified attributes from the filesystem root. */
537 rc = llapi_search_mounts(path, 0, donor_path, NULL);
539 llapi_layout_free(path_layout);
542 donor_layout = llapi_layout_get_by_path(donor_path, 0);
543 if (donor_layout == NULL) {
544 llapi_layout_free(path_layout);
548 inherit_layout_attributes(donor_layout, path_layout);
549 llapi_layout_free(donor_layout);
555 * Get the striping layout for the file at \a path.
557 * If \a flags contains LAYOUT_GET_EXPECTED, substitute
558 * expected inherited attribute values for unspecified attributes. See
559 * llapi_layout_expected().
561 * \param[in] path path for which to get the layout
562 * \param[in] flags flags to control how layout is retrieved
564 * \retval valid llapi_layout pointer on success
565 * \retval NULL if an error occurs
567 struct llapi_layout *llapi_layout_get_by_path(const char *path, uint32_t flags)
569 struct llapi_layout *layout = NULL;
573 if (flags & LAYOUT_GET_EXPECTED)
574 return llapi_layout_expected(path);
576 fd = open(path, O_RDONLY);
580 layout = llapi_layout_get_by_fd(fd, flags);
589 * Get the layout for the file with FID \a fidstr in filesystem \a lustre_dir.
591 * \param[in] lustre_dir path within Lustre filesystem containing \a fid
592 * \param[in] fid Lustre identifier of file to get layout for
594 * \retval valid llapi_layout pointer on success
595 * \retval NULL if an error occurs
597 struct llapi_layout *llapi_layout_get_by_fid(const char *lustre_dir,
598 const lustre_fid *fid,
603 int saved_msg_level = llapi_msg_get_level();
604 struct llapi_layout *layout = NULL;
606 /* Prevent llapi internal routines from writing to console
607 * while executing this function, then restore previous message
609 llapi_msg_set_level(LLAPI_MSG_OFF);
610 fd = llapi_open_by_fid(lustre_dir, fid, O_RDONLY);
611 llapi_msg_set_level(saved_msg_level);
616 layout = llapi_layout_get_by_fd(fd, flags);
624 /** * Free memory allocated for \a layout. */
625 void llapi_layout_free(struct llapi_layout *layout)
631 * Get the stripe count of \a layout.
633 * \param[in] layout layout to get stripe count from
634 * \param[out] count integer to store stripe count in
636 * \retval 0 on success
637 * \retval -1 if arguments are invalid
639 int llapi_layout_stripe_count_get(const struct llapi_layout *layout,
642 if (layout == NULL || count == NULL ||
643 layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
647 *count = layout->llot_stripe_count;
652 * The llapi_layout API functions have these extra validity checks since
653 * they use intuitively named macros to denote special behavior, whereas
654 * the old API uses 0 and -1.
657 static bool llapi_layout_stripe_count_is_valid(int64_t stripe_count)
659 return stripe_count == LLAPI_LAYOUT_DEFAULT ||
660 stripe_count == LLAPI_LAYOUT_WIDE ||
661 (stripe_count != 0 && stripe_count != -1 &&
662 llapi_stripe_count_is_valid(stripe_count));
665 static bool llapi_layout_stripe_size_is_valid(uint64_t stripe_size)
667 return stripe_size == LLAPI_LAYOUT_DEFAULT ||
669 llapi_stripe_size_is_aligned(stripe_size) &&
670 !llapi_stripe_size_is_too_big(stripe_size));
673 static bool llapi_layout_stripe_index_is_valid(int64_t stripe_index)
675 return stripe_index == LLAPI_LAYOUT_DEFAULT ||
676 (stripe_index >= 0 &&
677 llapi_stripe_index_is_valid(stripe_index));
681 * Set the stripe count of \a layout.
683 * \param[in] layout layout to set stripe count in
684 * \param[in] count value to be set
686 * \retval 0 on success
687 * \retval -1 if arguments are invalid
689 int llapi_layout_stripe_count_set(struct llapi_layout *layout,
692 if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC ||
693 !llapi_layout_stripe_count_is_valid(count)) {
698 layout->llot_stripe_count = count;
704 * Get the stripe size of \a layout.
706 * \param[in] layout layout to get stripe size from
707 * \param[out] size integer to store stripe size in
709 * \retval 0 on success
710 * \retval -1 if arguments are invalid
712 int llapi_layout_stripe_size_get(const struct llapi_layout *layout,
715 if (layout == NULL || size == NULL ||
716 layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
721 *size = layout->llot_stripe_size;
727 * Set the stripe size of \a layout.
729 * \param[in] layout layout to set stripe size in
730 * \param[in] size value to be set
732 * \retval 0 on success
733 * \retval -1 if arguments are invalid
735 int llapi_layout_stripe_size_set(struct llapi_layout *layout,
738 if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC ||
739 !llapi_layout_stripe_size_is_valid(size)) {
744 layout->llot_stripe_size = size;
750 * Get the RAID pattern of \a layout.
752 * \param[in] layout layout to get pattern from
753 * \param[out] pattern integer to store pattern in
755 * \retval 0 on success
756 * \retval -1 if arguments are invalid
758 int llapi_layout_pattern_get(const struct llapi_layout *layout,
761 if (layout == NULL || pattern == NULL ||
762 layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
767 *pattern = layout->llot_pattern;
773 * Set the RAID pattern of \a layout.
775 * \param[in] layout layout to set pattern in
776 * \param[in] pattern value to be set
778 * \retval 0 on success
779 * \retval -1 if arguments are invalid or RAID pattern
782 int llapi_layout_pattern_set(struct llapi_layout *layout, uint64_t pattern)
784 if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC) {
789 if (pattern != LLAPI_LAYOUT_DEFAULT ||
790 pattern != LLAPI_LAYOUT_RAID0) {
795 layout->llot_pattern = pattern;
801 * Set the OST index of stripe number \a stripe_number to \a ost_index.
803 * The index may only be set for stripe number 0 for now.
805 * \param[in] layout layout to set OST index in
806 * \param[in] stripe_number stripe number to set index for
807 * \param[in] ost_index the index to set
809 * \retval 0 on success
810 * \retval -1 if arguments are invalid or an unsupported stripe number
813 int llapi_layout_ost_index_set(struct llapi_layout *layout, int stripe_number,
816 if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC ||
817 !llapi_layout_stripe_index_is_valid(ost_index)) {
822 if (stripe_number != 0) {
827 layout->llot_stripe_offset = ost_index;
833 * Get the OST index associated with stripe \a stripe_number.
835 * Stripes are indexed starting from zero.
837 * \param[in] layout layout to get index from
838 * \param[in] stripe_number stripe number to get index for
839 * \param[out] index integer to store index in
841 * \retval 0 on success
842 * \retval -1 if arguments are invalid
844 int llapi_layout_ost_index_get(const struct llapi_layout *layout,
845 uint64_t stripe_number, uint64_t *index)
847 if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC ||
848 stripe_number >= layout->llot_stripe_count ||
849 index == NULL || layout->llot_objects_are_valid == 0) {
854 if (layout->llot_objects[stripe_number].l_ost_idx == -1)
855 *index = LLAPI_LAYOUT_DEFAULT;
857 *index = layout->llot_objects[stripe_number].l_ost_idx;
864 * Get the pool name of layout \a layout.
866 * \param[in] layout layout to get pool name from
867 * \param[out] dest buffer to store pool name in
868 * \param[in] n size in bytes of buffer \a dest
870 * \retval 0 on success
871 * \retval -1 if arguments are invalid
873 int llapi_layout_pool_name_get(const struct llapi_layout *layout, char *dest,
876 if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC ||
882 strncpy(dest, layout->llot_pool_name, n);
888 * Set the name of the pool of layout \a layout.
890 * \param[in] layout layout to set pool name in
891 * \param[in] pool_name pool name to set
893 * \retval 0 on success
894 * \retval -1 if arguments are invalid or pool name is too long
896 int llapi_layout_pool_name_set(struct llapi_layout *layout,
897 const char *pool_name)
901 if (layout == NULL || layout->llot_magic != LLAPI_LAYOUT_MAGIC ||
907 /* Strip off any 'fsname.' portion. */
908 ptr = strchr(pool_name, '.');
912 if (strlen(pool_name) > LOV_MAXPOOLNAME) {
917 strncpy(layout->llot_pool_name, pool_name,
918 sizeof(layout->llot_pool_name));
924 * Open and possibly create a file with a given \a layout.
926 * If \a layout is NULL this function acts as a simple wrapper for
927 * open(). By convention, ENOTTY is returned in errno if \a path
928 * refers to a non-Lustre file.
930 * \param[in] path name of the file to open
931 * \param[in] open_flags open() flags
932 * \param[in] mode permissions to create new file with
933 * \param[in] layout layout to create new file with
935 * \retval non-negative file descriptor on successful open
936 * \retval -1 if an error occurred
938 int llapi_layout_file_open(const char *path, int open_flags, mode_t mode,
939 const struct llapi_layout *layout)
944 struct lov_user_md *lum;
948 (layout != NULL && layout->llot_magic != LLAPI_LAYOUT_MAGIC)) {
953 /* Object creation must be postponed until after layout attributes
954 * have been applied. */
955 if (layout != NULL && (open_flags & O_CREAT))
956 open_flags |= O_LOV_DELAY_CREATE;
958 fd = open(path, open_flags, mode);
960 if (layout == NULL || fd < 0)
963 lum = llapi_layout_to_lum(layout);
972 lum_size = lov_user_md_size(0, lum->lmm_magic);
974 rc = fsetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_size, 0);
983 errno = errno == EOPNOTSUPP ? ENOTTY : errno;
989 * Create a file with a given \a layout.
991 * Force O_CREAT and O_EXCL flags on so caller is assured that file was
992 * created with the given \a layout on successful function return.
994 * \param[in] path name of the file to open
995 * \param[in] open_flags open() flags
996 * \param[in] mode permissions to create new file with
997 * \param[in] layout layout to create new file with
999 * \retval non-negative file descriptor on successful open
1000 * \retval -1 if an error occurred
1002 int llapi_layout_file_create(const char *path, int open_flags, int mode,
1003 const struct llapi_layout *layout)
1005 return llapi_layout_file_open(path, open_flags|O_CREAT|O_EXCL, mode,