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

staging: lustre: lmv: Match MDT where the FID locates first

With DNE every object can have two locks in different namespaces:
lookup lock in space of MDT storing direntry and update/open lock
in space of MDT storing inode. In lmv_find_cbdata/lmv_lock_lock,
it should try the MDT that the FID maps to first, since this can
be easily found, and only try others if that fails.

In the error handler of lmv_add_targets, it should check whether
ld_tgt_count is being increased before ld_tgt_count is being -1.
Signed-off-by: default avatarwang di <di.wang@intel.com>
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4098
Reviewed-on: http://review.whamcloud.com/8019Reviewed-by: default avatarAndreas Dilger <andreas.dilger@intel.com>
Reviewed-by: default avatarFan Yong <fan.yong@intel.com>
Signed-off-by: default avatarJames Simmons <jsimmons@infradead.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 865b734e
...@@ -64,35 +64,56 @@ int lmv_revalidate_slaves(struct obd_export *exp, struct mdt_body *mbody, ...@@ -64,35 +64,56 @@ int lmv_revalidate_slaves(struct obd_export *exp, struct mdt_body *mbody,
int extra_lock_flags); int extra_lock_flags);
static inline struct lmv_tgt_desc * static inline struct lmv_tgt_desc *
lmv_get_target(struct lmv_obd *lmv, u32 mds) lmv_get_target(struct lmv_obd *lmv, u32 mdt_idx, int *index)
{ {
int count = lmv->desc.ld_tgt_count;
int i; int i;
for (i = 0; i < count; i++) { for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
if (!lmv->tgts[i]) if (!lmv->tgts[i])
continue; continue;
if (lmv->tgts[i]->ltd_idx == mds) if (lmv->tgts[i]->ltd_idx == mdt_idx) {
if (index)
*index = i;
return lmv->tgts[i]; return lmv->tgts[i];
}
} }
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
} }
static inline struct lmv_tgt_desc * static inline int
lmv_find_target(struct lmv_obd *lmv, const struct lu_fid *fid) lmv_find_target_index(struct lmv_obd *lmv, const struct lu_fid *fid)
{ {
u32 mds = 0; struct lmv_tgt_desc *ltd;
int rc; u32 mdt_idx = 0;
int index = 0;
if (lmv->desc.ld_tgt_count > 1) { if (lmv->desc.ld_tgt_count > 1) {
rc = lmv_fld_lookup(lmv, fid, &mds); int rc;
if (rc)
return ERR_PTR(rc); rc = lmv_fld_lookup(lmv, fid, &mdt_idx);
if (rc < 0)
return rc;
} }
return lmv_get_target(lmv, mds); ltd = lmv_get_target(lmv, mdt_idx, &index);
if (IS_ERR(ltd))
return PTR_ERR(ltd);
return index;
}
static inline struct lmv_tgt_desc *
lmv_find_target(struct lmv_obd *lmv, const struct lu_fid *fid)
{
int index;
index = lmv_find_target_index(lmv, fid);
if (index < 0)
return ERR_PTR(index);
return lmv->tgts[index];
} }
static inline int lmv_stripe_md_size(int stripe_count) static inline int lmv_stripe_md_size(int stripe_count)
......
...@@ -480,6 +480,7 @@ static int lmv_add_target(struct obd_device *obd, struct obd_uuid *uuidp, ...@@ -480,6 +480,7 @@ static int lmv_add_target(struct obd_device *obd, struct obd_uuid *uuidp,
{ {
struct lmv_obd *lmv = &obd->u.lmv; struct lmv_obd *lmv = &obd->u.lmv;
struct lmv_tgt_desc *tgt; struct lmv_tgt_desc *tgt;
int orig_tgt_count = 0;
int rc = 0; int rc = 0;
CDEBUG(D_CONFIG, "Target uuid: %s. index %d\n", uuidp->uuid, index); CDEBUG(D_CONFIG, "Target uuid: %s. index %d\n", uuidp->uuid, index);
...@@ -549,14 +550,17 @@ static int lmv_add_target(struct obd_device *obd, struct obd_uuid *uuidp, ...@@ -549,14 +550,17 @@ static int lmv_add_target(struct obd_device *obd, struct obd_uuid *uuidp,
tgt->ltd_uuid = *uuidp; tgt->ltd_uuid = *uuidp;
tgt->ltd_active = 0; tgt->ltd_active = 0;
lmv->tgts[index] = tgt; lmv->tgts[index] = tgt;
if (index >= lmv->desc.ld_tgt_count) if (index >= lmv->desc.ld_tgt_count) {
orig_tgt_count = lmv->desc.ld_tgt_count;
lmv->desc.ld_tgt_count = index + 1; lmv->desc.ld_tgt_count = index + 1;
}
if (lmv->connected) { if (lmv->connected) {
rc = lmv_connect_mdc(obd, tgt); rc = lmv_connect_mdc(obd, tgt);
if (rc) { if (rc) {
spin_lock(&lmv->lmv_lock); spin_lock(&lmv->lmv_lock);
lmv->desc.ld_tgt_count--; if (lmv->desc.ld_tgt_count == index + 1)
lmv->desc.ld_tgt_count = orig_tgt_count;
memset(tgt, 0, sizeof(*tgt)); memset(tgt, 0, sizeof(*tgt));
spin_unlock(&lmv->lmv_lock); spin_unlock(&lmv->lmv_lock);
} else { } else {
...@@ -1263,7 +1267,7 @@ int __lmv_fid_alloc(struct lmv_obd *lmv, struct lu_fid *fid, u32 mds) ...@@ -1263,7 +1267,7 @@ int __lmv_fid_alloc(struct lmv_obd *lmv, struct lu_fid *fid, u32 mds)
struct lmv_tgt_desc *tgt; struct lmv_tgt_desc *tgt;
int rc; int rc;
tgt = lmv_get_target(lmv, mds); tgt = lmv_get_target(lmv, mds, NULL);
if (IS_ERR(tgt)) if (IS_ERR(tgt))
return PTR_ERR(tgt); return PTR_ERR(tgt);
...@@ -1610,6 +1614,7 @@ static int lmv_find_cbdata(struct obd_export *exp, const struct lu_fid *fid, ...@@ -1610,6 +1614,7 @@ static int lmv_find_cbdata(struct obd_export *exp, const struct lu_fid *fid,
{ {
struct obd_device *obd = exp->exp_obd; struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv; struct lmv_obd *lmv = &obd->u.lmv;
int tgt;
int i; int i;
int rc; int rc;
...@@ -1622,12 +1627,22 @@ static int lmv_find_cbdata(struct obd_export *exp, const struct lu_fid *fid, ...@@ -1622,12 +1627,22 @@ static int lmv_find_cbdata(struct obd_export *exp, const struct lu_fid *fid,
/* /*
* With DNE every object can have two locks in different namespaces: * With DNE every object can have two locks in different namespaces:
* lookup lock in space of MDT storing direntry and update/open lock in * lookup lock in space of MDT storing direntry and update/open lock in
* space of MDT storing inode. * space of MDT storing inode. Try the MDT that the FID maps to first,
* since this can be easily found, and only try others if that fails.
*/ */
for (i = 0; i < lmv->desc.ld_tgt_count; i++) { for (i = 0, tgt = lmv_find_target_index(lmv, fid);
if (!lmv->tgts[i] || !lmv->tgts[i]->ltd_exp) i < lmv->desc.ld_tgt_count;
i++, tgt = (tgt + 1) % lmv->desc.ld_tgt_count) {
if (tgt < 0) {
CDEBUG(D_HA, "%s: "DFID" is inaccessible: rc = %d\n",
obd->obd_name, PFID(fid), tgt);
tgt = 0;
}
if (!lmv->tgts[tgt] || !lmv->tgts[tgt]->ltd_exp)
continue; continue;
rc = md_find_cbdata(lmv->tgts[i]->ltd_exp, fid, it, data);
rc = md_find_cbdata(lmv->tgts[tgt]->ltd_exp, fid, it, data);
if (rc) if (rc)
return rc; return rc;
} }
...@@ -1676,7 +1691,7 @@ lmv_locate_target_for_name(struct lmv_obd *lmv, struct lmv_stripe_md *lsm, ...@@ -1676,7 +1691,7 @@ lmv_locate_target_for_name(struct lmv_obd *lmv, struct lmv_stripe_md *lsm,
*fid = oinfo->lmo_fid; *fid = oinfo->lmo_fid;
*mds = oinfo->lmo_mds; *mds = oinfo->lmo_mds;
tgt = lmv_get_target(lmv, *mds); tgt = lmv_get_target(lmv, *mds, NULL);
CDEBUG(D_INFO, "locate on mds %u "DFID"\n", *mds, PFID(fid)); CDEBUG(D_INFO, "locate on mds %u "DFID"\n", *mds, PFID(fid));
return tgt; return tgt;
...@@ -2866,24 +2881,32 @@ static enum ldlm_mode lmv_lock_match(struct obd_export *exp, __u64 flags, ...@@ -2866,24 +2881,32 @@ static enum ldlm_mode lmv_lock_match(struct obd_export *exp, __u64 flags,
struct obd_device *obd = exp->exp_obd; struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv; struct lmv_obd *lmv = &obd->u.lmv;
enum ldlm_mode rc; enum ldlm_mode rc;
int tgt;
int i; int i;
CDEBUG(D_INODE, "Lock match for "DFID"\n", PFID(fid)); CDEBUG(D_INODE, "Lock match for "DFID"\n", PFID(fid));
/* /*
* With CMD every object can have two locks in different namespaces: * With DNE every object can have two locks in different namespaces:
* lookup lock in space of mds storing direntry and update/open lock in * lookup lock in space of MDT storing direntry and update/open lock in
* space of mds storing inode. Thus we check all targets, not only that * space of MDT storing inode. Try the MDT that the FID maps to first,
* one fid was created in. * since this can be easily found, and only try others if that fails.
*/ */
for (i = 0; i < lmv->desc.ld_tgt_count; i++) { for (i = 0, tgt = lmv_find_target_index(lmv, fid);
struct lmv_tgt_desc *tgt = lmv->tgts[i]; i < lmv->desc.ld_tgt_count;
i++, tgt = (tgt + 1) % lmv->desc.ld_tgt_count) {
if (tgt < 0) {
CDEBUG(D_HA, "%s: "DFID" is inaccessible: rc = %d\n",
obd->obd_name, PFID(fid), tgt);
tgt = 0;
}
if (!tgt || !tgt->ltd_exp || !tgt->ltd_active) if (!lmv->tgts[tgt] || !lmv->tgts[tgt]->ltd_exp ||
!lmv->tgts[tgt]->ltd_active)
continue; continue;
rc = md_lock_match(tgt->ltd_exp, flags, fid, type, policy, mode, rc = md_lock_match(lmv->tgts[tgt]->ltd_exp, flags, fid,
lockh); type, policy, mode, lockh);
if (rc) if (rc)
return rc; return rc;
} }
......
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