/** * Get the layout for the file with FID \a fidstr in filesystem \a lustre_dir. * * \param[in] lustre_dir path within Lustre filesystem containing \a fid * \param[in] fid Lustre identifier of file to get layout for * * \retval valid llapi_layout pointer on success * \retval NULL if an error occurs */ struct llapi_layout *llapi_layout_get_by_fid(const char *lustre_dir, const lustre_fid *fid, uint32_t flags) { int fd; int tmp; int saved_msg_level = llapi_msg_get_level(); struct llapi_layout *layout = NULL; /* Prevent llapi internal routines from writing to console * while executing this function, then restore previous message * level. */ llapi_msg_set_level(LLAPI_MSG_OFF); fd = llapi_open_by_fid(lustre_dir, fid, O_RDONLY); llapi_msg_set_level(saved_msg_level); if (fd < 0) return NULL; layout = llapi_layout_get_by_fd(fd, flags); tmp = errno; close(fd); errno = tmp; return layout; }
/** * Get the striping layout for the file at \a path. * * If \a flags contains LAYOUT_GET_EXPECTED, substitute * expected inherited attribute values for unspecified attributes. See * llapi_layout_expected(). * * \param[in] path path for which to get the layout * \param[in] flags flags to control how layout is retrieved * * \retval valid llapi_layout pointer on success * \retval NULL if an error occurs */ struct llapi_layout *llapi_layout_get_by_path(const char *path, uint32_t flags) { struct llapi_layout *layout = NULL; int fd; int tmp; if (flags & LAYOUT_GET_EXPECTED) return llapi_layout_expected(path); fd = open(path, O_RDONLY); if (fd < 0) return layout; layout = llapi_layout_get_by_fd(fd, flags); tmp = errno; close(fd); errno = tmp; return layout; }
void test2(void) { int fd; int rc; char path[PATH_MAX]; snprintf(path, sizeof(path), "%s/%s", lustre_dir, T0FILE); fd = open(path, O_RDONLY); ASSERTF(fd >= 0, "open(%s): errno = %d", path, errno); struct llapi_layout *layout = llapi_layout_get_by_fd(fd, 0); ASSERTF(layout != NULL, "errno = %d", errno); rc = close(fd); ASSERTF(rc == 0, "close(%s): errno = %d", path, errno); __test1_helper(layout); llapi_layout_free(layout); }
/** * Get the expected striping layout for a file at \a path. * * Substitute expected inherited attribute values for unspecified * attributes. Unspecified attributes may belong to directories and * never-written-to files, and indicate that default values will be * assigned when files are created or first written to. A default value * is inherited from the parent directory if the attribute is specified * there, otherwise it is inherited from the filesystem root. * Unspecified attributes normally have the value LLAPI_LAYOUT_DEFAULT. * * The complete \a path need not refer to an existing file or directory, * but some leading portion of it must reside within a lustre filesystem. * A use case for this interface would be to obtain the literal striping * values that would be assigned to a new file in a given directory. * * \param[in] path path for which to get the expected layout * * \retval valid llapi_layout pointer on success * \retval NULL if an error occurs */ static struct llapi_layout *llapi_layout_expected(const char *path) { struct llapi_layout *path_layout = NULL; struct llapi_layout *donor_layout; char donor_path[PATH_MAX]; struct stat st; int fd; int rc; fd = open(path, O_RDONLY); if (fd < 0 && errno != ENOENT) return NULL; if (fd >= 0) { int tmp; path_layout = llapi_layout_get_by_fd(fd, 0); tmp = errno; close(fd); errno = tmp; } if (path_layout == NULL) { if (errno != ENODATA && errno != ENOENT) return NULL; path_layout = llapi_layout_alloc(); if (path_layout == NULL) return NULL; } if (is_fully_specified(path_layout)) return path_layout; rc = stat(path, &st); if (rc < 0 && errno != ENOENT) { llapi_layout_free(path_layout); return NULL; } /* If path is a not a directory or doesn't exist, inherit unspecified * attributes from parent directory. */ if ((rc == 0 && !S_ISDIR(st.st_mode)) || (rc < 0 && errno == ENOENT)) { get_parent_dir(path, donor_path, sizeof(donor_path)); donor_layout = llapi_layout_get_by_path(donor_path, 0); if (donor_layout != NULL) { inherit_layout_attributes(donor_layout, path_layout); llapi_layout_free(donor_layout); if (is_fully_specified(path_layout)) return path_layout; } } /* Inherit remaining unspecified attributes from the filesystem root. */ rc = llapi_search_mounts(path, 0, donor_path, NULL); if (rc < 0) { llapi_layout_free(path_layout); return NULL; } donor_layout = llapi_layout_get_by_path(donor_path, 0); if (donor_layout == NULL) { llapi_layout_free(path_layout); return NULL; } inherit_layout_attributes(donor_layout, path_layout); llapi_layout_free(donor_layout); return path_layout; }
void test6(void) { errno = 0; struct llapi_layout *layout = llapi_layout_get_by_fd(9999, 0); ASSERTF(layout == NULL && errno == EBADF, "errno = %d", errno); }