Whamcloud - gitweb
Branch HEAD
authoryangsheng <yangsheng>
Wed, 11 Mar 2009 11:07:13 +0000 (11:07 +0000)
committeryangsheng <yangsheng>
Wed, 11 Mar 2009 11:07:13 +0000 (11:07 +0000)
b=17701

i=adilger, nathan

Fixed issue cause by previous patch.

lustre/include/lustre/lustre_user.h
lustre/lov/lov_pack.c

index b9bbdf0..b942a63 100644 (file)
@@ -174,11 +174,6 @@ struct lov_user_md_v3 {           /* LOV EA user data (host-endian) */
         struct lov_user_ost_data_v1 lmm_objects[0]; /* per-stripe data */
 } __attribute__((packed));
 
-#define copy_lov_mds2user(user_md, mds_md) do { \
-        memcpy(user_md, mds_md, sizeof(*(user_md))); \
-        (user_md)->lmm_stripe_offset = 0; \
-        (user_md)->lmm_stripe_count = (mds_md)->lmm_stripe_count; } while(0)
-
 /* Compile with -D_LARGEFILE64_SOURCE or -D_GNU_SOURCE (or #define) to
  * use this.  It is unsafe to #define those values in this header as it
  * is possible the application has already #included <sys/stat.h>. */
index 383c701..17b9d47 100644 (file)
@@ -622,10 +622,13 @@ int lov_getstripe(struct obd_export *exp, struct lov_stripe_md *lsm,
                  (lum.lmm_magic != LOV_USER_MAGIC_V3))
                 rc = -EINVAL;
         else {
-                /* if v3 we just have to update the lum_size */
-                if (lum.lmm_magic == LOV_USER_MAGIC_V3)
-                        lum_size = sizeof(struct lov_user_md_v3);
-
+                if (lum.lmm_stripe_count && 
+                    (lum.lmm_stripe_count < lsm->lsm_stripe_count)) {
+                        /* Return right size of stripe to user */
+                        lum.lmm_stripe_count = lsm->lsm_stripe_count;
+                        rc = copy_to_user(lump, &lum, lum_size);
+                        RETURN(-EOVERFLOW);
+                }
                 rc = lov_packmd(exp, &lmmk, lsm);
                 if (rc < 0)
                         RETURN(rc);
@@ -639,21 +642,43 @@ int lov_getstripe(struct obd_export *exp, struct lov_stripe_md *lsm,
                          sizeof lmmk->lmm_objects[0]);
 
                 if ((cpu_to_le32(LOV_MAGIC) != LOV_MAGIC) &&
-                    (lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC)))
+                    ((lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V1)) ||
+                    (lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V3)))) {
                         lustre_swab_lov_mds_md(lmmk);
-                /* User wasn't expecting this many OST entries */
-                if (lum.lmm_stripe_count == 0) {
-                        copy_lov_mds2user(&lum, lmmk);
-                        if (copy_to_user(lump, &lum, lum_size))
-                                rc = -EFAULT;
-                } else if (lum.lmm_stripe_count < lmmk->lmm_stripe_count) {
-                        rc = -EOVERFLOW;
+                        lustre_swab_lov_user_md_objects(
+                                (struct lov_user_ost_data*)lmmk->lmm_objects,
+                                lmmk->lmm_stripe_count);
+                }
+                if (lum.lmm_magic == LOV_USER_MAGIC) {
+                        /* User request for v1, we need skip lmm_pool_name */
+                        if (lmmk->lmm_magic == LOV_MAGIC_V3) {
+                                memmove((char*)(&lmmk->lmm_stripe_count) +
+                                        sizeof(lmmk->lmm_stripe_count),
+                                        lmmk->lmm_objects,
+                                        lmmk->lmm_stripe_count *
+                                        sizeof(struct lov_ost_data_v1));
+                                lmm_size -= LOV_MAXPOOLNAME;
+                        }
                 } else {
-                        copy_lov_mds2user(&lum, lmmk);
-                        if (copy_to_user(lump, &lum, lmm_size))
-                                rc = -EFAULT;
+                        /* if v3 we just have to update the lum_size */
+                        lum_size = sizeof(struct lov_user_md_v3);
                 }
 
+                /* User wasn't expecting this many OST entries */
+                if (lum.lmm_stripe_count == 0)
+                        lmm_size = lum_size;
+                else if (lum.lmm_stripe_count < lmmk->lmm_stripe_count)
+                        RETURN(-EOVERFLOW);
+                /* 
+                 * Have a difference between lov_mds_md & lov_user_md.
+                 * So we have to re-order the data before copy to user.
+                 */
+                lum.lmm_stripe_count = lmmk->lmm_stripe_count;
+                ((struct lov_user_md*)lmmk)->lmm_stripe_offset = 0;
+                ((struct lov_user_md*)lmmk)->lmm_stripe_count = lum.lmm_stripe_count;
+                if (copy_to_user(lump, lmmk, lmm_size))
+                        rc = -EFAULT;
+
                 obd_free_diskmd(exp, &lmmk);
         }
         set_fs(seg);