From 48007300255836ec81b1d037ec450e71b8a754a8 Mon Sep 17 00:00:00 2001 From: Jian Yu Date: Thu, 8 Aug 2019 12:13:47 -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 This patch is back-ported from the following one: Lustre-commit: f4a5957164bb981c93072bb0a28118bb7207a209 Lustre-change: https://review.whamcloud.com/35626 Change-Id: I8069df0c8f07c0bedba2e27db7c3a5553f11afb4 Signed-off-by: Jian Yu Reviewed-on: https://review.whamcloud.com/35736 Tested-by: jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Oleg Drokin --- 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 | 36 +++++++++++++++++++++++++++++++----- 5 files changed, 44 insertions(+), 18 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 3c97c1e..4183744 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -590,7 +590,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); } @@ -725,7 +725,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 49b9e1a..d83032b 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -1900,7 +1900,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); @@ -1982,7 +1982,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 ea26bbf..56117d6 100644 --- a/lustre/llite/xattr.c +++ b/lustre/llite/xattr.c @@ -337,7 +337,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); @@ -478,7 +478,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); @@ -507,12 +506,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: @@ -521,7 +520,8 @@ static ssize_t ll_getxattr_lov(struct inode *inode, void *buf, size_t buf_size) case LOV_MAGIC_COMP_V1: 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 ed32cfea..be17b95 100644 --- a/lustre/ptlrpc/pack_generic.c +++ b/lustre/ptlrpc/pack_generic.c @@ -2361,25 +2361,51 @@ 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; + __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); -- 1.8.3.1