From 5590f5aa94a57a6553636e63d7897e1e2a885b03 Mon Sep 17 00:00:00 2001 From: Jian Yu Date: Fri, 2 Aug 2019 23:58:34 -0700 Subject: [PATCH] LU-12589 llite: swab LOV EA data in ll_getxattr_lov() On PPC client, the LOV EA data returned by getfattr from x86_64 server was not swabbed to the host endian. While running setfattr, the data was swabbed in ll_lov_setstripe_ea_info(), which caused magic mis-match in ll_lov_user_md_size() and then ll_setstripe_ea() returned -ERANGE. This patch fixed the above issue by swabbing LOV EA data in ll_getxattr_lov(). Test-Parameters: clientarch=ppc64 \ envdefinitions=ONLY="24D 102a" testlist=sanity Change-Id: I8069df0c8f07c0bedba2e27db7c3a5553f11afb4 Signed-off-by: Jian Yu Reviewed-on: https://review.whamcloud.com/35626 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Patrick Farrell --- lustre/include/lustre_swab.h | 2 +- lustre/llite/dir.c | 4 ++-- lustre/llite/file.c | 4 ++-- lustre/llite/xattr.c | 16 ++++++++-------- lustre/ptlrpc/pack_generic.c | 39 +++++++++++++++++++++++++++++++++------ 5 files changed, 46 insertions(+), 19 deletions(-) diff --git a/lustre/include/lustre_swab.h b/lustre/include/lustre_swab.h index ceaf9c9..911c795 100644 --- a/lustre/include/lustre_swab.h +++ b/lustre/include/lustre_swab.h @@ -98,7 +98,7 @@ void lustre_swab_lov_user_md_v3(struct lov_user_md_v3 *lum); void lustre_swab_lov_comp_md_v1(struct lov_comp_md_v1 *lum); void lustre_swab_lov_user_md_objects(struct lov_user_ost_data *lod, int stripe_count); -void lustre_swab_lov_user_md(struct lov_user_md *lum); +void lustre_swab_lov_user_md(struct lov_user_md *lum, size_t size); void lustre_swab_lov_mds_md(struct lov_mds_md *lmm); void lustre_swab_idx_info(struct idx_info *ii); void lustre_swab_lip_header(struct lu_idxpage *lip); diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 9b69fdf..f3c86bc 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -606,7 +606,7 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, */ if ((__swab32(lump->lmm_magic) & le32_to_cpu(LOV_MAGIC_MASK)) == le32_to_cpu(LOV_MAGIC_MAGIC)) - lustre_swab_lov_user_md(lump); + lustre_swab_lov_user_md(lump, 0); } else { lum_size = sizeof(struct lov_user_md_v1); } @@ -741,7 +741,7 @@ int ll_dir_getstripe(struct inode *inode, void **plmm, int *plmm_size, case LOV_MAGIC_COMP_V1: case LOV_USER_MAGIC_SPECIFIC: if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC)) - lustre_swab_lov_user_md((struct lov_user_md *)lmm); + lustre_swab_lov_user_md((struct lov_user_md *)lmm, 0); break; case LMV_MAGIC_V1: if (LMV_MAGIC != cpu_to_le32(LMV_MAGIC)) diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 6760ae0..adf5b6b 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -2043,7 +2043,7 @@ int ll_lov_setstripe_ea_info(struct inode *inode, struct dentry *dentry, if ((__swab32(lum->lmm_magic) & le32_to_cpu(LOV_MAGIC_MASK)) == le32_to_cpu(LOV_MAGIC_MAGIC)) { /* this code will only exist for big-endian systems */ - lustre_swab_lov_user_md(lum); + lustre_swab_lov_user_md(lum, 0); } ll_inode_size_lock(inode); @@ -2126,7 +2126,7 @@ int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename, stripe_count = 0; } - lustre_swab_lov_user_md((struct lov_user_md *)lmm); + lustre_swab_lov_user_md((struct lov_user_md *)lmm, 0); /* if function called for directory - we should * avoid swab not existent lsm objects */ diff --git a/lustre/llite/xattr.c b/lustre/llite/xattr.c index b8500df..52ca216 100644 --- a/lustre/llite/xattr.c +++ b/lustre/llite/xattr.c @@ -345,7 +345,7 @@ static int ll_xattr_set(const struct xattr_handler *handler, if (strncmp(name, "lov.", 4) == 0 && (__swab32(((struct lov_user_md *)value)->lmm_magic) & le32_to_cpu(LOV_MAGIC_MASK)) == le32_to_cpu(LOV_MAGIC_MAGIC)) - lustre_swab_lov_user_md((struct lov_user_md *)value); + lustre_swab_lov_user_md((struct lov_user_md *)value, 0); return ll_xattr_set_common(handler, dentry, inode, name, value, size, flags); @@ -485,7 +485,6 @@ static ssize_t ll_getxattr_lov(struct inode *inode, void *buf, size_t buf_size) }; struct lu_env *env; u16 refcheck; - u32 magic; if (!obj) RETURN(-ENODATA); @@ -514,12 +513,12 @@ static ssize_t ll_getxattr_lov(struct inode *inode, void *buf, size_t buf_size) * recognizing layout gen as stripe offset when the * file is restored. See LU-2809. */ - magic = ((struct lov_mds_md *)buf)->lmm_magic; - if ((magic & __swab32(LOV_MAGIC_MAGIC)) == - __swab32(LOV_MAGIC_MAGIC)) - magic = __swab32(magic); + if ((((struct lov_mds_md *)buf)->lmm_magic & + __swab32(LOV_MAGIC_MAGIC)) == __swab32(LOV_MAGIC_MAGIC)) + lustre_swab_lov_user_md((struct lov_user_md *)buf, + cl.cl_size); - switch (magic) { + switch (((struct lov_mds_md *)buf)->lmm_magic) { case LOV_MAGIC_V1: case LOV_MAGIC_V3: case LOV_MAGIC_SPECIFIC: @@ -529,7 +528,8 @@ static ssize_t ll_getxattr_lov(struct inode *inode, void *buf, size_t buf_size) case LOV_MAGIC_FOREIGN: goto out_env; default: - CERROR("Invalid LOV magic %08x\n", magic); + CERROR("Invalid LOV magic %08x\n", + ((struct lov_mds_md *)buf)->lmm_magic); GOTO(out_env, rc = -EINVAL); } diff --git a/lustre/ptlrpc/pack_generic.c b/lustre/ptlrpc/pack_generic.c index 9ff1ce9..1d33649 100644 --- a/lustre/ptlrpc/pack_generic.c +++ b/lustre/ptlrpc/pack_generic.c @@ -2376,25 +2376,52 @@ void lustre_swab_lov_user_md_objects(struct lov_user_ost_data *lod, } EXPORT_SYMBOL(lustre_swab_lov_user_md_objects); -void lustre_swab_lov_user_md(struct lov_user_md *lum) +void lustre_swab_lov_user_md(struct lov_user_md *lum, size_t size) { + struct lov_user_md_v1 *v1; + struct lov_user_md_v3 *v3; + struct lov_foreign_md *lfm; + __u16 stripe_count; ENTRY; CDEBUG(D_IOCTL, "swabbing lov_user_md\n"); switch (lum->lmm_magic) { case __swab32(LOV_MAGIC_V1): case LOV_USER_MAGIC_V1: - lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lum); + { + v1 = (struct lov_user_md_v1 *)lum; + stripe_count = v1->lmm_stripe_count; + + if (lum->lmm_magic != LOV_USER_MAGIC_V1) + __swab16s(&stripe_count); + + lustre_swab_lov_user_md_v1(v1); + if (size > sizeof(*v1)) + lustre_swab_lov_user_md_objects(v1->lmm_objects, + stripe_count); + break; + } case __swab32(LOV_MAGIC_V3): case LOV_USER_MAGIC_V3: - lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lum); + { + v3 = (struct lov_user_md_v3 *)lum; + stripe_count = v3->lmm_stripe_count; + + if (lum->lmm_magic != LOV_USER_MAGIC_V3) + __swab16s(&stripe_count); + + lustre_swab_lov_user_md_v3(v3); + if (size > sizeof(*v3)) + lustre_swab_lov_user_md_objects(v3->lmm_objects, + stripe_count); break; + } case __swab32(LOV_USER_MAGIC_SPECIFIC): case LOV_USER_MAGIC_SPECIFIC: { - struct lov_user_md_v3 *v3 = (struct lov_user_md_v3 *)lum; - __u16 stripe_count = v3->lmm_stripe_count; + v3 = (struct lov_user_md_v3 *)lum; + stripe_count = v3->lmm_stripe_count; if (lum->lmm_magic != LOV_USER_MAGIC_SPECIFIC) __swab16s(&stripe_count); @@ -2410,7 +2437,7 @@ void lustre_swab_lov_user_md(struct lov_user_md *lum) case __swab32(LOV_MAGIC_FOREIGN): case LOV_USER_MAGIC_FOREIGN: { - struct lov_foreign_md *lfm = (struct lov_foreign_md *)lum; + lfm = (struct lov_foreign_md *)lum; __swab32s(&lfm->lfm_magic); __swab32s(&lfm->lfm_length); __swab32s(&lfm->lfm_type); -- 1.8.3.1