From 03bbd4c27471751ada57282fad15e074ae01e9d7 Mon Sep 17 00:00:00 2001 From: Fan Yong Date: Fri, 7 Jul 2017 23:24:14 +0800 Subject: [PATCH 1/1] LU-9753 ofd: 64-bits diff variable to avoid overflow In ofd_create_hdl(), the logic will compare the OST stroed LAST_ID with the MDT given one: if the difference exceeds some threshold, then it will trust the OST LAST_ID directly and reset the MDT side value with the OST one. Otherwise, the orphan OST-objects will be destroyed. Unfortunately, both the OST stored LAST_ID and MDT given one are 64 bits, but the @diff variable is only 32 bits, and if the OST side value is too larger than the MDT side, then the @diff will overflow. That will misguide the OST to destroy useful OST-objects by wrong. This patch change the @diff as 64 bits variable. Signed-off-by: Fan Yong Change-Id: If75899cbab5754be4ede226e0463ba5f69d70e3d Reviewed-on: https://review.whamcloud.com/27975 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Alex Zhuravlev Reviewed-by: Oleg Drokin --- lustre/include/lu_target.h | 2 +- lustre/ofd/ofd_dev.c | 24 ++++++++++++++++-------- lustre/ofd/ofd_obd.c | 7 ++++--- lustre/target/tgt_grant.c | 2 +- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/lustre/include/lu_target.h b/lustre/include/lu_target.h index 307fff8..0d3ef96 100644 --- a/lustre/include/lu_target.h +++ b/lustre/include/lu_target.h @@ -519,7 +519,7 @@ void tgt_grant_commit(struct obd_export *exp, unsigned long grant_used, int rc); int tgt_grant_commit_cb_add(struct thandle *th, struct obd_export *exp, unsigned long grant); long tgt_grant_create(const struct lu_env *env, struct obd_export *exp, - int *nr); + s64 *nr); int tgt_statfs_internal(const struct lu_env *env, struct lu_target *lut, struct obd_statfs *osfs, __u64 max_age, int *from_cache); diff --git a/lustre/ofd/ofd_dev.c b/lustre/ofd/ofd_dev.c index 7c8fa9e..2476f9e 100644 --- a/lustre/ofd/ofd_dev.c +++ b/lustre/ofd/ofd_dev.c @@ -1559,7 +1559,8 @@ static int ofd_create_hdl(struct tgt_session_info *tsi) u64 seq = ostid_seq(&oa->o_oi); u64 oid = ostid_id(&oa->o_oi); struct ofd_seq *oseq; - int rc = 0, diff; + s64 diff; + int rc = 0; int sync_trans = 0; long granted = 0; @@ -1629,9 +1630,16 @@ static int ofd_create_hdl(struct tgt_session_info *tsi) GOTO(out, rc); } diff = oid - ofd_seq_last_oid(oseq); - CDEBUG(D_HA, "ofd_last_id() = %llu -> diff = %d\n", - ofd_seq_last_oid(oseq), diff); + CDEBUG(D_HA, "ofd_last_id() = %llu -> diff = %lld\n", + ofd_seq_last_oid(oseq), diff); if (-diff > OST_MAX_PRECREATE) { + LCONSOLE(D_INFO, "%s: too large difference between MDS " + "LAST_ID "DFID" (%llu) and OST LAST_ID "DFID" " + "(%llu), trust the OST\n", + ofd_name(ofd), PFID(&oa->o_oi.oi_fid), oid, + PFID(&oseq->os_oi.oi_fid), + ofd_seq_last_oid(oseq)); + /* Let MDS know that we are so far ahead. */ rc = ostid_set_id(&rep_oa->o_oi, ofd_seq_last_oid(oseq) + 1); @@ -1706,7 +1714,7 @@ static int ofd_create_hdl(struct tgt_session_info *tsi) rc = granted; granted = 0; CDEBUG(D_HA, "%s: failed to acquire grant " - "space for precreate (%d): rc = %d\n", + "space for precreate (%lld): rc = %d\n", ofd_name(ofd), diff, rc); diff = 0; } @@ -1726,7 +1734,7 @@ static int ofd_create_hdl(struct tgt_session_info *tsi) CDEBUG(D_HA, "%s: precreate FID "DOSTID" is over " "%u larger than the LAST_ID "DOSTID", only " - "precreating the last %u objects.\n", + "precreating the last %lld objects.\n", ofd_name(ofd), POSTID(&oa->o_oi), 5 * OST_MAX_PRECREATE, POSTID(&oseq->os_oi), diff); @@ -1735,7 +1743,7 @@ static int ofd_create_hdl(struct tgt_session_info *tsi) while (diff > 0) { next_id = ofd_seq_last_oid(oseq) + 1; - count = ofd_precreate_batch(ofd, diff); + count = ofd_precreate_batch(ofd, (int)diff); CDEBUG(D_HA, "%s: reserve %d objects in group %#llx" " at %llu\n", ofd_name(ofd), @@ -1743,7 +1751,7 @@ static int ofd_create_hdl(struct tgt_session_info *tsi) if (!(lustre_msg_get_flags(req->rq_reqmsg) & MSG_REPLAY) && cfs_time_after(jiffies, enough_time)) { - CDEBUG(D_HA, "%s: Slow creates, %d/%d objects" + CDEBUG(D_HA, "%s: Slow creates, %d/%lld objects" " created at a rate of %d/s\n", ofd_name(ofd), created, diff + created, created / DISK_TIMEOUT); @@ -1764,7 +1772,7 @@ static int ofd_create_hdl(struct tgt_session_info *tsi) lustre_msg_get_flags(req->rq_reqmsg) & MSG_REPLAY) LCONSOLE_WARN("%s: can't create the same count of" " objects when replaying the request" - " (diff is %d). see LU-4621\n", + " (diff is %lld). see LU-4621\n", ofd_name(ofd), diff); if (created > 0) diff --git a/lustre/ofd/ofd_obd.c b/lustre/ofd/ofd_obd.c index 03489fe..cc04521 100644 --- a/lustre/ofd/ofd_obd.c +++ b/lustre/ofd/ofd_obd.c @@ -1011,9 +1011,10 @@ static int ofd_echo_create(const struct lu_env *env, struct obd_export *exp, struct ofd_device *ofd = ofd_exp(exp); u64 seq = ostid_seq(&oa->o_oi); struct ofd_seq *oseq; - int rc = 0, diff = 1; long granted; u64 next_id; + s64 diff = 1; + int rc = 0; int count; ENTRY; @@ -1049,13 +1050,13 @@ static int ofd_echo_create(const struct lu_env *env, struct obd_export *exp, rc = granted; granted = 0; CDEBUG(D_HA, "%s: failed to acquire grant space for " - "precreate (%d): rc = %d\n", ofd_name(ofd), diff, rc); + "precreate (%lld): rc = %d\n", ofd_name(ofd), diff, rc); diff = 0; GOTO(out, rc); } next_id = ofd_seq_last_oid(oseq) + 1; - count = ofd_precreate_batch(ofd, diff); + count = ofd_precreate_batch(ofd, (int)diff); rc = ofd_precreate_objects(env, ofd, next_id, oseq, count, 0); if (rc < 0) { diff --git a/lustre/target/tgt_grant.c b/lustre/target/tgt_grant.c index 2dbb2c2..1caad7c 100644 --- a/lustre/target/tgt_grant.c +++ b/lustre/target/tgt_grant.c @@ -1271,7 +1271,7 @@ EXPORT_SYMBOL(tgt_grant_prepare_write); * \retval >= 0 amount of grant space allocated to the precreate request * \retval -ENOSPC on failure */ -long tgt_grant_create(const struct lu_env *env, struct obd_export *exp, int *nr) +long tgt_grant_create(const struct lu_env *env, struct obd_export *exp, s64 *nr) { struct lu_target *lut = exp->exp_obd->u.obt.obt_lut; struct tg_grants_data *tgd = &lut->lut_tgd; -- 1.8.3.1