Whamcloud - gitweb
b=11149
authornathan <nathan>
Fri, 2 Mar 2007 17:19:39 +0000 (17:19 +0000)
committernathan <nathan>
Fri, 2 Mar 2007 17:19:39 +0000 (17:19 +0000)
r=adilger
Add checks for null indicies in QOS code.
Also fix 'lfs df' and /proc...lov/target_obd.

lustre/ChangeLog
lustre/llite/llite_lib.c
lustre/lov/lov_obd.c
lustre/lov/lov_qos.c
lustre/lov/lproc_lov.c
lustre/utils/lfs.c

index a6b8a3e..f011316 100644 (file)
@@ -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. <info@clusterfs.com>
index 5858ca9..b6ba695 100644 (file)
@@ -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)
index 6753cde..5b9112f 100644 (file)
@@ -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);
 
index 8dc03e6..8bcc7e2 100644 (file)
@@ -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;
index 3cdab73..ed79fc4 100644 (file)
@@ -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)
index 32bd1e5..1e90437 100644 (file)
@@ -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,