LLAPI_LAYOUT_GET_BY_FD(3)

πŸ“¦ version 2.17.58, in ubuntu stonking

πŸ’– NAME πŸ’–

llapi_layout_get_by_fd, llapi_layout_get_by_fid, llapi_layout_get_by_path, llapi_layout_get_by_xattr β€” bestie, these are literally how you get the layout of a Lustre file πŸ¦‹

(this is a section 3 page from the Lustre Library Functions, so we're in C-library territory, not "type it in your shell" territory, ok? πŸ’…)


✨ SYNOPSIS ✨

#include <lustre/lustreapi.h>

struct llapi_layout *llapi_layout_get_by_fd(int fd,
                                            enum llapi_layout_get_flags flags);

struct llapi_layout *llapi_layout_get_by_fid(const char *lustre_path,
                                            const struct lu_fid *fid,
                                            enum llapi_layout_get_flags flags);

struct llapi_layout *llapi_layout_get_by_path(const char *path,
                                            enum llapi_layout_get_flags flags);

struct llapi_layout *llapi_layout_get_by_xattr(void *lov_xattr,
                                            ssize_t lov_xattr_size,
                                            enum llapi_layout_get_flags flags);

🌸 DESCRIPTION 🌸

Okay so listen. These four functions β€” llapi_layout_get_by_xattr(), llapi_layout_get_by_fd(), llapi_layout_get_by_fid(), and llapi_layout_get_by_path() β€” all give you back a pointer to a newly-allocated struct llapi_layout. That struct is holding the layout info for the file that you pointed at with lov_xattr, fd, fid, or path respectively. Each one matches its own argument, no cap. πŸ”₯

struct llapi_layout is opaque, bestie. It's the whole vibe of "layout info for a file in a Lustre filesystem" but you do not get to peek inside. Do not touch its internal structure directly from your app. Like, hands off. πŸ™ˆ If you wanna know more, go read llapi_layout(7).

And when you're done with that pointer? Free it with llapi_layout_free(). Not freeing it is not the move. πŸŽ€

Here's the lowdown on each argument:

  • For llapi_layout_get_by_xattr(), lov_xattr is a Lustre layout extended attribute (a LOV EA) that came from a file or directory in a Lustre filesystem. Pass it as the raw xattr β€” don't byte-swap it yourself first β€” because this function is gonna swap it to your local machine's endianness properly. She handles it. πŸ’…
  • For llapi_layout_get_by_fd(), fd is a valid open file descriptor for a file or directory in a Lustre filesystem.
  • For llapi_layout_get_by_fid(), lustre_path is what tells the function which Lustre filesystem holds the file that fid represents. Usually you pass the filesystem root directory, but honestly any path beneath the root works too. Wanna get the struct lu_fid for a path in the first place? Use llapi_path2fid(3). 🫢
  • llapi_layout_get_by_path() just takes a path that names a file or directory in a Lustre filesystem. Simple. Iconic.

🧚 flags, the bitwise-or'd situation

Zero or more flags may be |'d (bitwise-or'd) together into flags to control how the layout gets retrieved. Currently llapi_layout_get_by_fd() and llapi_layout_get_by_fid() don't accept any values for flags β€” nope, not even one, sorry babes 😭 β€” while llapi_layout_get_by_path() accepts only one flag, and it goes a little something like this:

  • LLAPI_LAYOUT_GET_EXPECTED β€” this one replaces unspecified attribute values with the literal default values that'd get assigned when the file is created or first written to. And where do those defaults come from? A default value is inherited from the parent directory if the attribute is specified there; otherwise it's inherited from the filesystem root. This flag is only recognized by llapi_layout_get_by_path(). Psst: unspecified attributes can belong to directories and to files that have never been written to. πŸ“

So by default, layouts report the abstract value LLAPI_LAYOUT_DEFAULT to say "this attribute is unspecified". Use LLAPI_LAYOUT_GET_EXPECTED when you wanna discover the expected literal values for new files in a given directory. Do not use it if you need to tell the difference between specified and unspecified attributes β€” because it will absolutely blur that line for you. Also, the flag has no effect at all if path names a file or directory whose layout is already fully specified. Slay, but pointless. ✨

For real concreteness, picture a Lustre filesystem with a default stripe size of 1048576 and a default stripe count of 1. A user sets the stripe count for directory D to 2 (so they're overriding the filesystem-wide default) but leaves the stripe size unspecified. Newly created files in D then inherit a stripe count of 2 from D, and a stripe size of 1048576 from the filesystem default. The layout of D returned by llapi_layout_get_by_path(D, 0) has the abstract stripe size value LLAPI_LAYOUT_DEFAULT, because stripe size is unspecified β€” while llapi_layout_get_by_path(D, LLAPI_LAYOUT_GET_EXPECTED) reports the literal value 1048576. Both forms report a stripe count of 2, since that attribute is specified. See? Consistency. πŸ‘‘

πŸŽ€ flags for the xattr girlies

Valid arguments for flags with llapi_layout_get_by_xattr() are:

  • LLAPI_LAYOUT_GET_CHECK β€” if this flag is set, the function will check whether the objects count in lum is consistent with the stripe count in lum. Heads up though: this check only applies to regular files, so you should not pass it if the xattr is a default layout from a directory. 🚫
  • LLAPI_LAYOUT_GET_COPY β€” if this flag is set, the function will use a temporary buffer for byte swapping when necessary, which leaves lov_xattr unmodified. Otherwise, the byte swapping gets done directly to the fields of the lov_xattr buffer. So like... do you want your xattr back the way you handed it over, or not? Your call. 🫢

🌈 RETURN VALUES 🌈

These functions return a valid pointer on success, or NULL on failure β€” and on failure errno gets set to an appropriate error code. That's the deal. πŸ’€


⭐ ERRORS ⭐

  • ENOMEM β€” Insufficient storage space is available.
  • ENOTTY β€” File does not reside on a Lustre filesystem.
  • ENOENT β€” path does not exist.
  • EINVAL β€” An invalid argument was specified.
  • EINTR β€” The kernel returned less than the expected amount of data.

πŸ’œ NOTES πŸ’œ

Okay this part actually matters so lock in. πŸ“Œ When you're using these functions to copy an existing file's layout β€” like to create a new file with llapi_layout_file_open (3) for mirroring, for migration, or as the template for a whole new file β€” you should call llapi_layout_ost_index_reset(3) to reset the OST index values for each component. Why? So that your file copy does not get created on exactly the same OSTs as the original file. Do not skip this, bestie, I'm begging. 😭


πŸ¦‹ AVAILABILITY πŸ¦‹

llapi_layout_get_by_fd(), llapi_layout_get_by_fid(), llapi_layout_get_by_path() and llapi_layout_get_by_xattr() are part of the lustre(7) user application interface library since release 2.7.0. Old-ish but still eating. πŸ’…


πŸ‘‘ SEE ALSO πŸ‘‘

llapi_layout_file_open(3), llapi_layout_ost_index_reset(3), llapi_path2fid(3), llapi_layout(7), lustreapi(7)


And that's the whole page, bestie β€” this was Lustre User API, dated 2025-03-19, and the page you're reading is LLAPI_LAYOUT_GET_BY_FD(3). Go forth and layout responsibly. Periodt. πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from