From 30d55877c30ca06db4003b70025fcc526e144569 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Tue, 25 Sep 2018 12:17:46 +0200 Subject: [PATCH] LU-11417 llapi: add llapi_layout_get_by_xattr(3) API Add new llapi_layout_get_by_xattr(3) interface to be able to extract a layout structure from a LOV EA xattr. This can be useful when the xattr is retrieved from some external source (e.g. tarball, HSM, or tools that directly access the underlying ldiskfs or ZFS filesystem). Signed-off-by: Andreas Dilger Change-Id: I9b405bf6b3119e44097f36d49ac5859ff93ebbe5 Reviewed-on: https://review.whamcloud.com/33230 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Jian Yu Reviewed-by: Li Xi Reviewed-by: Oleg Drokin --- lustre/doc/llapi_layout.7 | 4 +++- lustre/doc/llapi_layout_get_by_fd.3 | 10 ++++++++++ lustre/doc/llapi_layout_get_by_xattr.3 | 1 + lustre/utils/liblustreapi_layout.c | 23 ++++++++++++++++------- 4 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 lustre/doc/llapi_layout_get_by_xattr.3 diff --git a/lustre/doc/llapi_layout.7 b/lustre/doc/llapi_layout.7 index c077c04..0c1a622 100644 --- a/lustre/doc/llapi_layout.7 +++ b/lustre/doc/llapi_layout.7 @@ -50,8 +50,9 @@ One can allocate and initialize a new from an existing file with one of the .BR llapi_layout_get_by_path (3), .BR llapi_layout_get_by_fd (3), +.BR llapi_layout_get_by_fid (3), or -.BR llapi_layout_get_by_fid (3) +.BR llapi_layout_get_by_xattr (3) functions. .IP \[bu] To access attribute values from @@ -194,6 +195,7 @@ The RAID pattern may only be set to 0. .BR llapi_layout_get_by_fd (3), .BR llapi_layout_get_by_fid (3), .BR llapi_layout_get_by_path (3), +.BR llapi_layout_get_by_xattr (3), .BR llapi_layout_ost_index_get (3), .BR llapi_layout_ost_index_set (3), .BR llapi_layout_pattern_get (3), diff --git a/lustre/doc/llapi_layout_get_by_fd.3 b/lustre/doc/llapi_layout_get_by_fd.3 index ed08d20..bb4451e 100644 --- a/lustre/doc/llapi_layout_get_by_fd.3 +++ b/lustre/doc/llapi_layout_get_by_fd.3 @@ -6,6 +6,8 @@ obtain the layout of a Lustre file .nf .B #include .PP +.BI "struct llapi_layout *llapi_layout_get_by_xattr(const void *"lov_xattr ", +.BI " ssize_t " lov_xattr_size ); .BI "struct llapi_layout *llapi_layout_get_by_fd(int "fd ", uint32_t " flags ); .PP .BI "struct llapi_layout *llapi_layout_get_by_fid(const char *"lustre_path , @@ -17,6 +19,7 @@ obtain the layout of a Lustre file .fi .SH DESCRIPTION .PP +.BR llapi_layout_get_by_xattr() , .BR llapi_layout_get_by_fd() , .BR llapi_layout_get_by_fid() , and @@ -24,6 +27,7 @@ and return a pointer to a newly-allocated .B struct llapi_layout containing the layout information for the file referenced by +.IR lov_xattr , .IR fd , .IR fid , or @@ -39,6 +43,12 @@ The pointer should be freed with when it is no longer needed. .PP For +.BR llapi_layout_get_by_xattr() , +.I lov_xattr +is a Lustre layout extended attribute (LOV EA) from a file or directory in +a Lustre filesystem. +.PP +For .BR llapi_layout_get_by_fd() , .I fd is a valid open file descriptor for a file or directory in a Lustre diff --git a/lustre/doc/llapi_layout_get_by_xattr.3 b/lustre/doc/llapi_layout_get_by_xattr.3 new file mode 100644 index 0000000..5a4e926 --- /dev/null +++ b/lustre/doc/llapi_layout_get_by_xattr.3 @@ -0,0 +1 @@ +.so man3/llapi_layout_get_by_fd.3 diff --git a/lustre/utils/liblustreapi_layout.c b/lustre/utils/liblustreapi_layout.c index f8b3ea6..f84b3b3 100644 --- a/lustre/utils/liblustreapi_layout.c +++ b/lustre/utils/liblustreapi_layout.c @@ -360,15 +360,16 @@ struct llapi_layout *llapi_layout_alloc(void) * Convert the data from a lov_user_md to a newly allocated llapi_layout. * The caller is responsible for freeing the returned pointer. * - * \param[in] lum LOV user metadata structure to copy data from - * \param[in] lum_size size the the lum passed in + * \param[in] lov_xattr LOV user metadata xattr to copy data from + * \param[in] lov_xattr_size size the lov_xattr_size passed in * * \retval valid llapi_layout pointer on success * \retval NULL if memory allocation fails */ -static struct llapi_layout * -llapi_layout_from_lum(const struct lov_user_md *lum, int lum_size) +struct llapi_layout *llapi_layout_get_by_xattr(const void *lov_xattr, + ssize_t lov_xattr_size) { + const struct lov_user_md *lum = lov_xattr; struct lov_comp_md_v1 *comp_v1 = NULL; struct lov_comp_md_entry_v1 *ent; struct lov_user_md *v1; @@ -392,6 +393,14 @@ llapi_layout_from_lum(const struct lov_user_md *lum, int lum_size) lum->lmm_magic == LOV_MAGIC_V3) { ent_count = 1; layout->llot_is_composite = false; + + if (lov_xattr_size <= 0) { + errno = EINVAL; + goto error; + } + } else { + errno = EOPNOTSUPP; + goto error; } if (ent_count == 0) { @@ -405,12 +414,12 @@ llapi_layout_from_lum(const struct lov_user_md *lum, int lum_size) ent = &comp_v1->lcm_entries[i]; v1 = (struct lov_user_md *)((char *)comp_v1 + ent->lcme_offset); - lum_size = ent->lcme_size; + lov_xattr_size = ent->lcme_size; } else { ent = NULL; } - obj_count = llapi_layout_objects_in_lum(v1, lum_size); + obj_count = llapi_layout_objects_in_lum(v1, lov_xattr_size); comp = __llapi_comp_alloc(obj_count); if (comp == NULL) goto error; @@ -884,7 +893,7 @@ struct llapi_layout *llapi_layout_get_by_fd(int fd, uint32_t flags) goto out; } - layout = llapi_layout_from_lum(lum, bytes_read); + layout = llapi_layout_get_by_xattr(lum, bytes_read); out: free(lum); return layout; -- 1.8.3.1