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 <yujian@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/35626
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Patrick Farrell <pfarrell@whamcloud.com>
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_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);
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);
*/
if ((__swab32(lump->lmm_magic) & le32_to_cpu(LOV_MAGIC_MASK)) ==
le32_to_cpu(LOV_MAGIC_MAGIC))
*/
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);
}
} else {
lum_size = sizeof(struct lov_user_md_v1);
}
case LOV_MAGIC_COMP_V1:
case LOV_USER_MAGIC_SPECIFIC:
if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
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))
break;
case LMV_MAGIC_V1:
if (LMV_MAGIC != cpu_to_le32(LMV_MAGIC))
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 */
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);
}
ll_inode_size_lock(inode);
- 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 */
/* if function called for directory - we should
* avoid swab not existent lsm objects */
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))
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);
return ll_xattr_set_common(handler, dentry, inode, name, value, size,
flags);
};
struct lu_env *env;
u16 refcheck;
};
struct lu_env *env;
u16 refcheck;
if (!obj)
RETURN(-ENODATA);
if (!obj)
RETURN(-ENODATA);
* recognizing layout gen as stripe offset when the
* file is restored. See LU-2809.
*/
* 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 (((struct lov_mds_md *)buf)->lmm_magic) {
case LOV_MAGIC_V1:
case LOV_MAGIC_V3:
case LOV_MAGIC_SPECIFIC:
case LOV_MAGIC_V1:
case LOV_MAGIC_V3:
case LOV_MAGIC_SPECIFIC:
case LOV_MAGIC_FOREIGN:
goto out_env;
default:
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);
}
GOTO(out_env, rc = -EINVAL);
}
}
EXPORT_SYMBOL(lustre_swab_lov_user_md_objects);
}
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:
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);
+
case __swab32(LOV_MAGIC_V3):
case LOV_USER_MAGIC_V3:
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);
case __swab32(LOV_USER_MAGIC_SPECIFIC):
case LOV_USER_MAGIC_SPECIFIC:
{
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);
if (lum->lmm_magic != LOV_USER_MAGIC_SPECIFIC)
__swab16s(&stripe_count);
case __swab32(LOV_MAGIC_FOREIGN):
case LOV_USER_MAGIC_FOREIGN:
{
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);
__swab32s(&lfm->lfm_magic);
__swab32s(&lfm->lfm_length);
__swab32s(&lfm->lfm_type);