Whamcloud - gitweb
LU-8998 clio: getstripe support comp layout
authorNiu Yawei <yawei.niu@intel.com>
Thu, 12 Jan 2017 14:48:19 +0000 (09:48 -0500)
committerJinshan Xiong <jinshan.xiong@intel.com>
Thu, 6 Apr 2017 04:31:52 +0000 (21:31 -0700)
{get/set}stripe support composite layout

Signed-off-by: Bobi Jam <bobijam.xu@intel.com>
Signed-off-by: Niu Yawei <yawei.niu@intel.com>
Change-Id: Iafe5205a79f721be1ec5ec83ab80a86a4b537e18
Reviewed-on: https://review.whamcloud.com/24851
Tested-by: Jenkins
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Lai Siyao <lai.siyao@intel.com>
Reviewed-by: Jinshan Xiong <jinshan.xiong@intel.com>
lustre/llite/dir.c
lustre/llite/file.c
lustre/llite/llite_internal.h
lustre/llite/xattr.c
lustre/lov/lov_internal.h
lustre/lov/lov_object.c
lustre/lov/lov_pack.c

index b171f3e..c78767e 100644 (file)
@@ -570,6 +570,15 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump,
                         lum_size = sizeof(struct lov_user_md_v3);
                         break;
                 }
                         lum_size = sizeof(struct lov_user_md_v3);
                         break;
                 }
+               case LOV_USER_MAGIC_COMP_V1: {
+                       if (lump->lmm_magic !=
+                           cpu_to_le32(LOV_USER_MAGIC_COMP_V1))
+                               lustre_swab_lov_comp_md_v1(
+                                       (struct lov_comp_md_v1 *)lump);
+                       lum_size = le32_to_cpu(
+                               ((struct lov_comp_md_v1 *)lump)->lcm_size);
+                       break;
+               }
                case LMV_USER_MAGIC: {
                        if (lump->lmm_magic != cpu_to_le32(LMV_USER_MAGIC))
                                lustre_swab_lmv_user_md(
                case LMV_USER_MAGIC: {
                        if (lump->lmm_magic != cpu_to_le32(LMV_USER_MAGIC))
                                lustre_swab_lmv_user_md(
@@ -610,7 +619,10 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump,
         * LOV_USER_MAGIC_V3 have the same initial fields so we do not
         * need the make the distiction between the 2 versions
         */
         * LOV_USER_MAGIC_V3 have the same initial fields so we do not
         * need the make the distiction between the 2 versions
         */
-       if (set_default && mgc->u.cli.cl_mgc_mgsexp) {
+       if (set_default && mgc->u.cli.cl_mgc_mgsexp &&
+           (lump == NULL ||
+            le32_to_cpu(lump->lmm_magic) == LOV_USER_MAGIC_V1 ||
+            le32_to_cpu(lump->lmm_magic) == LOV_USER_MAGIC_V3)) {
                char *param = NULL;
                char *buf;
 
                char *param = NULL;
                char *buf;
 
@@ -625,23 +637,23 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump,
                buf += strlen(buf);
 
                /* Set root stripesize */
                buf += strlen(buf);
 
                /* Set root stripesize */
-               sprintf(buf, ".stripesize=%u",
-                       lump ? le32_to_cpu(lump->lmm_stripe_size) : 0);
+               snprintf(buf, MGS_PARAM_MAXLEN, ".stripesize=%u",
+                        lump ? le32_to_cpu(lump->lmm_stripe_size) : 0);
                rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param);
                if (rc)
                        GOTO(end, rc);
 
                /* Set root stripecount */
                rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param);
                if (rc)
                        GOTO(end, rc);
 
                /* Set root stripecount */
-               sprintf(buf, ".stripecount=%hd",
-                       lump ? le16_to_cpu(lump->lmm_stripe_count) : 0);
+               snprintf(buf, MGS_PARAM_MAXLEN, ".stripecount=%hd",
+                        lump ? le16_to_cpu(lump->lmm_stripe_count) : 0);
                rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param);
                if (rc)
                        GOTO(end, rc);
 
                /* Set root stripeoffset */
                rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param);
                if (rc)
                        GOTO(end, rc);
 
                /* Set root stripeoffset */
-               sprintf(buf, ".stripeoffset=%hd",
-                       lump ? le16_to_cpu(lump->lmm_stripe_offset) :
-                       (typeof(lump->lmm_stripe_offset))(-1));
+               snprintf(buf, MGS_PARAM_MAXLEN, ".stripeoffset=%hd",
+                        lump ? le16_to_cpu(lump->lmm_stripe_offset) :
+                               (typeof(lump->lmm_stripe_offset))(-1));
                rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param);
 
 end:
                rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param);
 
 end:
@@ -719,6 +731,11 @@ int ll_dir_getstripe(struct inode *inode, void **plmm, int *plmm_size,
                if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
                        lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lmm);
                break;
                if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
                        lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lmm);
                break;
+       case LOV_MAGIC_COMP_V1:
+               if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
+                       lustre_swab_lov_comp_md_v1(
+                                       (struct lov_comp_md_v1 *)lmm);
+               break;
        case LMV_MAGIC_V1:
                if (LMV_MAGIC != cpu_to_le32(LMV_MAGIC))
                        lustre_swab_lmv_mds_md((union lmv_mds_md *)lmm);
        case LMV_MAGIC_V1:
                if (LMV_MAGIC != cpu_to_le32(LMV_MAGIC))
                        lustre_swab_lmv_mds_md((union lmv_mds_md *)lmm);
@@ -1254,36 +1271,37 @@ lmv_out_free:
 
                RETURN(rc);
        }
 
                RETURN(rc);
        }
-        case LL_IOC_LOV_SETSTRIPE: {
-                struct lov_user_md_v3 lumv3;
-                struct lov_user_md_v1 *lumv1 = (struct lov_user_md_v1 *)&lumv3;
+       case LL_IOC_LOV_SETSTRIPE: {
+               struct lov_user_md_v3 lumv3;
+               struct lov_user_md_v1 *lumv1 = (struct lov_user_md_v1 *)&lumv3;
                struct lov_user_md_v1 __user *lumv1p =
                        (struct lov_user_md_v1 __user *)arg;
                struct lov_user_md_v3 __user *lumv3p =
                        (struct lov_user_md_v3 __user *)arg;
 
                struct lov_user_md_v1 __user *lumv1p =
                        (struct lov_user_md_v1 __user *)arg;
                struct lov_user_md_v3 __user *lumv3p =
                        (struct lov_user_md_v3 __user *)arg;
 
-                int set_default = 0;
+               int set_default = 0;
 
 
-                LASSERT(sizeof(lumv3) == sizeof(*lumv3p));
-                LASSERT(sizeof(lumv3.lmm_objects[0]) ==
-                        sizeof(lumv3p->lmm_objects[0]));
-                /* first try with v1 which is smaller than v3 */
+               CLASSERT(sizeof(struct lov_user_md_v3) >
+                        sizeof(struct lov_comp_md_v1));
+               LASSERT(sizeof(lumv3) == sizeof(*lumv3p));
+               LASSERT(sizeof(lumv3.lmm_objects[0]) ==
+                               sizeof(lumv3p->lmm_objects[0]));
+               /* first try with v1 which is smaller than v3 */
                if (copy_from_user(lumv1, lumv1p, sizeof(*lumv1)))
                         RETURN(-EFAULT);
 
                if (copy_from_user(lumv1, lumv1p, sizeof(*lumv1)))
                         RETURN(-EFAULT);
 
-                if ((lumv1->lmm_magic == LOV_USER_MAGIC_V3) ) {
+               if (lumv1->lmm_magic == LOV_USER_MAGIC_V3)
                        if (copy_from_user(&lumv3, lumv3p, sizeof(lumv3)))
                        if (copy_from_user(&lumv3, lumv3p, sizeof(lumv3)))
-                                RETURN(-EFAULT);
-                }
+                               RETURN(-EFAULT);
 
                if (inode->i_sb->s_root == file_dentry(file))
 
                if (inode->i_sb->s_root == file_dentry(file))
-                        set_default = 1;
+                       set_default = 1;
 
 
-                /* in v1 and v3 cases lumv1 points to data */
-                rc = ll_dir_setstripe(inode, lumv1, set_default);
+               /* in v1 and v3 cases lumv1 points to data */
+               rc = ll_dir_setstripe(inode, lumv1, set_default);
 
 
-                RETURN(rc);
-        }
+               RETURN(rc);
+       }
        case LL_IOC_LMV_GETSTRIPE: {
                struct lmv_user_md __user *ulmv =
                                        (struct lmv_user_md __user *)arg;
        case LL_IOC_LMV_GETSTRIPE: {
                struct lmv_user_md __user *ulmv =
                                        (struct lmv_user_md __user *)arg;
index 2b68937..c3b8cef 100644 (file)
@@ -1593,10 +1593,10 @@ int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename,
         lmm = req_capsule_server_sized_get(&req->rq_pill, &RMF_MDT_MD, lmmsize);
         LASSERT(lmm != NULL);
 
         lmm = req_capsule_server_sized_get(&req->rq_pill, &RMF_MDT_MD, lmmsize);
         LASSERT(lmm != NULL);
 
-        if ((lmm->lmm_magic != cpu_to_le32(LOV_MAGIC_V1)) &&
-            (lmm->lmm_magic != cpu_to_le32(LOV_MAGIC_V3))) {
-                GOTO(out, rc = -EPROTO);
-        }
+       if (lmm->lmm_magic != cpu_to_le32(LOV_MAGIC_V1) &&
+           lmm->lmm_magic != cpu_to_le32(LOV_MAGIC_V3) &&
+           lmm->lmm_magic != cpu_to_le32(LOV_MAGIC_COMP_V1))
+               GOTO(out, rc = -EPROTO);
 
         /*
          * This is coming from the MDS, so is probably in
 
         /*
          * This is coming from the MDS, so is probably in
@@ -1606,26 +1606,35 @@ int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename,
         if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC)) {
                int stripe_count;
 
         if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC)) {
                int stripe_count;
 
-               stripe_count = le16_to_cpu(lmm->lmm_stripe_count);
-               if (le32_to_cpu(lmm->lmm_pattern) & LOV_PATTERN_F_RELEASED)
-                       stripe_count = 0;
+               if (lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_V1) ||
+                   lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_V3)) {
+                       stripe_count = le16_to_cpu(lmm->lmm_stripe_count);
+                       if (le32_to_cpu(lmm->lmm_pattern) &
+                           LOV_PATTERN_F_RELEASED)
+                               stripe_count = 0;
+               }
 
                 /* if function called for directory - we should
                  * avoid swab not existent lsm objects */
                 if (lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_V1)) {
 
                 /* if function called for directory - we should
                  * avoid swab not existent lsm objects */
                 if (lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_V1)) {
-                        lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lmm);
+                       lustre_swab_lov_user_md_v1(
+                                       (struct lov_user_md_v1 *)lmm);
                        if (S_ISREG(body->mbo_mode))
                                lustre_swab_lov_user_md_objects(
                                    ((struct lov_user_md_v1 *)lmm)->lmm_objects,
                                    stripe_count);
                } else if (lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_V3)) {
                        lustre_swab_lov_user_md_v3(
                        if (S_ISREG(body->mbo_mode))
                                lustre_swab_lov_user_md_objects(
                                    ((struct lov_user_md_v1 *)lmm)->lmm_objects,
                                    stripe_count);
                } else if (lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_V3)) {
                        lustre_swab_lov_user_md_v3(
-                               (struct lov_user_md_v3 *)lmm);
+                                       (struct lov_user_md_v3 *)lmm);
                        if (S_ISREG(body->mbo_mode))
                        if (S_ISREG(body->mbo_mode))
-                                lustre_swab_lov_user_md_objects(
-                                 ((struct lov_user_md_v3 *)lmm)->lmm_objects,
-                                 stripe_count);
-                }
+                               lustre_swab_lov_user_md_objects(
+                                ((struct lov_user_md_v3 *)lmm)->lmm_objects,
+                                stripe_count);
+               } else if (lmm->lmm_magic ==
+                          cpu_to_le32(LOV_MAGIC_COMP_V1)) {
+                       lustre_swab_lov_comp_md_v1(
+                                       (struct lov_comp_md_v1 *)lmm);
+               }
         }
 
 out:
         }
 
 out:
@@ -1694,14 +1703,6 @@ static int ll_lov_setstripe(struct inode *inode, struct file *file,
 
        lum_size = rc;
        rc = ll_lov_setstripe_ea_info(inode, file, flags, klum, lum_size);
 
        lum_size = rc;
        rc = ll_lov_setstripe_ea_info(inode, file, flags, klum, lum_size);
-       if (rc == 0) {
-               __u32 gen;
-
-               put_user(0, &lum->lmm_stripe_count);
-
-               ll_layout_refresh(inode, &gen);
-               rc = ll_file_getstripe(inode, (struct lov_user_md __user *)arg);
-       }
 
        OBD_FREE(klum, lum_size);
        RETURN(rc);
 
        OBD_FREE(klum, lum_size);
        RETURN(rc);
index cd34ccb..854c6cb 100644 (file)
@@ -921,6 +921,8 @@ static inline ssize_t ll_lov_user_md_size(const struct lov_user_md *lum)
 
                return lov_user_md_size(lum->lmm_stripe_count,
                                        LOV_USER_MAGIC_SPECIFIC);
 
                return lov_user_md_size(lum->lmm_stripe_count,
                                        LOV_USER_MAGIC_SPECIFIC);
+       case LOV_USER_MAGIC_COMP_V1:
+               return ((struct lov_comp_md_v1 *)lum)->lcm_size;
        }
 
        return -EINVAL;
        }
 
        return -EINVAL;
index ca0e5c9..9d9260b 100644 (file)
@@ -209,82 +209,98 @@ static int get_hsm_state(struct inode *inode, __u32 *hus_states)
        OBD_FREE_PTR(hus);
        return rc;
 }
        OBD_FREE_PTR(hus);
        return rc;
 }
-
-int ll_setxattr(struct dentry *dentry, const char *name,
-                const void *value, size_t size, int flags)
+int ll_setstripe_ea(struct dentry *dentry, struct lov_user_md *lump,
+                   size_t size)
 {
 {
-        struct inode *inode = dentry->d_inode;
-
-        LASSERT(inode);
-        LASSERT(name);
+       struct inode *inode = dentry->d_inode;
+       int rc = 0;
+       bool return_err = false;
 
 
-       CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p), xattr %s\n",
-              PFID(ll_inode2fid(inode)), inode, name);
+       if (lump != NULL && lump->lmm_magic == LOV_USER_MAGIC_COMP_V1) {
+               return_err = true;
+               goto setstripe;
+       }
 
 
-        ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETXATTR, 1);
-
-       if ((strncmp(name, XATTR_TRUSTED_PREFIX,
-                    sizeof(XATTR_TRUSTED_PREFIX) - 1) == 0 &&
-            strcmp(name + sizeof(XATTR_TRUSTED_PREFIX) - 1, "lov") == 0) ||
-           (strncmp(name, XATTR_LUSTRE_PREFIX,
-                    sizeof(XATTR_LUSTRE_PREFIX) - 1) == 0 &&
-            strcmp(name + sizeof(XATTR_LUSTRE_PREFIX) - 1, "lov") == 0)) {
-               struct lov_user_md *lump = (struct lov_user_md *)value;
-               int rc = 0;
-
-               /* Attributes that are saved via getxattr will always have
-                * the stripe_offset as 0.  Instead, the MDS should be
-                * allowed to pick the starting OST index.   b=17846 */
-               if (lump != NULL && lump->lmm_stripe_offset == 0)
-                       lump->lmm_stripe_offset = -1;
-               /* Avoid anyone directly setting the RELEASED flag. */
-               if (lump != NULL &&
-                       (lump->lmm_pattern & LOV_PATTERN_F_RELEASED)) {
-                       /* Only if we have a released flag check if the file
-                       * was indeed archived. */
-                       __u32 state = HS_NONE;
-                       rc = get_hsm_state(inode, &state);
-                       if (rc != 0)
-                               RETURN(rc);
-                       if (!(state & HS_ARCHIVED)) {
-                               CDEBUG(D_VFSTRACE,
-                                       "hus_states state = %x, pattern = %x\n",
-                                       state, lump->lmm_pattern);
-                               /* Here the state is: real file is not
-                                * archived but user is requesting to set
-                                * the RELEASED flag so we mask off the
-                                * released flag from the request */
-                               lump->lmm_pattern ^= LOV_PATTERN_F_RELEASED;
-                       }
+       /* Attributes that are saved via getxattr will always have
+        * the stripe_offset as 0.  Instead, the MDS should be
+        * allowed to pick the starting OST index.   b=17846 */
+       if (lump != NULL && lump->lmm_stripe_offset == 0)
+               lump->lmm_stripe_offset = -1;
+       /* Avoid anyone directly setting the RELEASED flag. */
+       if (lump != NULL &&
+               (lump->lmm_pattern & LOV_PATTERN_F_RELEASED)) {
+               /* Only if we have a released flag check if the file
+               * was indeed archived. */
+               __u32 state = HS_NONE;
+               rc = get_hsm_state(inode, &state);
+               if (rc != 0)
+                       RETURN(rc);
+               if (!(state & HS_ARCHIVED)) {
+                       CDEBUG(D_VFSTRACE,
+                               "hus_states state = %x, pattern = %x\n",
+                               state, lump->lmm_pattern);
+                       /* Here the state is: real file is not
+                        * archived but user is requesting to set
+                        * the RELEASED flag so we mask off the
+                        * released flag from the request */
+                       lump->lmm_pattern ^= LOV_PATTERN_F_RELEASED;
                }
                }
+       }
 
 
-               if (lump != NULL && S_ISREG(inode->i_mode)) {
-                       struct file     f;
-                       __u64           it_flags = FMODE_WRITE;
-                       int             lum_size;
+setstripe:
+       if (lump != NULL && S_ISREG(inode->i_mode)) {
+               struct file     f;
+               __u64           it_flags = FMODE_WRITE;
+               int             lum_size;
+
+               lum_size = ll_lov_user_md_size(lump);
+               /**
+                * b=10667: ignore error.
+                * Silently eat error on setting strusted.lov attribute for
+                * SuSE 9, it added default option to copy all attributes in
+                * 'cp' command.
+                */
+               if (lum_size < 0 || size < lum_size)
+                       return return_err ? -ERANGE : 0;
+
+               memset(&f, 0, sizeof(f)); /* f.f_flags is used below */
+               f.f_path.dentry = dentry;
+               rc = ll_lov_setstripe_ea_info(inode, &f, it_flags, lump,
+                                             lum_size);
+               /* b=10667 */
+               if (!return_err)
+                       rc = 0;
+       } else if (S_ISDIR(inode->i_mode)) {
+               rc = ll_dir_setstripe(inode, lump, 0);
+       }
 
 
-                       lum_size = ll_lov_user_md_size(lump);
-                       if (lum_size < 0 || size < lum_size)
-                               return 0; /* b=10667: ignore error */
+       return rc;
+}
 
 
-                       memset(&f, 0, sizeof(f)); /* f.f_flags is used below */
-                       f.f_path.dentry = dentry;
-                       rc = ll_lov_setstripe_ea_info(inode, &f, it_flags, lump,
-                                                     lum_size);
-                       /* b=10667: rc always be 0 here for now */
-                       rc = 0;
-                } else if (S_ISDIR(inode->i_mode)) {
-                        rc = ll_dir_setstripe(inode, lump, 0);
-                }
+int ll_setxattr(struct dentry *dentry, const char *name,
+               const void *value, size_t size, int flags)
+{
+       struct inode *inode = dentry->d_inode;
 
 
-                return rc;
+       LASSERT(inode);
+       LASSERT(name);
 
 
-        } else if (strcmp(name, XATTR_NAME_LMA) == 0 ||
-                   strcmp(name, XATTR_NAME_LINK) == 0)
-                return 0;
+       CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p), xattr %s\n",
+              PFID(ll_inode2fid(inode)), inode, name);
 
 
-        return ll_setxattr_common(inode, name, value, size, flags,
-                                  OBD_MD_FLXATTR);
+       ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETXATTR, 1);
+
+       /* lustre/trusted.lov.xxx would be passed through xattr API */
+       if (strcmp(name, XATTR_NAME_LOV) == 0 ||
+           strcmp(name, XATTR_LUSTRE_LOV) == 0)
+               return ll_setstripe_ea(dentry, (struct lov_user_md *)value,
+                                      size);
+       else if (strcmp(name, XATTR_NAME_LMA) == 0 ||
+                strcmp(name, XATTR_NAME_LINK) == 0)
+               return 0;
+
+       return ll_setxattr_common(inode, name, value, size, flags,
+                                 OBD_MD_FLXATTR);
 }
 
 int ll_removexattr(struct dentry *dentry, const char *name)
 }
 
 int ll_removexattr(struct dentry *dentry, const char *name)
@@ -472,6 +488,9 @@ static ssize_t ll_getxattr_lov(struct inode *inode, void *buf, size_t buf_size)
                 * otherwise it would confuse tar --xattr by
                 * recognizing layout gen as stripe offset when the
                 * file is restored. See LU-2809. */
                 * otherwise it would confuse tar --xattr by
                 * recognizing layout gen as stripe offset when the
                 * file is restored. See LU-2809. */
+               if (((struct lov_mds_md *)buf)->lmm_magic == LOV_MAGIC_COMP_V1)
+                       goto out_env;
+
                ((struct lov_mds_md *)buf)->lmm_layout_gen = 0;
 out_env:
                cl_env_put(env, &refcheck);
                ((struct lov_mds_md *)buf)->lmm_layout_gen = 0;
 out_env:
                cl_env_put(env, &refcheck);
index c4db325..83b0ff8 100644 (file)
@@ -69,6 +69,30 @@ struct lov_stripe_md {
        struct lov_stripe_md_entry *lsm_entries[];
 };
 
        struct lov_stripe_md_entry *lsm_entries[];
 };
 
+static inline size_t lov_comp_md_size(const struct lov_stripe_md *lsm)
+{
+       struct lov_stripe_md_entry *lsme;
+       size_t size;
+       int entry;
+
+       if (lsm->lsm_magic == LOV_MAGIC_V1 || lsm->lsm_magic == LOV_MAGIC_V3)
+               return lov_mds_md_size(lsm->lsm_entries[0]->lsme_stripe_count,
+                                      lsm->lsm_entries[0]->lsme_magic);
+
+       LASSERT(lsm->lsm_magic == LOV_MAGIC_COMP_V1);
+
+       size = sizeof(struct lov_comp_md_v1);
+       for (entry = 0; entry < lsm->lsm_entry_count; entry++) {
+               lsme = lsm->lsm_entries[entry];
+
+               size += sizeof(*lsme);
+               size += lov_mds_md_size(lsme->lsme_stripe_count,
+                                       lsme->lsme_magic);
+       }
+
+       return size;
+}
+
 static inline bool lsm_has_objects(struct lov_stripe_md *lsm)
 {
        return lsm != NULL && !lsm->lsm_is_released;
 static inline bool lsm_has_objects(struct lov_stripe_md *lsm)
 {
        return lsm != NULL && !lsm->lsm_is_released;
index eb0fe68..da3fc21 100644 (file)
@@ -1641,8 +1641,7 @@ static int lov_object_layout_get(const struct lu_env *env,
                RETURN(0);
        }
 
                RETURN(0);
        }
 
-       cl->cl_size = lov_mds_md_size(lsm->lsm_entries[0]->lsme_stripe_count,
-                                     lsm->lsm_magic);
+       cl->cl_size = lov_comp_md_size(lsm);
        cl->cl_layout_gen = lsm->lsm_layout_gen;
 
        rc = lov_lsm_pack(lsm, buf->lb_buf, buf->lb_len);
        cl->cl_layout_gen = lsm->lsm_layout_gen;
 
        rc = lov_lsm_pack(lsm, buf->lb_buf, buf->lb_len);
index cc8c205..db005e5 100644 (file)
@@ -128,8 +128,8 @@ void lov_dump_lmm(int level, void *lmm)
  * then return the size needed. If \a buf_size is too small then
  * return -ERANGE. Otherwise return the size of the result.
  */
  * then return the size needed. If \a buf_size is too small then
  * return -ERANGE. Otherwise return the size of the result.
  */
-ssize_t lov_lsm_pack(const struct lov_stripe_md *lsm, void *buf,
-                    size_t buf_size)
+ssize_t lov_lsm_pack_v1v3(const struct lov_stripe_md *lsm, void *buf,
+                         size_t buf_size)
 {
        struct lov_mds_md_v1 *lmmv1 = buf;
        struct lov_mds_md_v3 *lmmv3 = buf;
 {
        struct lov_mds_md_v1 *lmmv1 = buf;
        struct lov_mds_md_v3 *lmmv3 = buf;
@@ -180,6 +180,89 @@ ssize_t lov_lsm_pack(const struct lov_stripe_md *lsm, void *buf,
        RETURN(lmm_size);
 }
 
        RETURN(lmm_size);
 }
 
+ssize_t lov_lsm_pack(const struct lov_stripe_md *lsm, void *buf,
+                    size_t buf_size)
+{
+       struct lov_comp_md_v1 *lcmv1 = buf;
+       struct lov_comp_md_entry_v1 *lcme;
+       struct lov_ost_data_v1 *lmm_objects;
+       size_t lmm_size;
+       unsigned int entry;
+       unsigned int offset;
+       unsigned int size;
+       unsigned int i;
+       ENTRY;
+
+       if (lsm->lsm_magic == LOV_MAGIC_V1 || lsm->lsm_magic == LOV_MAGIC_V3)
+               return lov_lsm_pack_v1v3(lsm, buf, buf_size);
+
+       lmm_size = lov_comp_md_size(lsm);
+       if (buf_size == 0)
+               RETURN(lmm_size);
+
+       if (buf_size < lmm_size)
+               RETURN(-ERANGE);
+
+       lcmv1->lcm_magic = cpu_to_le32(lsm->lsm_magic);
+       lcmv1->lcm_size = cpu_to_le32(lmm_size);
+       lcmv1->lcm_layout_gen = cpu_to_le32(lsm->lsm_layout_gen);
+       lcmv1->lcm_entry_count = cpu_to_le16(lsm->lsm_entry_count);
+
+       offset = sizeof(*lcmv1) + sizeof(*lcme) * lsm->lsm_entry_count;
+
+       for (entry = 0; entry < lsm->lsm_entry_count; entry++) {
+               struct lov_stripe_md_entry *lsme;
+               struct lov_mds_md *lmm;
+
+               lsme = lsm->lsm_entries[entry];
+               lcme = &lcmv1->lcm_entries[entry];
+
+               lcme->lcme_id = cpu_to_le32(lsme->lsme_id);
+               lcme->lcme_extent.e_start =
+                       cpu_to_le64(lsme->lsme_extent.e_start);
+               lcme->lcme_extent.e_end =
+                       cpu_to_le64(lsme->lsme_extent.e_end);
+               lcme->lcme_offset = cpu_to_le32(offset);
+
+               lmm = (struct lov_mds_md *)((char *)lcmv1 + offset);
+               lmm->lmm_magic = cpu_to_le32(lsme->lsme_magic);
+               /* lmm->lmm_oi not set */
+               lmm->lmm_pattern = cpu_to_le32(lsme->lsme_pattern);
+               lmm->lmm_stripe_size = cpu_to_le32(lsme->lsme_stripe_size);
+               lmm->lmm_stripe_count = cpu_to_le16(lsme->lsme_stripe_count);
+               lmm->lmm_layout_gen = cpu_to_le16(lsme->lsme_layout_gen);
+
+               if (lsme->lsme_magic == LOV_MAGIC_V3) {
+                       struct lov_mds_md_v3 *lmmv3 =
+                                               (struct lov_mds_md_v3 *)lmm;
+
+                       strlcpy(lmmv3->lmm_pool_name, lsme->lsme_pool_name,
+                               sizeof(lmmv3->lmm_pool_name));
+                       lmm_objects = lmmv3->lmm_objects;
+               } else {
+                       lmm_objects =
+                               ((struct lov_mds_md_v1 *)lmm)->lmm_objects;
+               }
+
+               for (i = 0; i < lsme->lsme_stripe_count; i++) {
+                       struct lov_oinfo *loi = lsme->lsme_oinfo[i];
+
+                       ostid_cpu_to_le(&loi->loi_oi, &lmm_objects[i].l_ost_oi);
+                       lmm_objects[i].l_ost_gen =
+                                       cpu_to_le32(loi->loi_ost_gen);
+                       lmm_objects[i].l_ost_idx =
+                                       cpu_to_le32(loi->loi_ost_idx);
+               }
+
+               size = lov_mds_md_size(lsme->lsme_stripe_count,
+                                      lsme->lsme_magic);
+               lcme->lcme_size = cpu_to_le32(size);
+               offset += size;
+       } /* for each layout component */
+
+       RETURN(lmm_size);
+}
+
 /* Find the max stripecount we should use */
 __u16 lov_get_stripecnt(struct lov_obd *lov, __u32 magic, __u16 stripe_count)
 {
 /* Find the max stripecount we should use */
 __u16 lov_get_stripecnt(struct lov_obd *lov, __u32 magic, __u16 stripe_count)
 {
@@ -254,44 +337,19 @@ int lov_getstripe(struct lov_object *obj, struct lov_stripe_md *lsm,
 {
        /* we use lov_user_md_v3 because it is larger than lov_user_md_v1 */
        struct lov_mds_md       *lmmk;
 {
        /* we use lov_user_md_v3 because it is larger than lov_user_md_v1 */
        struct lov_mds_md       *lmmk;
-       struct lov_user_md_v3   lum;
-       u32                     stripe_count;
-       size_t                  lum_size;
        size_t                  lmmk_size;
        ssize_t                 lmm_size;
        size_t                  lmmk_size;
        ssize_t                 lmm_size;
-       int                     rc;
+       int                     rc = 0;
        ENTRY;
 
        ENTRY;
 
-       if (lsm->lsm_magic != LOV_MAGIC_V1 && lsm->lsm_magic != LOV_MAGIC_V3) {
+       if (lsm->lsm_magic != LOV_MAGIC_V1 && lsm->lsm_magic != LOV_MAGIC_V3 &&
+           lsm->lsm_magic != LOV_MAGIC_COMP_V1) {
                CERROR("bad LSM MAGIC: 0x%08X != 0x%08X nor 0x%08X\n",
                       lsm->lsm_magic, LOV_MAGIC_V1, LOV_MAGIC_V3);
                GOTO(out, rc = -EIO);
        }
 
                CERROR("bad LSM MAGIC: 0x%08X != 0x%08X nor 0x%08X\n",
                       lsm->lsm_magic, LOV_MAGIC_V1, LOV_MAGIC_V3);
                GOTO(out, rc = -EIO);
        }
 
-       if (!lsm->lsm_is_released)
-               stripe_count = lsm->lsm_entries[0]->lsme_stripe_count;
-       else
-               stripe_count = 0;
-
-       /* we only need the header part from user space to get lmm_magic and
-        * lmm_stripe_count, (the header part is common to v1 and v3) */
-       lum_size = sizeof(struct lov_user_md_v1);
-       if (copy_from_user(&lum, lump, lum_size))
-               GOTO(out, rc = -EFAULT);
-
-       if (lum.lmm_magic != LOV_USER_MAGIC_V1 &&
-           lum.lmm_magic != LOV_USER_MAGIC_V3 &&
-           lum.lmm_magic != LOV_USER_MAGIC_SPECIFIC)
-               GOTO(out, rc = -EINVAL);
-
-       if (lum.lmm_stripe_count != 0 && lum.lmm_stripe_count < stripe_count) {
-               /* Return right size of stripe to user */
-               lum.lmm_stripe_count = stripe_count;
-               rc = copy_to_user(lump, &lum, lum_size);
-               GOTO(out, rc = -EOVERFLOW);
-       }
-
-       lmmk_size = lov_mds_md_size(stripe_count, lsm->lsm_magic);
+       lmmk_size = lov_comp_md_size(lsm);
 
        OBD_ALLOC_LARGE(lmmk, lmmk_size);
        if (lmmk == NULL)
 
        OBD_ALLOC_LARGE(lmmk, lmmk_size);
        if (lmmk == NULL)
@@ -301,53 +359,24 @@ int lov_getstripe(struct lov_object *obj, struct lov_stripe_md *lsm,
        if (lmm_size < 0)
                GOTO(out_free, rc = lmm_size);
 
        if (lmm_size < 0)
                GOTO(out_free, rc = lmm_size);
 
-       /* FIXME: Bug 1185 - copy fields properly when structs change */
-       /* struct lov_user_md_v3 and struct lov_mds_md_v3 must be the same */
-       CLASSERT(sizeof(lum) == sizeof(struct lov_mds_md_v3));
-       CLASSERT(sizeof(lum.lmm_objects[0]) == sizeof(lmmk->lmm_objects[0]));
-
-       if (cpu_to_le32(LOV_MAGIC) != 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);
-               lustre_swab_lov_user_md_objects(
+       if (cpu_to_le32(LOV_MAGIC) != LOV_MAGIC) {
+               if (lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V1) ||
+                   lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V3)) {
+                       lustre_swab_lov_mds_md(lmmk);
+                       lustre_swab_lov_user_md_objects(
                                (struct lov_user_ost_data *)lmmk->lmm_objects,
                                lmmk->lmm_stripe_count);
                                (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(((struct lov_mds_md_v1 *)lmmk)->lmm_objects,
-                               ((struct lov_mds_md_v3 *)lmmk)->lmm_objects,
-                               lmmk->lmm_stripe_count *
-                               sizeof(struct lov_ost_data_v1));
-                       lmm_size -= LOV_MAXPOOLNAME;
+               } else if (lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_COMP_V1)) {
+                       lustre_swab_lov_comp_md_v1(
+                                       (struct lov_comp_md_v1 *)lmmk);
                }
                }
-       } else {
-               /* 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)
-               GOTO(out_free, rc = -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;
-       lum.lmm_layout_gen = lmmk->lmm_layout_gen;
-       ((struct lov_user_md *)lmmk)->lmm_layout_gen = lum.lmm_layout_gen;
-       ((struct lov_user_md *)lmmk)->lmm_stripe_count = lum.lmm_stripe_count;
-       if (copy_to_user(lump, lmmk, lmm_size))
+       if (copy_to_user(lump, lmmk, lmmk_size))
                GOTO(out_free, rc = -EFAULT);
 
                GOTO(out_free, rc = -EFAULT);
 
-       GOTO(out_free, rc = 0);
 out_free:
        OBD_FREE_LARGE(lmmk, lmmk_size);
 out:
 out_free:
        OBD_FREE_LARGE(lmmk, lmmk_size);
 out:
-       return rc;
+       RETURN(rc);
 }
 }