Whamcloud - gitweb
b=23210 don't update obd->obd_osfs if target is gone already
authorJohann Lombardi <johann@sun.com>
Wed, 30 Jun 2010 08:53:33 +0000 (10:53 +0200)
committerJohann Lombardi <johann@sun.com>
Wed, 30 Jun 2010 08:53:33 +0000 (10:53 +0200)
i=wangdi
i=landen

lov_disconnect() can clean up lov->lov_tgts while the statfs interpret
routine of an rpc in flight has not been executed yet.

lustre/lov/lov_request.c

index 0d98af3..9701e0c 100644 (file)
@@ -1601,14 +1601,12 @@ static int cb_statfs_update(struct obd_info *oinfo, int rc)
 {
         struct lov_request *lovreq;
         struct obd_statfs *osfs, *lov_sfs;
-        struct obd_device *obd;
         struct lov_obd *lov;
         int success;
         ENTRY;
 
         lovreq = container_of(oinfo, struct lov_request, rq_oi);
         lov = &lovreq->rq_rqset->set_obd->u.lov;
-        obd = class_exp2obd(lov->lov_tgts[lovreq->rq_idx]->ltd_exp);
 
         osfs = lovreq->rq_rqset->set_oi->oi_osfs;
         lov_sfs = oinfo->oi_osfs;
@@ -1625,11 +1623,20 @@ static int cb_statfs_update(struct obd_info *oinfo, int rc)
                 GOTO(out, rc);
         }
 
-        spin_lock(&obd->obd_osfs_lock);
-        memcpy(&obd->obd_osfs, lov_sfs, sizeof(*lov_sfs));
-        if ((oinfo->oi_flags & OBD_STATFS_FROM_CACHE) == 0)
-                obd->obd_osfs_age = cfs_time_current_64();
-        spin_unlock(&obd->obd_osfs_lock);
+        obd_getref(lovreq->rq_rqset->set_obd);
+        if (lov->lov_tgts[lovreq->rq_idx] &&
+            lov->lov_tgts[lovreq->rq_idx]->ltd_exp) {
+                /* lov_disconnect() might have already removed the target */
+                struct obd_device *obd;
+
+                obd = class_exp2obd(lov->lov_tgts[lovreq->rq_idx]->ltd_exp);
+                spin_lock(&obd->obd_osfs_lock);
+                memcpy(&obd->obd_osfs, lov_sfs, sizeof(*lov_sfs));
+                if ((oinfo->oi_flags & OBD_STATFS_FROM_CACHE) == 0)
+                        obd->obd_osfs_age = cfs_time_current_64();
+                spin_unlock(&obd->obd_osfs_lock);
+        }
+        obd_putref(lovreq->rq_rqset->set_obd);
 
         lov_update_statfs(osfs, lov_sfs, success);
         qos_update(lov);