From a4c8c816a67af216f20439cf79750a1f8d09d1f2 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Thu, 10 Mar 2022 17:20:27 -0600 Subject: [PATCH] EX-4965 lipe: use new e2fsprogs xattr API Switch to the ext2fs_xattr_handle API since this handles xattrs stored in a separate file. Add sanity-lipe test_100() to verify. Test-Parameters: testlist=sanity-lipe Signed-off-by: John L. Hammond Change-Id: Ibc39d01ecfb04307755f44751fc69ffbd79b5d69 Reviewed-on: https://review.whamcloud.com/46784 Tested-by: jenkins Reviewed-by: Andreas Dilger --- lipe/src/lamigo.c | 9 +- lipe/src/lipe_ldiskfs.c | 19 +- lipe/src/lipe_object_attrs.c | 48 ++--- lipe/src/lipe_object_attrs.h | 12 +- lipe/src/lipe_zfs.c | 44 +++-- lipe/src/lustre_ea.c | 22 +++ lipe/src/lustre_ea.h | 3 +- lipe/src/lustre_ea_ldiskfs.c | 422 ++++++++++++++++++++++++------------------- lipe/src/policy.c | 8 +- lipe/src/policy.h | 1 + lipe/src/posix_ea.c | 47 ++--- lustre/tests/sanity-lipe.sh | 20 ++ 12 files changed, 373 insertions(+), 282 deletions(-) diff --git a/lipe/src/lamigo.c b/lipe/src/lamigo.c index 9099530..5260ec6 100644 --- a/lipe/src/lamigo.c +++ b/lipe/src/lamigo.c @@ -1143,10 +1143,11 @@ static int lamigo_get_attrs(const struct lu_fid *fid, } if (need_attr & LIPE_OBJECT_ATTR_LINKEA) { - rc = fgetxattr(fd, XATTR_NAME_LINK, attrs->loa_leh_buf, - sizeof(attrs->loa_leh_buf)); + char buf[XATTR_SIZE_MAX]; + + rc = fgetxattr(fd, XATTR_NAME_LINK, buf, sizeof(buf)); if (rc >= 0) - rc = lipe_object_attrs_set_links(attrs, attrs->loa_leh_buf, rc); + rc = lipe_object_attrs_set_links(attrs, buf, rc); } if (need_attr & LIPE_OBJECT_ATTR_HSMEA) { @@ -2492,7 +2493,7 @@ static int lamigo_lipe_callback(struct lipe_instance *instance, goto out; } - resync = lamigo_striping_is_in_sync((void *)attrs->loa_lum, fast_pools, + resync = lamigo_striping_is_in_sync(attrs->loa_lum, fast_pools, slow_pools, &mo); if (resync == AMIGO_RESYNC_NONE) { lamigo_hist_add(&attrs->loa_fid, resync); diff --git a/lipe/src/lipe_ldiskfs.c b/lipe/src/lipe_ldiskfs.c index 33d2b5e..848bb8d 100644 --- a/lipe/src/lipe_ldiskfs.c +++ b/lipe/src/lipe_ldiskfs.c @@ -165,7 +165,7 @@ static int ldiskfs_scan_groups(ext2_inode_scan scan, /* skip snapshot inodes */ continue; } - + if (!LINUX_S_ISDIR(inode->i_mode) && (inode->i_flags & EXT2_NODUMP_FL)) { /* skip files which are not to be backuped */ @@ -185,6 +185,11 @@ static int ldiskfs_scan_groups(ext2_inode_scan scan, LDEBUG("failed to apply policy on inode [%d]\n", ino); rc = 0; } + + if (object->u.lo_ldiskfs.lol_xattr_handle != NULL) + ext2fs_xattrs_close(&object->u.lo_ldiskfs.lol_xattr_handle); + + object->u.lo_ldiskfs.lol_xattr_handle = NULL; } return rc; @@ -196,7 +201,10 @@ void *ldiskfs_scan_thread(void *arg) struct lipe_instance *instance = info->ti_instance; const char *dev = instance->li_device; struct scan_result *result = &info->ti_result; - struct lipe_object object; + struct lipe_object object = { + .lo_backfs_ops = &ldiskfs_operations, + .lo_backfs_type = instance->li_detected_fstype, + }; ext2_filsys fs; ext2_inode_scan scan; struct ext2_inode_large *inode; @@ -212,9 +220,6 @@ void *ldiskfs_scan_thread(void *arg) goto out; } - object.lo_backfs_ops = &ldiskfs_operations; - object.lo_backfs_type = instance->li_detected_fstype; - gettimeofday(&result->sr_time_start, NULL); sysattrs.lps_sys_time = result->sr_time_start.tv_sec * 1000 + result->sr_time_start.tv_usec / 1000; @@ -228,8 +233,6 @@ void *ldiskfs_scan_thread(void *arg) goto out_free_attrs; } - object.u.lo_ldiskfs.lol_fs = fs; - rc = ext2fs_read_inode_bitmap(fs); if (rc) { LERROR("failed to ext2fs_read_inode_bitmap on [%s]: %s\n", dev, @@ -244,7 +247,6 @@ void *ldiskfs_scan_thread(void *arg) goto out_close; } - inode_size = EXT2_INODE_SIZE(fs->super); if (inode_size < sizeof(*inode)) inode_size = sizeof(*inode); @@ -255,6 +257,7 @@ void *ldiskfs_scan_thread(void *arg) goto out_scan; } + object.u.lo_ldiskfs.lol_fs = fs; object.u.lo_ldiskfs.lol_inode = inode; while (1) { diff --git a/lipe/src/lipe_object_attrs.c b/lipe/src/lipe_object_attrs.c index 669de48..4295c1e 100644 --- a/lipe/src/lipe_object_attrs.c +++ b/lipe/src/lipe_object_attrs.c @@ -307,32 +307,9 @@ static void lipe_object_attrs_xattrs_fini(struct lipe_object_attrs *attrs) LASSERT(lipe_list_empty(&attrs->loa_xattrs)); } -void lipe_object_attrs_reset(struct lipe_object_attrs *attrs) -{ - struct lov_user_md *lum = attrs->loa_lum; - int lum_size = attrs->loa_lum_size; - - lipe_object_attrs_links_fini(attrs); - lipe_object_attrs_paths_fini(attrs); - lipe_object_attrs_xattrs_fini(attrs); - memset(lum, 0, lum_size); - memset(attrs, 0, sizeof(*attrs)); - attrs->loa_lum = lum; - attrs->loa_lum_size = lum_size; - LIPE_INIT_LIST_HEAD(&attrs->loa_links); - LIPE_INIT_LIST_HEAD(&attrs->loa_paths); - LIPE_INIT_LIST_HEAD(&attrs->loa_xattrs); -} - int lipe_object_attrs_init(struct lipe_object_attrs *attrs) { memset(attrs, 0, sizeof(*attrs)); - attrs->loa_lum_size = lov_user_md_size(LOV_MAX_STRIPE_COUNT, - LOV_USER_MAGIC_V3); - LIPE_ALLOC(attrs->loa_lum, attrs->loa_lum_size); - if (attrs->loa_lum == NULL) - return -ENOMEM; - LIPE_INIT_LIST_HEAD(&attrs->loa_links); LIPE_INIT_LIST_HEAD(&attrs->loa_paths); LIPE_INIT_LIST_HEAD(&attrs->loa_xattrs); @@ -345,16 +322,26 @@ void lipe_object_attrs_fini(struct lipe_object_attrs *attrs) lipe_object_attrs_links_fini(attrs); lipe_object_attrs_paths_fini(attrs); lipe_object_attrs_xattrs_fini(attrs); - LIPE_FREE(attrs->loa_lum, attrs->loa_lum_size); + free(attrs->loa_lum); + free(attrs->loa_lmv); +} + +void lipe_object_attrs_reset(struct lipe_object_attrs *attrs) +{ + lipe_object_attrs_fini(attrs); + lipe_object_attrs_init(attrs); } int lipe_object_attrs_add_link(struct lipe_object_attrs *attrs, const struct lu_fid *parent_fid, - const char *name) + const char *name, int namelen) { struct lipe_link_entry *lle = NULL; int rc; + if (namelen <= 0) + return -EOVERFLOW; /* ? */ + LIPE_ALLOC_PTR(lle); if (lle == NULL) { rc = -ENOMEM; @@ -363,7 +350,7 @@ int lipe_object_attrs_add_link(struct lipe_object_attrs *attrs, lle->lle_parent_fid = *parent_fid; - lle->lle_name = strdup(name); + lle->lle_name = strndup(name, namelen); if (lle->lle_name == NULL) { rc = -ENOMEM; goto out; @@ -418,6 +405,7 @@ int lipe_object_attrs_set_links(struct lipe_object_attrs *attrs, for (i = 0; i < reccount; i++) { unsigned int reclen = (lee->lee_reclen[0] << 8) | lee->lee_reclen[1]; struct lu_fid parent_fid; + int namelen; pos += reclen; if (pos > len) { @@ -428,10 +416,12 @@ int lipe_object_attrs_set_links(struct lipe_object_attrs *attrs, fid_be_to_cpu(&parent_fid, (const struct lu_fid *)&lee->lee_parent_fid); - LDEBUG(" %d: parent_fid "DFID", name '%s'\n", - i, PFID(&parent_fid), lee->lee_name); + namelen = reclen - offsetof(struct link_ea_entry, lee_name[0]); + + LDEBUG(" %d: parent_fid "DFID", name '%.*s'\n", + i, PFID(&parent_fid), namelen, lee->lee_name); - rc = lipe_object_attrs_add_link(attrs, &parent_fid, lee->lee_name); + rc = lipe_object_attrs_add_link(attrs, &parent_fid, lee->lee_name, namelen); if (rc < 0) return rc; diff --git a/lipe/src/lipe_object_attrs.h b/lipe/src/lipe_object_attrs.h index ea5a353..38ccbd9 100644 --- a/lipe/src/lipe_object_attrs.h +++ b/lipe/src/lipe_object_attrs.h @@ -130,12 +130,10 @@ struct lipe_object_attrs { struct lu_fid loa_fid; char loa_fid_str[FID_NOBRACE_LEN + 1]; __u64 loa_attr_bits; - /* Buffer for struct link_ea_header */ - char loa_leh_buf[MAX_LINKEA_SIZE]; - /* Buffer for lmv */ - char loa_lmv_buf[XATTR_SIZE_MAX]; - struct lov_user_md *loa_lum; - int loa_lum_size; + void *loa_lmv; + size_t loa_lmv_size; + void *loa_lum; + size_t loa_lum_size; struct hsm_user_state loa_hsm_state; enum lustre_dom_status loa_dom_status; struct lustre_som_attrs loa_som; @@ -193,7 +191,7 @@ void lipe_object_attrs_fini(struct lipe_object_attrs *attrs); void lipe_object_attrs_reset(struct lipe_object_attrs *attrs); int lipe_object_attrs_add_link(struct lipe_object_attrs *attrs, const struct lu_fid *parent_fid, - const char *name); + const char *name, int namelen); int lipe_object_attrs_set_links(struct lipe_object_attrs *attrs, const void *link_xattr, size_t link_xattr_size); diff --git a/lipe/src/lipe_zfs.c b/lipe/src/lipe_zfs.c index 441575c..5f72c47 100644 --- a/lipe/src/lipe_zfs.c +++ b/lipe/src/lipe_zfs.c @@ -85,21 +85,19 @@ close_objset(objset_t *os, void *tag) static int zfs_get_xattr(struct lipe_object *lobject, struct lipe_object_attrs *attrs, - const char *xattr_name, uchar_t *value, uint_t cnt) + const char *xattr_name, void *value, size_t value_size) { int rc; - rc = lipe_object_attrs_add_xattr(attrs, xattr_name, (const char *)value, - cnt); + rc = lipe_object_attrs_add_xattr(attrs, xattr_name, value, value_size); if (rc) { OBJ_ERROR(lobject, "failed to add xattr [%s]\n", xattr_name); return rc; } if (strcmp(xattr_name, XATTR_NAME_LMA) == 0) { - struct lustre_mdt_attrs *lma; + struct lustre_mdt_attrs *lma = value; - lma = (struct lustre_mdt_attrs *)value; fid_le_to_cpu(&attrs->loa_fid, &lma->lma_self_fid); snprintf(attrs->loa_fid_str, sizeof(attrs->loa_fid_str), DFID_NOBRACE, @@ -109,30 +107,25 @@ static int zfs_get_xattr(struct lipe_object *lobject, struct filter_fid *ff = &attrs->loa_filter_fid; struct lu_fid pfid; - memcpy(ff, value, cnt); + memcpy(ff, value, value_size); fid_le_to_cpu(&pfid, &ff->ff_parent); ff->ff_parent = pfid; attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_FILTER_FID; - attrs->loa_filter_fid_size = cnt; + attrs->loa_filter_fid_size = value_size; } else if (strcmp(xattr_name, XATTR_NAME_LINK) == 0) { - memcpy(attrs->loa_leh_buf, value, cnt); - - rc = lipe_object_attrs_set_links(attrs, value, cnt); + rc = lipe_object_attrs_set_links(attrs, value, value_size); if (rc) { OBJ_ERROR(lobject, "failed to decode linkea\n"); return rc; } } else if (strcmp(xattr_name, XATTR_NAME_LMV) == 0) { - if (cnt > sizeof(attrs->loa_lmv_buf)) { - OBJ_ERROR(lobject, "invalid lmv ea\n"); - return -EINVAL; - } - memcpy(attrs->loa_lmv_buf, value, cnt); + rc = xmemdup(&attrs->loa_lmv, &attrs->loa_lmv_size, value, value_size); + if (rc < 0) + return rc; } else if (strcmp(xattr_name, XATTR_NAME_HSM) == 0) { + struct hsm_attrs *hsm = value; struct hsm_user_state *hus = &attrs->loa_hsm_state; - struct hsm_attrs *hsm; - hsm = (struct hsm_attrs *)value; rc = lipe_hsm2user(hsm, hus); if (rc) { OBJ_ERROR(lobject, @@ -142,22 +135,27 @@ static int zfs_get_xattr(struct lipe_object *lobject, } attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_HSMEA; } else if (strcmp(xattr_name, XATTR_NAME_LOV) == 0) { - rc = decode_lum((struct lov_user_md *)value, cnt); + rc = decode_lum(value, value_size); if (rc) { OBJ_ERROR(lobject, "failed to decode LOV EA, rc = %d\n", rc); return rc; } - memcpy(attrs->loa_lum, value, cnt); + + rc = xmemdup(&attrs->loa_lum, &attrs->loa_lum_size, value, value_size); + if (rc < 0) + return rc; + attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_LOVEA; } else if (strcmp(xattr_name, XATTR_NAME_SOM) == 0) { - if (cnt != sizeof(attrs->loa_som)) { + if (value_size != sizeof(attrs->loa_som)) { OBJ_ERROR(lobject, "unexpected size of LSoM xattr, expected [%u] got [%u]\n", - sizeof(attrs->loa_som), cnt); + sizeof(attrs->loa_som), value_size); } - lipe_som_swab((struct lustre_som_attrs *)value); - memcpy(&attrs->loa_som, value, cnt); + + lipe_som_swab(value); + attrs->loa_som = *(struct lustre_som_attrs *)value; } return 0; } diff --git a/lipe/src/lustre_ea.c b/lipe/src/lustre_ea.c index 31b06d2..e6141dc 100644 --- a/lipe/src/lustre_ea.c +++ b/lipe/src/lustre_ea.c @@ -7,13 +7,35 @@ * * Author: Li Xi */ +#include #include #include +#include +#include #include #include #include "lustre_ea.h" #include "debug.h" +int xmemdup(void **pdst, size_t *pdst_size, const void *src, size_t src_size) +{ + void *dst; + + assert(*pdst == NULL); + assert(*pdst_size == 0); + + dst = malloc(src_size); + if (dst == NULL && src_size != 0) + return -ENOMEM; + + memcpy(dst, src, src_size); + + *pdst = dst; + *pdst_size = src_size; + + return 0; +} + /* Copied from Lustre/utils/liblustreapi.c */ static inline struct lov_user_md * lov_comp_entry(struct lov_comp_md_v1 *comp_v1, int ent_idx) diff --git a/lipe/src/lustre_ea.h b/lipe/src/lustre_ea.h index 488ea59..a97fa78 100644 --- a/lipe/src/lustre_ea.h +++ b/lipe/src/lustre_ea.h @@ -9,11 +9,12 @@ */ #ifndef _LIPE_LUSTRE_EA_H_ #define _LIPE_LUSTRE_EA_H_ - +#include #include #include "general_policy.h" #include "lipe_object_attrs.h" +int xmemdup(void **pdst, size_t *pdst_size, const void *src, size_t src_size); int match_lum_ost(struct lov_user_md *lum, int64_t ost_index); int regular_expression_match_lum_pool(struct lov_user_md *lum, regex_t *reg); int shell_pattern_match_lum_pool(struct lov_user_md *lum, char *pattern); diff --git a/lipe/src/lustre_ea_ldiskfs.c b/lipe/src/lustre_ea_ldiskfs.c index 7baa380..0684672 100644 --- a/lipe/src/lustre_ea_ldiskfs.c +++ b/lipe/src/lustre_ea_ldiskfs.c @@ -14,35 +14,12 @@ #include "debug.h" #include "policy.h" -int get_link_ea_ldiskfs(struct lipe_object *object, - struct lipe_object_attrs *attrs) -{ - int size; - int rc; - ext2_filsys fs = object->u.lo_ldiskfs.lol_fs; - ext2_ino_t ino = object->u.lo_ldiskfs.lol_ino; - struct ext2_inode_large *inode = object->u.lo_ldiskfs.lol_inode; - - rc = ext2fs_attr_get(fs, (struct ext2_inode *)inode, - EXT2_ATTR_INDEX_TRUSTED, - XATTR_NAME_LINK + strlen("trusted."), - attrs->loa_leh_buf, sizeof(attrs->loa_leh_buf), - &size); - if (rc) { - LDEBUG("inode [%d] has no [%s] xattr, ignoring rc = %d\n", - ino, XATTR_NAME_LINK, rc); - return -ENODATA; - } - - rc = lipe_object_attrs_set_links(attrs, attrs->loa_leh_buf, size); - if (rc) { - LERROR("failed to decode linkea for inode [%d]\n", ino); - return rc; - } - - attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_LINKEA; - return 0; -} +#define min(x, y) ({ \ + typeof(x) _min1 = (x); \ + typeof(y) _min2 = (y); \ + (void) (&_min1 == &_min2); \ + _min1 < _min2 ? _min1 : _min2; \ +}) /* Due to a bug in e2fsprogs-1.45.6.wc3, and potential ongoing changes in * upstream releases, the definition of EXT2_ET_EA_NAME_NOT_FOUND may be @@ -55,202 +32,281 @@ int get_link_ea_ldiskfs(struct lipe_object *object, #define EXT2_ET_EA_NAME_NOT_FOUND_1456WC3 (2133571514L) #define EXT2_ET_EA_NAME_NOT_FOUND_1462WC3 (2133571515L) +static ext2_ino_t lo_ino(const struct lipe_object *lo) +{ + return lo->u.lo_ldiskfs.lol_ino; +} + static bool xattr_name_not_found(long errcode) { - return errcode == EXT2_ET_EA_NAME_NOT_FOUND || + return errcode == EXT2_ET_EA_KEY_NOT_FOUND || + errcode == EXT2_ET_EA_NAME_NOT_FOUND || errcode == EXT2_ET_EA_NAME_NOT_FOUND_1445WC1 || errcode == EXT2_ET_EA_NAME_NOT_FOUND_1456WC1 || errcode == EXT2_ET_EA_NAME_NOT_FOUND_1456WC3 || errcode == EXT2_ET_EA_NAME_NOT_FOUND_1462WC3; } -int get_lmv_ea_ldiskfs(struct lipe_object *object, - struct lipe_object_attrs *attrs) +static int ldiskfs_xattr_get(struct lipe_object *lo, + const char *name, + void **value, size_t *value_size) { - int size; - long rc; - ext2_filsys fs = object->u.lo_ldiskfs.lol_fs; - ext2_ino_t ino = object->u.lo_ldiskfs.lol_ino; - struct ext2_inode_large *inode = object->u.lo_ldiskfs.lol_inode; - - memset(attrs->loa_lmv_buf, 0, sizeof(attrs->loa_lmv_buf)); - rc = ext2fs_attr_get(fs, (struct ext2_inode *)inode, - EXT2_ATTR_INDEX_TRUSTED, - XATTR_NAME_LMV + strlen("trusted."), - attrs->loa_lmv_buf, sizeof(attrs->loa_lmv_buf), - &size); + ext2_filsys fs = lo->u.lo_ldiskfs.lol_fs; + struct ext2_inode_large *inode = lo->u.lo_ldiskfs.lol_inode; + struct ext2_xattr_handle *handle = NULL; + errcode_t rc; + + assert(*value == NULL); + assert(*value_size == 0); + + if (lo->u.lo_ldiskfs.lol_xattr_handle == NULL) { + rc = ext2fs_xattrs_open(fs, lo_ino(lo), &handle); + if (rc != 0) + goto out; + + rc = ext2fs_xattrs_read_inode(handle, inode); + if (rc != 0) + goto out; + + lo->u.lo_ldiskfs.lol_xattr_handle = handle; + handle = NULL; /* lo owns it now. */ + } + + rc = ext2fs_xattr_get(lo->u.lo_ldiskfs.lol_xattr_handle, name, value, value_size); +out: if (xattr_name_not_found(rc)) { - LDEBUG("inode [%d] has no [%s] xattr ignoring rc = %u\n", - ino, XATTR_NAME_LMV, rc); - return 1; - } else if (rc) { - LERROR("failed to get [%s] xattr for inode [%d], rc = %d\n", - XATTR_NAME_LMV, ino, rc); - return -ENODATA; + rc = -ENODATA; + } else if (rc != 0) { + /* EXT2_ET_EA_TOO_BIG, what else? */ + + LERROR("ino = %u: cannot get '%s' xattr: rc = %ld (%s)\n", + lo_ino(lo), name, rc, error_message(rc)); + rc = -EINVAL; } - return 0; + if (handle != NULL) + ext2fs_xattrs_close(&handle); + + return rc; } -int get_lma_ea_ldiskfs(struct lipe_object *object, - struct lipe_object_attrs *attrs) +static int get_link_ea_ldiskfs(struct lipe_object *lo, struct lipe_object_attrs *loa) { - char buf[MAX_LINKEA_SIZE]; + const char *name = XATTR_NAME_LINK; + void *value = NULL; + size_t value_size = 0; + int rc; + + rc = ldiskfs_xattr_get(lo, name, &value, &value_size); + if (rc != 0) { + LDEBUG("ino = %u: no '%s' xattr, ignoring: rc = %d\n", + lo_ino(lo), name, rc); + goto out; + } + + rc = lipe_object_attrs_set_links(loa, value, value_size); + if (rc != 0) { + LDEBUG("ino = %u: cannot decode '%s' xattr, ignoring: rc = %d\n", + lo_ino(lo), name, rc); + goto out; + } + + loa->loa_attr_bits |= LIPE_OBJECT_ATTR_LINKEA; +out: + free(value); + + return rc; +} + +static int get_lmv_ea_ldiskfs(struct lipe_object *lo, struct lipe_object_attrs *loa) +{ + const char *name = XATTR_NAME_LMV; + void *value = NULL; + size_t value_size = 0; + int rc; + + rc = ldiskfs_xattr_get(lo, name, &value, &value_size); + if (rc != 0) { + LDEBUG("ino = %u: no '%s' xattr, ignoring: rc = %d\n", + lo_ino(lo), name, rc); + goto out; + } + + loa->loa_lmv = value; + loa->loa_lmv_size = value_size; + value = NULL; + value_size = 0; + + /* There is no LIPE_OBJECT_ATTR_LMVEA. */ +out: + free(value); + + return rc; +} + +static int get_lma_ea_ldiskfs(struct lipe_object *lo, struct lipe_object_attrs *loa) +{ + const char *name = XATTR_NAME_LMA; struct lustre_mdt_attrs *lma; - int size; - int rc; - ext2_filsys fs = object->u.lo_ldiskfs.lol_fs; - ext2_ino_t ino = object->u.lo_ldiskfs.lol_ino; - struct ext2_inode_large *inode = object->u.lo_ldiskfs.lol_inode; - - rc = ext2fs_attr_get(fs, (struct ext2_inode *)inode, - EXT2_ATTR_INDEX_TRUSTED, - XATTR_NAME_LMA + strlen("trusted."), - buf, MAX_LINKEA_SIZE, &size); - if (rc) { - LDEBUG("inode [%d] has no [%s] xattr, ignoring rc = %d\n", - ino, XATTR_NAME_LMA, rc); - return -ENODATA; + void *value = NULL; + size_t value_size = 0; + int rc; + + rc = ldiskfs_xattr_get(lo, name, &value, &value_size); + if (rc != 0) { + LDEBUG("ino = %u: no '%s' xattr, ignoring: rc = %d\n", + lo_ino(lo), name, rc); + goto out; } - lma = (struct lustre_mdt_attrs *)buf; - fid_le_to_cpu(&attrs->loa_fid, &lma->lma_self_fid); - snprintf(attrs->loa_fid_str, sizeof(attrs->loa_fid_str), DFID_NOBRACE, - PFID(&attrs->loa_fid)); - attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_LMAEA; - return 0; + /* FIXME Check value_size. */ + + lma = value; + fid_le_to_cpu(&loa->loa_fid, &lma->lma_self_fid); + snprintf(loa->loa_fid_str, sizeof(loa->loa_fid_str), DFID_NOBRACE, + PFID(&loa->loa_fid)); + + loa->loa_attr_bits |= LIPE_OBJECT_ATTR_LMAEA; +out: + free(value); + + return rc; } -int get_hsm_ea_ldiskfs(struct lipe_object *object, - struct lipe_object_attrs *attrs) +static int get_hsm_ea_ldiskfs(struct lipe_object *lo, struct lipe_object_attrs *loa) { - char buf[MAX_LINKEA_SIZE]; - struct hsm_attrs *hsm; - long rc; - int size; - struct hsm_user_state *hus = &attrs->loa_hsm_state; - ext2_filsys fs = object->u.lo_ldiskfs.lol_fs; - ext2_ino_t ino = object->u.lo_ldiskfs.lol_ino; - struct ext2_inode_large *inode = object->u.lo_ldiskfs.lol_inode; - - LASSERT(sizeof(*hsm) < MAX_LINKEA_SIZE); - - rc = ext2fs_attr_get(fs, (struct ext2_inode *)inode, - EXT2_ATTR_INDEX_TRUSTED, - XATTR_NAME_HSM + strlen("trusted."), - buf, MAX_LINKEA_SIZE, &size); - if (xattr_name_not_found(rc)) { - LDEBUGW(&attrs->loa_fid, "inode [%d] has no [%s] xattr\n", - ino, XATTR_NAME_HSM); - hus->hus_states = 0; - hus->hus_archive_id = 0; - } else if (rc) { - LERROR("failed to get [%s] xattr for inode [%d], rc = %d\n", - XATTR_NAME_HSM, ino, rc); - return -ENODATA; - } else { - hsm = (struct hsm_attrs *)buf; - rc = lipe_hsm2user(hsm, hus); - if (rc) { - LERROR("failed to extract [%s] xattr for inode [%d], rc = %d\n", - XATTR_NAME_HSM, ino, rc); - return rc; - } + const char *name = XATTR_NAME_HSM; + void *value = NULL; + size_t value_size = 0; + int rc; + struct hsm_user_state *hus = &loa->loa_hsm_state; + struct hsm_attrs *hsm; + + memset(hus, 0, sizeof(*hus)); + + rc = ldiskfs_xattr_get(lo, name, &value, &value_size); + if (rc != 0) { + LDEBUG("ino = %u: no '%s' xattr, ignoring: rc = %d\n", + lo_ino(lo), name, rc); + goto out; } - attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_HSMEA; - return 0; + + if (value_size < sizeof(*hsm)) { + LERROR("ino = %u: xattr '%s': got size %zu, expected %zu\n", + lo_ino(lo), name, value_size, sizeof(*hsm)); + rc = -ENODATA; + goto out; + } + + hsm = value; + rc = lipe_hsm2user(hsm, hus); + if (rc != 0) { + LERROR("ino = %u: cannot parse '%s' xattr: rc = %d\n", lo_ino(lo), name, rc); + goto out; + } + + loa->loa_attr_bits |= LIPE_OBJECT_ATTR_HSMEA; +out: + free(value); + + return rc; } -int get_fid_ea_ldiskfs(struct lipe_object *object, - struct lipe_object_attrs *attrs) +static int get_fid_ea_ldiskfs(struct lipe_object *lo, struct lipe_object_attrs *loa) { - ext2_filsys fs = object->u.lo_ldiskfs.lol_fs; - ext2_ino_t ino = object->u.lo_ldiskfs.lol_ino; - struct ext2_inode_large *inode = object->u.lo_ldiskfs.lol_inode; - struct filter_fid *ff = &attrs->loa_filter_fid; - struct lu_fid pfid; - int size; - int rc; - - rc = ext2fs_attr_get(fs, (struct ext2_inode *)inode, - EXT2_ATTR_INDEX_TRUSTED, - XATTR_NAME_FID + strlen("trusted."), - (char *)ff, sizeof(*ff), &size); - if (rc) { - LDEBUG("inode [%d] has no [%s] xattr, ignoring rc = %d\n", - ino, XATTR_NAME_FID, rc); - return -ENODATA; + const char *name = XATTR_NAME_FID; + void *value = NULL; + size_t value_size = 0; + int rc; + struct filter_fid *ff = &loa->loa_filter_fid; + + rc = ldiskfs_xattr_get(lo, name, &value, &value_size); + if (rc != 0) { + LDEBUG("ino = %u: no '%s' xattr, ignoring: rc = %d\n", + lo_ino(lo), name, rc); + goto out; } - fid_le_to_cpu(&pfid, &ff->ff_parent); - ff->ff_parent = pfid; - attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_FILTER_FID; - attrs->loa_filter_fid_size = size; - return 0; + if (value_size < sizeof(ff->ff_parent)) { + rc = -EINVAL; + goto out; + } + + memset(ff, 0, sizeof(&ff)); + memcpy(ff, value, min(sizeof(*ff), value_size)); + fid_le_to_cpu(&ff->ff_parent, &ff->ff_parent); + /* ...? */ + + loa->loa_filter_fid_size = value_size; + loa->loa_attr_bits |= LIPE_OBJECT_ATTR_FILTER_FID; +out: + free(value); + + return rc; } -int get_lum_ea_ldiskfs(struct lipe_object *object, - struct lipe_object_attrs *attrs) +static int get_lum_ea_ldiskfs(struct lipe_object *lo, struct lipe_object_attrs *loa) { - int rc; - int size; - struct lov_user_md *lov = attrs->loa_lum; - ext2_filsys fs = object->u.lo_ldiskfs.lol_fs; - ext2_ino_t ino = object->u.lo_ldiskfs.lol_ino; - struct ext2_inode_large *inode = object->u.lo_ldiskfs.lol_inode; - - rc = ext2fs_attr_get(fs, (struct ext2_inode *)inode, - EXT2_ATTR_INDEX_TRUSTED, - XATTR_NAME_LOV + strlen("trusted."), - (char *)lov, attrs->loa_lum_size, &size); - if (rc) { - LDEBUGW(&attrs->loa_fid, "inode [%d] has no [%s] xattr, rc = %d\n", - ino, XATTR_NAME_LOV, rc); - return -ENODATA; + const char *name = XATTR_NAME_LOV; + void *value = NULL; + size_t value_size = 0; + int rc; + + rc = ldiskfs_xattr_get(lo, name, &value, &value_size); + if (rc != 0) { + LDEBUG("ino = %u: no '%s' xattr, ignoring: rc = %d\n", + lo_ino(lo), name, rc); + goto out; } - rc = decode_lum(lov, size); - if (rc) { - LERROR("failed to decode lovea for inode [%d], rc = %d\n", - ino, rc); - return rc; + rc = decode_lum(value, value_size); + if (rc != 0) { + LERROR("ino = %u: cannot decode '%s' xattr: rc = %d\n", + lo_ino(lo), name, rc); + goto out; } - attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_LOVEA; - return 0; + + loa->loa_lum = value; + loa->loa_lum_size = value_size; + value = NULL; + value_size = 0; + + loa->loa_attr_bits |= LIPE_OBJECT_ATTR_LOVEA; +out: + free(value); + + return rc; } -/* - * llapi_layout_get_by_xattr() and LSoM are both included in Lustre-2.12, - * so no need to duplicate the macros. - */ -int get_som_ea_ldiskfs(struct lipe_object *object, - struct lipe_object_attrs *attrs) +static int get_som_ea_ldiskfs(struct lipe_object *lo, struct lipe_object_attrs *loa) { - int rc; - int size; - struct lustre_som_attrs *som = &attrs->loa_som; - ext2_filsys fs = object->u.lo_ldiskfs.lol_fs; - ext2_ino_t ino = object->u.lo_ldiskfs.lol_ino; - struct ext2_inode_large *inode = object->u.lo_ldiskfs.lol_inode; - - rc = ext2fs_attr_get(fs, (struct ext2_inode *)inode, - EXT2_ATTR_INDEX_TRUSTED, - XATTR_NAME_SOM + strlen("trusted."), - (char *)som, sizeof(*som), &size); - if (rc) { - LDEBUGW(&attrs->loa_fid, "inode [%d] has no [%s] xattr, rc = %d\n", - ino, XATTR_NAME_SOM, rc); - return -ENODATA; + const char *name = XATTR_NAME_SOM; + void *value = NULL; + size_t value_size = 0; + int rc; + struct lustre_som_attrs *som = &loa->loa_som; + + rc = ldiskfs_xattr_get(lo, name, &value, &value_size); + if (rc != 0) { + LDEBUG("ino = %u: no '%s' xattr, ignoring: rc = %d\n", + lo_ino(lo), name, rc); + goto out; } - if (size != sizeof(*som)) { - LERROR("unexpected size of [%s] xattr for inode [%d], expected [%d], got [%d]\n", - XATTR_NAME_SOM, ino, sizeof(*som), size); - return -ENODATA; + if (value_size < sizeof(*som)) { + LERROR("ino = %u: xattr '%s': got size %zu, expected %zu\n", + lo_ino(lo), name, value_size, sizeof(*som)); + rc = -ENODATA; + goto out; } + *som = *(struct lustre_som_attrs *)value; lipe_som_swab(som); + /* LIPE_OBJECT_ATTR_SOM is set in get_som_ea() according to flags. */ +out: + free(value); + return rc; } diff --git a/lipe/src/policy.c b/lipe/src/policy.c index da7d023..ca7d56c 100644 --- a/lipe/src/policy.c +++ b/lipe/src/policy.c @@ -823,10 +823,10 @@ static bool object_is_dir_substripe(struct lipe_object *object, if (rc && rc != -ENOTSUP) return false; - lmm = (union lmv_mds_md *)attrs->loa_lmv_buf; - if (lmm->lmv_magic == LMV_MAGIC_STRIPE) - return true; - return false; + lmm = attrs->loa_lmv; + assert(lmm != NULL); + + return lmm->lmv_magic == LMV_MAGIC_STRIPE; } static int get_lma_ea(struct lipe_object *object, diff --git a/lipe/src/policy.h b/lipe/src/policy.h index 37064f4..1097583 100644 --- a/lipe/src/policy.h +++ b/lipe/src/policy.h @@ -286,6 +286,7 @@ struct lipe_object_ldiskfs { ext2_filsys lol_fs; ext2_ino_t lol_ino; struct ext2_inode_large *lol_inode; + struct ext2_xattr_handle *lol_xattr_handle; }; struct lipe_object_zfs { diff --git a/lipe/src/posix_ea.c b/lipe/src/posix_ea.c index 35ecbc8..70d35b7 100644 --- a/lipe/src/posix_ea.c +++ b/lipe/src/posix_ea.c @@ -29,9 +29,9 @@ static int get_link_ea_posix(struct lipe_object *object, int rc; ssize_t size; const char *path = object->u.lo_posix.lop_path; + char buf[XATTR_SIZE_MAX]; - size = lgetxattr(path, XATTR_NAME_LINK, attrs->loa_leh_buf, - sizeof(attrs->loa_leh_buf)); + size = lgetxattr(path, XATTR_NAME_LINK, buf, sizeof(buf)); if (size < 0) { if (errno == ENOATTR) LDEBUG("path [%s] has no [%s] xattr, ignoring\n", @@ -42,7 +42,7 @@ static int get_link_ea_posix(struct lipe_object *object, return -errno; } - rc = lipe_object_attrs_set_links(attrs, attrs->loa_leh_buf, size); + rc = lipe_object_attrs_set_links(attrs, buf, size); if (rc) { LERROR("failed to decode linkea for path [%s]\n", path); return -1; @@ -54,13 +54,11 @@ static int get_link_ea_posix(struct lipe_object *object, static int get_lmv_ea_posix(struct lipe_object *object, struct lipe_object_attrs *attrs) { - ssize_t rc; - const char *path = object->u.lo_posix.lop_path; - - memset(attrs->loa_lmv_buf, 0, sizeof(attrs->loa_lmv_buf)); + const char *path = object->u.lo_posix.lop_path; + char buf[XATTR_SIZE_MAX]; + ssize_t rc; - rc = lgetxattr(path, XATTR_NAME_LMV, attrs->loa_lmv_buf, - sizeof(attrs->loa_lmv_buf)); + rc = lgetxattr(path, XATTR_NAME_LMV, buf, sizeof(buf)); if (rc < 0) { if (errno == ENOATTR) { LDEBUG("path [%s] has no [%s] xattr, ignoring\n", @@ -73,19 +71,18 @@ static int get_lmv_ea_posix(struct lipe_object *object, } } - return 0; + return xmemdup(&attrs->loa_lmv, &attrs->loa_lmv_size, buf, rc); } static int get_lma_ea_posix(struct lipe_object *object, struct lipe_object_attrs *attrs) { - char buf[MAX_LINKEA_SIZE]; - struct lustre_mdt_attrs *lma; - ssize_t size; - const char *path = object->u.lo_posix.lop_path; + const char *path = object->u.lo_posix.lop_path; + struct lustre_mdt_attrs *lma; + char buf[XATTR_SIZE_MAX]; + ssize_t size; - size = lgetxattr(path, XATTR_NAME_LMA, buf, - MAX_LINKEA_SIZE); + size = lgetxattr(path, XATTR_NAME_LMA, buf, sizeof(buf)); if (size < 0) { if (errno == ENOATTR) LDEBUG("path [%d] has no [%s] xattr, ignoring\n", @@ -145,13 +142,12 @@ static int get_hsm_ea_posix(struct lipe_object *object, static int get_lum_ea_posix(struct lipe_object *object, struct lipe_object_attrs *attrs) { - int rc; - int size; - struct lov_user_md *lov = attrs->loa_lum; - const char *path = object->u.lo_posix.lop_path; + const char *path = object->u.lo_posix.lop_path; + char buf[XATTR_SIZE_MAX]; + int size; + int rc; - size = lgetxattr(path, XATTR_NAME_LOV, - (char *)lov, attrs->loa_lum_size); + size = lgetxattr(path, XATTR_NAME_LOV, buf, sizeof(buf)); if (size < 0) { if (errno == ENOATTR) LDEBUG("path [%d] has no [%s] xattr, ignoring\n", @@ -162,11 +158,16 @@ static int get_lum_ea_posix(struct lipe_object *object, return -errno; } - rc = decode_lum(lov, size); + rc = decode_lum((struct lov_user_md_v1 *)buf, size); if (rc) { LERROR("failed to decode lovea for path [%s]\n", path); return rc; } + + rc = xmemdup(&attrs->loa_lum, &attrs->loa_lum_size, buf, size); + if (rc < 0) + return rc; + attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_LOVEA; return 0; } diff --git a/lustre/tests/sanity-lipe.sh b/lustre/tests/sanity-lipe.sh index 9bbf2a9..571a288 100644 --- a/lustre/tests/sanity-lipe.sh +++ b/lustre/tests/sanity-lipe.sh @@ -1465,6 +1465,26 @@ test_23() { } run_test 23 "lipe_find -size and -blocks work" +test_100() { + local file=$DIR/$tdir/$tfile + local facet=${LIPE_MDS_FACET:-$(lipe_get_random_mds)} + local index=$(($(facet_number $facet) - 1)) + local link_count=200 + local i + + $LFS mkdir -i $index $DIR/$tdir || error "$LFS mkdir '$td' failed" + touch $file + + for ((i = 1; i < link_count; i++)); do + ln $file $file.$i + done + + lipe_find_expect_file $facet $file true + lipe_find_expect_file $facet $file true -name $tfile + lipe_find_expect_file $facet $file true -name $tfile.1 +} +run_test 100 "lipe_find works with big link xattrs" + do_lipe_scan2_facet() { local facet="$1" local device="$(facet_device $facet)" -- 1.8.3.1