Commit fad3a392 authored by wang di's avatar wang di Committed by Greg Kroah-Hartman

staging: lustre: lmv: change handling of lmv striping information

The lmv_[un]pack_md function are used to calculate the
size of the data used to represent the LMV striping data.
The original code was straight forward in its calculate
with lmv_get_easize since only one type of data format
could exist. We want to be able to support different
version of this data in the future so this patch moves
to generating the size of the data using the stripe count
and which LMV_MAGIC_* version.
Signed-off-by: default avatarwang di <di.wang@intel.com>
Reviewed-on: http://review.whamcloud.com/7043
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3531Reviewed-by: default avatarJohn L. Hammond <john.hammond@intel.com>
Reviewed-by: default avatarJinshan Xiong <jinshan.xiong@intel.com>
Reviewed-by: default avatarAndreas Dilger <andreas.dilger@intel.com>
Reviewed-by: default avatarOleg Drokin <oleg.drokin@intel.com>
Signed-off-by: default avatarJames Simmons <jsimmons@infradead.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e7deb890
...@@ -2482,10 +2482,6 @@ struct lmv_desc { ...@@ -2482,10 +2482,6 @@ struct lmv_desc {
struct obd_uuid ld_uuid; struct obd_uuid ld_uuid;
}; };
#define MEA_MAGIC_LAST_CHAR 0xb2221ca1
#define MEA_MAGIC_ALL_CHARS 0xb222a11c
#define MEA_MAGIC_HASH_SEGMENT 0xb222a11b
/* lmv structures */ /* lmv structures */
#define LMV_MAGIC_V1 0x0CD10CD0 /* normal stripe lmv magic */ #define LMV_MAGIC_V1 0x0CD10CD0 /* normal stripe lmv magic */
#define LMV_USER_MAGIC 0x0CD20CD0 /* default lmv magic*/ #define LMV_USER_MAGIC 0x0CD20CD0 /* default lmv magic*/
......
...@@ -41,12 +41,15 @@ struct lmv_oinfo { ...@@ -41,12 +41,15 @@ struct lmv_oinfo {
}; };
struct lmv_stripe_md { struct lmv_stripe_md {
__u32 mea_magic; __u32 lsm_md_magic;
__u32 mea_count; __u32 lsm_md_stripe_count;
__u32 mea_master; __u32 lsm_md_master_mdt_index;
__u32 mea_padding; __u32 lsm_md_hash_type;
char mea_pool_name[LOV_MAXPOOLNAME]; __u32 lsm_md_layout_version;
struct lu_fid mea_ids[0]; __u32 lsm_md_default_count;
__u32 lsm_md_default_index;
char lsm_md_pool_name[LOV_MAXPOOLNAME];
struct lmv_oinfo lsm_md_oinfo[0];
}; };
union lmv_mds_md; union lmv_mds_md;
......
...@@ -94,6 +94,13 @@ lmv_find_target(struct lmv_obd *lmv, const struct lu_fid *fid) ...@@ -94,6 +94,13 @@ lmv_find_target(struct lmv_obd *lmv, const struct lu_fid *fid)
return lmv_get_target(lmv, mds); return lmv_get_target(lmv, mds);
} }
static inline int lmv_stripe_md_size(int stripe_count)
{
struct lmv_stripe_md *lsm;
return sizeof(*lsm) + stripe_count * sizeof(lsm->lsm_md_oinfo[0]);
}
struct lmv_tgt_desc struct lmv_tgt_desc
*lmv_locate_mds(struct lmv_obd *lmv, struct md_op_data *op_data, *lmv_locate_mds(struct lmv_obd *lmv, struct md_op_data *op_data,
struct lu_fid *fid); struct lu_fid *fid);
......
...@@ -2376,105 +2376,224 @@ static int lmv_set_info_async(const struct lu_env *env, struct obd_export *exp, ...@@ -2376,105 +2376,224 @@ static int lmv_set_info_async(const struct lu_env *env, struct obd_export *exp,
return -EINVAL; return -EINVAL;
} }
static int lmv_packmd(struct obd_export *exp, struct lov_mds_md **lmmp, static int lmv_pack_md_v1(const struct lmv_stripe_md *lsm,
struct lov_stripe_md *lsm) struct lmv_mds_md_v1 *lmm1)
{ {
struct obd_device *obd = class_exp2obd(exp); int cplen;
struct lmv_obd *lmv = &obd->u.lmv; int i;
struct lmv_stripe_md *meap;
struct lmv_stripe_md *lsmp; lmm1->lmv_magic = cpu_to_le32(lsm->lsm_md_magic);
int mea_size; lmm1->lmv_stripe_count = cpu_to_le32(lsm->lsm_md_stripe_count);
int i; lmm1->lmv_master_mdt_index = cpu_to_le32(lsm->lsm_md_master_mdt_index);
lmm1->lmv_hash_type = cpu_to_le32(lsm->lsm_md_hash_type);
cplen = strlcpy(lmm1->lmv_pool_name, lsm->lsm_md_pool_name,
sizeof(lmm1->lmv_pool_name));
if (cplen >= sizeof(lmm1->lmv_pool_name))
return -E2BIG;
for (i = 0; i < lsm->lsm_md_stripe_count; i++)
fid_cpu_to_le(&lmm1->lmv_stripe_fids[i],
&lsm->lsm_md_oinfo[i].lmo_fid);
return 0;
}
int lmv_pack_md(union lmv_mds_md **lmmp, const struct lmv_stripe_md *lsm,
int stripe_count)
{
int lmm_size = 0, rc = 0;
bool allocated = false;
mea_size = lmv_get_easize(lmv); LASSERT(lmmp);
if (!lmmp)
return mea_size;
/* Free lmm */
if (*lmmp && !lsm) { if (*lmmp && !lsm) {
int stripe_cnt;
stripe_cnt = lmv_mds_md_stripe_count_get(*lmmp);
lmm_size = lmv_mds_md_size(stripe_cnt,
le32_to_cpu((*lmmp)->lmv_magic));
if (!lmm_size)
return -EINVAL;
kvfree(*lmmp); kvfree(*lmmp);
*lmmp = NULL; *lmmp = NULL;
return 0; return 0;
} }
/* Alloc lmm */
if (!*lmmp && !lsm) {
lmm_size = lmv_mds_md_size(stripe_count, LMV_MAGIC);
LASSERT(lmm_size > 0);
*lmmp = libcfs_kvzalloc(lmm_size, GFP_NOFS);
if (!*lmmp)
return -ENOMEM;
lmv_mds_md_stripe_count_set(*lmmp, stripe_count);
(*lmmp)->lmv_magic = cpu_to_le32(LMV_MAGIC);
return lmm_size;
}
/* pack lmm */
LASSERT(lsm);
lmm_size = lmv_mds_md_size(lsm->lsm_md_stripe_count,
lsm->lsm_md_magic);
if (!*lmmp) { if (!*lmmp) {
*lmmp = libcfs_kvzalloc(mea_size, GFP_NOFS); *lmmp = libcfs_kvzalloc(lmm_size, GFP_NOFS);
if (!*lmmp) if (!*lmmp)
return -ENOMEM; return -ENOMEM;
allocated = true;
} }
if (!lsm) switch (lsm->lsm_md_magic) {
return mea_size; case LMV_MAGIC_V1:
rc = lmv_pack_md_v1(lsm, &(*lmmp)->lmv_md_v1);
break;
default:
rc = -EINVAL;
break;
}
lsmp = (struct lmv_stripe_md *)lsm; if (rc && allocated) {
meap = (struct lmv_stripe_md *)*lmmp; kvfree(*lmmp);
*lmmp = NULL;
}
if (lsmp->mea_magic != MEA_MAGIC_LAST_CHAR && return lmm_size;
lsmp->mea_magic != MEA_MAGIC_ALL_CHARS) }
return -EINVAL; EXPORT_SYMBOL(lmv_pack_md);
meap->mea_magic = cpu_to_le32(lsmp->mea_magic); static int lmv_unpack_md_v1(struct obd_export *exp, struct lmv_stripe_md *lsm,
meap->mea_count = cpu_to_le32(lsmp->mea_count); const struct lmv_mds_md_v1 *lmm1)
meap->mea_master = cpu_to_le32(lsmp->mea_master); {
struct lmv_obd *lmv = &exp->exp_obd->u.lmv;
int stripe_count;
int rc = 0;
int cplen;
int i;
for (i = 0; i < lmv->desc.ld_tgt_count; i++) { lsm->lsm_md_magic = le32_to_cpu(lmm1->lmv_magic);
meap->mea_ids[i] = lsmp->mea_ids[i]; lsm->lsm_md_stripe_count = le32_to_cpu(lmm1->lmv_stripe_count);
fid_cpu_to_le(&meap->mea_ids[i], &lsmp->mea_ids[i]); lsm->lsm_md_master_mdt_index = le32_to_cpu(lmm1->lmv_master_mdt_index);
lsm->lsm_md_hash_type = le32_to_cpu(lmm1->lmv_hash_type);
lsm->lsm_md_layout_version = le32_to_cpu(lmm1->lmv_layout_version);
cplen = strlcpy(lsm->lsm_md_pool_name, lmm1->lmv_pool_name,
sizeof(lsm->lsm_md_pool_name));
if (cplen >= sizeof(lsm->lsm_md_pool_name))
return -E2BIG;
CDEBUG(D_INFO, "unpack lsm count %d, master %d hash_type %d layout_version %d\n",
lsm->lsm_md_stripe_count, lsm->lsm_md_master_mdt_index,
lsm->lsm_md_hash_type, lsm->lsm_md_layout_version);
stripe_count = le32_to_cpu(lmm1->lmv_stripe_count);
for (i = 0; i < le32_to_cpu(stripe_count); i++) {
fid_le_to_cpu(&lsm->lsm_md_oinfo[i].lmo_fid,
&lmm1->lmv_stripe_fids[i]);
rc = lmv_fld_lookup(lmv, &lsm->lsm_md_oinfo[i].lmo_fid,
&lsm->lsm_md_oinfo[i].lmo_mds);
if (rc)
return rc;
CDEBUG(D_INFO, "unpack fid #%d "DFID"\n", i,
PFID(&lsm->lsm_md_oinfo[i].lmo_fid));
} }
return mea_size; return rc;
} }
static int lmv_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp, int lmv_unpack_md(struct obd_export *exp, struct lmv_stripe_md **lsmp,
struct lov_mds_md *lmm, int lmm_size) const union lmv_mds_md *lmm, int stripe_count)
{ {
struct obd_device *obd = class_exp2obd(exp); struct lmv_stripe_md *lsm;
struct lmv_stripe_md **tmea = (struct lmv_stripe_md **)lsmp; bool allocated = false;
struct lmv_stripe_md *mea = (struct lmv_stripe_md *)lmm; int lsm_size, rc;
struct lmv_obd *lmv = &obd->u.lmv;
int mea_size; LASSERT(lsmp);
int i;
__u32 magic; lsm = *lsmp;
/* Free memmd */
if (lsm && !lmm) {
int i;
mea_size = lmv_get_easize(lmv); for (i = 1; i < lsm->lsm_md_stripe_count; i++) {
if (!lsmp) if (lsm->lsm_md_oinfo[i].lmo_root)
return mea_size; iput(lsm->lsm_md_oinfo[i].lmo_root);
}
if (*lsmp && !lmm) { kvfree(lsm);
kvfree(*tmea);
*lsmp = NULL; *lsmp = NULL;
return 0; return 0;
} }
LASSERT(mea_size == lmm_size); /* Alloc memmd */
if (!lsm && !lmm) {
lsm_size = lmv_stripe_md_size(stripe_count);
lsm = libcfs_kvzalloc(lsm_size, GFP_NOFS);
if (!lsm)
return -ENOMEM;
lsm->lsm_md_stripe_count = stripe_count;
*lsmp = lsm;
return 0;
}
*tmea = libcfs_kvzalloc(mea_size, GFP_NOFS); /* Unpack memmd */
if (!*tmea) if (le32_to_cpu(lmm->lmv_magic) != LMV_MAGIC_V1) {
return -ENOMEM; CERROR("%s: invalid magic %x.\n", exp->exp_obd->obd_name,
le32_to_cpu(lmm->lmv_magic));
return -EINVAL;
}
if (!lmm) lsm_size = lmv_stripe_md_size(lmv_mds_md_stripe_count_get(lmm));
return mea_size; if (!lsm) {
lsm = libcfs_kvzalloc(lsm_size, GFP_NOFS);
if (!lsm)
return -ENOMEM;
allocated = true;
*lsmp = lsm;
}
if (mea->mea_magic == MEA_MAGIC_LAST_CHAR || switch (le32_to_cpu(lmm->lmv_magic)) {
mea->mea_magic == MEA_MAGIC_ALL_CHARS || case LMV_MAGIC_V1:
mea->mea_magic == MEA_MAGIC_HASH_SEGMENT) { rc = lmv_unpack_md_v1(exp, lsm, &lmm->lmv_md_v1);
magic = le32_to_cpu(mea->mea_magic); break;
} else { default:
/* CERROR("%s: unrecognized magic %x\n", exp->exp_obd->obd_name,
* Old mea is not handled here. le32_to_cpu(lmm->lmv_magic));
*/ rc = -EINVAL;
CERROR("Old not supportable EA is found\n"); break;
LBUG();
} }
(*tmea)->mea_magic = magic; if (rc && allocated) {
(*tmea)->mea_count = le32_to_cpu(mea->mea_count); kvfree(lsm);
(*tmea)->mea_master = le32_to_cpu(mea->mea_master); *lsmp = NULL;
lsm_size = rc;
}
return lsm_size;
}
for (i = 0; i < (*tmea)->mea_count; i++) { int lmv_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp,
(*tmea)->mea_ids[i] = mea->mea_ids[i]; struct lov_mds_md *lmm, int disk_len)
fid_le_to_cpu(&(*tmea)->mea_ids[i], &(*tmea)->mea_ids[i]); {
return lmv_unpack_md(exp, (struct lmv_stripe_md **)lsmp,
(union lmv_mds_md *)lmm, disk_len);
}
int lmv_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
struct lov_stripe_md *lsm)
{
const struct lmv_stripe_md *lmv = (struct lmv_stripe_md *)lsm;
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv_obd = &obd->u.lmv;
int stripe_count;
if (!lmmp) {
if (lsm)
stripe_count = lmv->lsm_md_stripe_count;
else
stripe_count = lmv_obd->desc.ld_tgt_count;
return lmv_mds_md_size(stripe_count, LMV_MAGIC_V1);
} }
return mea_size;
return lmv_pack_md((union lmv_mds_md **)lmmp, lmv, 0);
} }
static int lmv_cancel_unused(struct obd_export *exp, const struct lu_fid *fid, static int lmv_cancel_unused(struct obd_export *exp, const struct lu_fid *fid,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment