Whamcloud - gitweb
LU-12589 llite: swab LOV EA data in ll_getxattr_lov() 26/35626/4
authorJian Yu <yujian@whamcloud.com>
Sat, 3 Aug 2019 06:58:34 +0000 (23:58 -0700)
committerOleg Drokin <green@whamcloud.com>
Wed, 21 Aug 2019 04:59:53 +0000 (04:59 +0000)
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>
lustre/include/lustre_swab.h
lustre/llite/dir.c
lustre/llite/file.c
lustre/llite/xattr.c
lustre/ptlrpc/pack_generic.c

index ceaf9c9..911c795 100644 (file)
@@ -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_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);
index 9b69fdf..f3c86bc 100644 (file)
@@ -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))
                 */
                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);
        }
@@ -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))
        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))
index 6760ae0..adf5b6b 100644 (file)
@@ -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 */
        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);
@@ -2126,7 +2126,7 @@ int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename,
                                stripe_count = 0;
                }
 
                                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 */
 
                /* if function called for directory - we should
                 * avoid swab not existent lsm objects */
index b8500df..52ca216 100644 (file)
@@ -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))
        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);
@@ -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;
                };
                struct lu_env *env;
                u16 refcheck;
-               u32 magic;
 
                if (!obj)
                        RETURN(-ENODATA);
 
                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.
                 */
                 * 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:
                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:
                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);
                }
 
index 9ff1ce9..1d33649 100644 (file)
@@ -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);
 
 }
 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);
+
                break;
                break;
+       }
        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);
                break;
                break;
+       }
        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);
@@ -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:
        {
        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);