From: Niu Yawei Date: Thu, 12 Jan 2017 14:48:19 +0000 (-0500) Subject: LU-8998 clio: getstripe support comp layout X-Git-Tag: 2.9.56~46^2~16 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=fafe6b4d4a6fa63cedff3bd44e6578009578b3d7 LU-8998 clio: getstripe support comp layout {get/set}stripe support composite layout Signed-off-by: Bobi Jam Signed-off-by: Niu Yawei Change-Id: Iafe5205a79f721be1ec5ec83ab80a86a4b537e18 Reviewed-on: https://review.whamcloud.com/24851 Tested-by: Jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Lai Siyao Reviewed-by: Jinshan Xiong --- diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index b171f3e..c78767e 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -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; } + 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( @@ -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 */ - 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; @@ -625,23 +637,23 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, 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 */ - 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 */ - 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: @@ -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; + 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); @@ -1254,36 +1271,37 @@ lmv_out_free: 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; - 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 ((lumv1->lmm_magic == LOV_USER_MAGIC_V3) ) { + if (lumv1->lmm_magic == LOV_USER_MAGIC_V3) if (copy_from_user(&lumv3, lumv3p, sizeof(lumv3))) - RETURN(-EFAULT); - } + RETURN(-EFAULT); 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; diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 2b68937..c3b8cef 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -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); - 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 @@ -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; - 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)) { - 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( - (struct lov_user_md_v3 *)lmm); + (struct lov_user_md_v3 *)lmm); 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: @@ -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); - 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); diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index cd34ccb..854c6cb5 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -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); + case LOV_USER_MAGIC_COMP_V1: + return ((struct lov_comp_md_v1 *)lum)->lcm_size; } return -EINVAL; diff --git a/lustre/llite/xattr.c b/lustre/llite/xattr.c index ca0e5c9..9d9260b 100644 --- a/lustre/llite/xattr.c +++ b/lustre/llite/xattr.c @@ -209,82 +209,98 @@ static int get_hsm_state(struct inode *inode, __u32 *hus_states) 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) @@ -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. */ + 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); diff --git a/lustre/lov/lov_internal.h b/lustre/lov/lov_internal.h index c4db325..83b0ff8 100644 --- a/lustre/lov/lov_internal.h +++ b/lustre/lov/lov_internal.h @@ -69,6 +69,30 @@ struct lov_stripe_md { 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; diff --git a/lustre/lov/lov_object.c b/lustre/lov/lov_object.c index eb0fe68..da3fc21 100644 --- a/lustre/lov/lov_object.c +++ b/lustre/lov/lov_object.c @@ -1641,8 +1641,7 @@ static int lov_object_layout_get(const struct lu_env *env, 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); diff --git a/lustre/lov/lov_pack.c b/lustre/lov/lov_pack.c index cc8c205..db005e5 100644 --- a/lustre/lov/lov_pack.c +++ b/lustre/lov/lov_pack.c @@ -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. */ -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; @@ -180,6 +180,89 @@ ssize_t lov_lsm_pack(const struct lov_stripe_md *lsm, void *buf, 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) { @@ -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; - struct lov_user_md_v3 lum; - u32 stripe_count; - size_t lum_size; size_t lmmk_size; ssize_t lmm_size; - int rc; + int rc = 0; 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); } - 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) @@ -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); - /* 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); - } - - 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 = 0); out_free: OBD_FREE_LARGE(lmmk, lmmk_size); out: - return rc; + RETURN(rc); }