From 777b8700ce548043e2cd9f9cf69627b42af8b3bb Mon Sep 17 00:00:00 2001 From: nathan Date: Fri, 2 Mar 2007 17:19:39 +0000 Subject: [PATCH] b=11149 r=adilger Add checks for null indicies in QOS code. Also fix 'lfs df' and /proc...lov/target_obd. --- lustre/ChangeLog | 8 +++++++- lustre/llite/llite_lib.c | 7 +++++-- lustre/lov/lov_obd.c | 3 ++- lustre/lov/lov_qos.c | 37 ++++++++++++++++++++++++------------- lustre/lov/lproc_lov.c | 8 ++++++-- lustre/utils/lfs.c | 6 ++++++ 6 files changed, 50 insertions(+), 19 deletions(-) diff --git a/lustre/ChangeLog b/lustre/ChangeLog index a6b8a3e..f011316 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -246,7 +246,13 @@ Description: The wrong (new) MDC name was used when setting parameters for upgraded MDT's. Also allows changing of OSC (and MDC) parameters if --writeconf is specified at tunefs upgrade time. - +Severity : major +Frequency : when setting specific ost indicies +Bugzilla : 11149 +Description: QOS code breaks on skipped indicies +Details : Add checks for missing OST indicies in the QOS code, so OSTs + created with --index need not be sequential. + ------------------------------------------------------------------------------ TBD Cluster File Systems, Inc. diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 5858ca9..b6ba695 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -1942,9 +1942,12 @@ int ll_obd_statfs(struct inode *inode, void *arg) lov_obd = class_exp2obd(sbi->ll_osc_exp); lov = &lov_obd->u.lov; - if ((index >= lov->desc.ld_tgt_count) || - !lov->lov_tgts[index]) + if (index >= lov->desc.ld_tgt_count) GOTO(out_statfs, rc = -ENODEV); + + if (!lov->lov_tgts[index]) + /* Try again with the next index */ + GOTO(out_statfs, rc = -EAGAIN); client_obd = class_exp2obd(lov->lov_tgts[index]->ltd_exp); if (!lov->lov_tgts[index]->ltd_active) diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index 6753cde..5b9112f 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -92,7 +92,7 @@ static int lov_connect_obd(struct obd_device *obd, __u32 index, int activate, struct obd_connect_data *data) { struct lov_obd *lov = &obd->u.lov; - struct obd_uuid tgt_uuid = lov->lov_tgts[index]->ltd_uuid; + struct obd_uuid tgt_uuid; struct obd_device *tgt_obd; struct obd_uuid lov_osc_uuid = { "LOV_OSC_UUID" }; struct lustre_handle conn = {0, }; @@ -106,6 +106,7 @@ static int lov_connect_obd(struct obd_device *obd, __u32 index, int activate, if (!lov->lov_tgts[index]) RETURN(-EINVAL); + tgt_uuid = lov->lov_tgts[index]->ltd_uuid; tgt_obd = class_find_client_obd(&tgt_uuid, LUSTRE_OSC_NAME, &obd->obd_uuid); diff --git a/lustre/lov/lov_qos.c b/lustre/lov/lov_qos.c index 8dc03e6..8bcc7e2 100644 --- a/lustre/lov/lov_qos.c +++ b/lustre/lov/lov_qos.c @@ -116,6 +116,9 @@ int qos_del_tgt(struct obd_device *obd, __u32 index) int rc = 0; ENTRY; + if (!lov->lov_tgts[index]) + RETURN(0); + down_write(&lov->lov_qos.lq_rw_sem); oss = lov->lov_tgts[index]->ltd_qos.ltq_oss; @@ -200,7 +203,8 @@ static int qos_calc_ppo(struct obd_device *obd) we have to double the OST penalty */ num_active = 1; for (i = 0; i < lov->desc.ld_tgt_count; i++) - lov->lov_tgts[i]->ltd_qos.ltq_penalty_per_obj <<= 1; + if (lov->lov_tgts[i]) + lov->lov_tgts[i]->ltd_qos.ltq_penalty_per_obj <<= 1; } /* Per-OSS penalty is prio * oss_avail / oss_osts / (num_oss - 1) / 2 */ @@ -320,7 +324,7 @@ static int qos_used(struct lov_obd *lov, __u32 index, __u64 *total_wt) static int qos_calc_rr(struct lov_obd *lov) { struct lov_qos_oss *oss; - unsigned ost_count, placed; + unsigned ost_count, placed, real_count; int i; ENTRY; @@ -343,15 +347,20 @@ static int qos_calc_rr(struct lov_obd *lov) RETURN(-ENOMEM); } - for (i = 0; i < ost_count; i++) + real_count = 0; + for (i = 0; i < ost_count; i++) { lov->lov_qos.lq_rr_array[i] = LOV_QOS_EMPTY; + if (lov->lov_tgts[i]) + real_count++; + } /* Place all the OSTs from 1 OSS at the same time. */ placed = 0; list_for_each_entry(oss, &lov->lov_qos.lq_oss_list, lqo_oss_list) { int j = 0; for (i = 0; i < ost_count; i++) { - if (lov->lov_tgts[i]->ltd_qos.ltq_oss == oss) { + if (lov->lov_tgts[i] && + (lov->lov_tgts[i]->ltd_qos.ltq_oss == oss)) { /* Evenly space these OSTs across arrayspace */ int next = j * ost_count / oss->lqo_ost_count; while (lov->lov_qos.lq_rr_array[next] != @@ -368,10 +377,10 @@ static int qos_calc_rr(struct lov_obd *lov) lov->lov_qos.lq_dirty_rr = 0; up_write(&lov->lov_qos.lq_rw_sem); - if (placed != ost_count) { + if (placed != real_count) { /* This should never happen */ LCONSOLE_ERROR("Failed to place all OSTs in the round-robin " - "list (%d of %d).\n", placed, ost_count); + "list (%d of %d).\n", placed, real_count); for (i = 0; i < ost_count; i++) { LCONSOLE(D_WARNING, "rr #%d ost idx=%d\n", i, lov->lov_qos.lq_rr_array[i]); @@ -379,10 +388,10 @@ static int qos_calc_rr(struct lov_obd *lov) lov->lov_qos.lq_dirty_rr = 1; RETURN(-EAGAIN); } - + #ifdef QOS_DEBUG for (i = 0; i < ost_count; i++) { - LCONSOLE(D_QOS, "rr #%d ost idx=%d\n", i, + LCONSOLE(D_QOS, "rr #%d ost idx=%d\n", i, lov->lov_qos.lq_rr_array[i]); } #endif @@ -513,11 +522,11 @@ static int alloc_rr(struct lov_obd *lov, int *idx_arr, int *stripe_cnt) #ifdef QOS_DEBUG CDEBUG(D_QOS, "#%d strt %d act %d strp %d ary %d idx %d\n", i, lov->lov_start_idx, - lov->lov_tgts[ost_idx] ? + ((ost_idx != LOV_QOS_EMPTY) && lov->lov_tgts[ost_idx]) ? lov->lov_tgts[ost_idx]->ltd_active : 0, idx_pos - idx_arr, array_idx, ost_idx); #endif - if (!lov->lov_tgts[ost_idx] || + if ((ost_idx == LOV_QOS_EMPTY) || !lov->lov_tgts[ost_idx] || !lov->lov_tgts[ost_idx]->ltd_active) continue; *idx_pos = ost_idx; @@ -672,7 +681,8 @@ static int alloc_qos(struct obd_export *exp, int *idx_arr, int *stripe_cnt) /* On average, this will hit larger-weighted osts more often. 0-weight osts will always get used last (only when rand=0).*/ for (i = 0; i < ost_count; i++) { - if (!lov->lov_tgts[i]->ltd_qos.ltq_usable) + if (!lov->lov_tgts[i] || + !lov->lov_tgts[i]->ltd_qos.ltq_usable) continue; cur_weight += lov->lov_tgts[i]->ltd_qos.ltq_weight; if (cur_weight >= rand) { @@ -722,7 +732,7 @@ static int alloc_idx_array(struct obd_export *exp, struct lov_stripe_md *lsm, tmp_arr[i] = -1; if (newea || - lsm->lsm_oinfo[0]->loi_ost_idx >= lov->desc.ld_tgt_count) + lsm->lsm_oinfo[0]->loi_ost_idx >= lov->desc.ld_tgt_count) rc = alloc_qos(exp, tmp_arr, &stripe_cnt); else rc = alloc_specific(lov, lsm, tmp_arr); @@ -806,9 +816,10 @@ int qos_prep_create(struct obd_export *exp, struct lov_request_set *set) } stripes = alloc_idx_array(exp, lsm, newea, &idx_arr, &idx_cnt); - LASSERT(stripes <= lsm->lsm_stripe_count); if (stripes <= 0) GOTO(out_err, rc = stripes ? stripes : -EIO); + LASSERTF(stripes <= lsm->lsm_stripe_count,"requested %d allocated %d\n", + lsm->lsm_stripe_count, stripes); for (i = 0; i < stripes; i++) { struct lov_request *req; diff --git a/lustre/lov/lproc_lov.c b/lustre/lov/lproc_lov.c index 3cdab73..ed79fc4 100644 --- a/lustre/lov/lproc_lov.c +++ b/lustre/lov/lproc_lov.c @@ -277,8 +277,12 @@ static void *lov_tgt_seq_next(struct seq_file *p, void *v, loff_t *pos) struct obd_device *dev = p->private; struct lov_obd *lov = &dev->u.lov; - ++*pos; - return (*pos >= lov->desc.ld_tgt_count) ? NULL : lov->lov_tgts[*pos]; + while (*pos < lov->desc.ld_tgt_count) { + ++*pos; + if (lov->lov_tgts[*pos]) + return lov->lov_tgts[*pos]; + } + return NULL; } static int lov_tgt_seq_show(struct seq_file *p, void *v) diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 32bd1e5..1e90437 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -671,6 +671,9 @@ static int mntdf(char *mntdir, int ishow, int cooked) if (rc == -ENODEV) break; + if (rc == -EAGAIN) + continue; + if (rc == -ENOTCONN || rc == -ETIMEDOUT || rc == -EIO || rc == -ENODATA || rc == 0) { showdf(mntdir, &stat_buf, uuid_buf.uuid, ishow, cooked, @@ -695,6 +698,9 @@ static int mntdf(char *mntdir, int ishow, int cooked) if (rc == -ENODEV) break; + if (rc == -EAGAIN) + continue; + if (rc == -ENOTCONN || rc == -ETIMEDOUT || rc == -EIO || rc == -ENODATA || rc == 0) { showdf(mntdir, &stat_buf, uuid_buf.uuid, ishow, cooked, -- 1.8.3.1