Whamcloud - gitweb
Introduce .gitignore files.
[fs/lustre-release.git] / lustre / mdt / mdt_recovery.c
index 449241b..1709333 100644 (file)
@@ -179,9 +179,9 @@ static int mdt_last_rcvd_header_write(const struct lu_env *env,
         RETURN(rc);
 }
 
-static int mdt_last_rcvd_read(const struct lu_env *env,
-                              struct mdt_device *mdt,
-                              struct lsd_client_data *lcd, loff_t *off)
+static int mdt_last_rcvd_read(const struct lu_env *env, struct mdt_device *mdt,
+                              struct lsd_client_data *lcd, loff_t *off, 
+                              int index)
 {
         struct mdt_thread_info *mti;
         struct lsd_client_data *tmp;
@@ -191,8 +191,10 @@ static int mdt_last_rcvd_read(const struct lu_env *env,
         tmp = &mti->mti_lcd;
         rc = dt_record_read(env, mdt->mdt_last_rcvd,
                             mdt_buf(env, tmp, sizeof(*tmp)), off);
-        if (rc == 0)
+        if (rc == 0) {
+                check_lcd(mdt2obd_dev(mdt)->obd_name, index, tmp);
                 lcd_le_to_cpu(tmp, lcd);
+        }
 
         CDEBUG(D_INFO, "read lcd @%d rc = %d, uuid = %s, last_transno = "LPU64
                ", last_xid = "LPU64", last_result = %u, last_data = %u, "
@@ -264,7 +266,7 @@ static int mdt_clients_data_init(const struct lu_env *env,
                 off = lsd->lsd_client_start +
                         cl_idx * lsd->lsd_client_size;
 
-                rc = mdt_last_rcvd_read(env, mdt, lcd, &off);
+                rc = mdt_last_rcvd_read(env, mdt, lcd, &off, cl_idx);
                 if (rc) {
                         CERROR("error reading MDS %s idx %d, off %llu: rc %d\n",
                                LAST_RCVD, cl_idx, off, rc);
@@ -576,7 +578,7 @@ int mdt_client_new(const struct lu_env *env, struct mdt_device *mdt)
          * transaction so that many connecting clients will not bring
          * server down with lots of sync writes.
          */
-        mdt_trans_add_cb(th, lut_cb_client, mti->mti_exp);
+        mdt_trans_add_cb(th, lut_cb_client, class_export_cb_get(mti->mti_exp));
         spin_lock(&mti->mti_exp->exp_lock);
         mti->mti_exp->exp_need_sync = 1;
         spin_unlock(&mti->mti_exp->exp_lock);
@@ -690,8 +692,9 @@ int mdt_client_del(const struct lu_env *env, struct mdt_device *mdt)
                 LBUG();
         }
 
-        /* write server data at first so last_transno will be save in it in
-         * any case */
+        /* Make sure the server's last_transno is up to date.
+         * This should be done before zeroing client slot so last_transno will
+         * be in server data or in client data in case of failure */
         mdt_server_data_update(env, mdt);
 
         mdt_trans_credit_init(env, mdt, MDT_TXN_LAST_RCVD_WRITE_OP);
@@ -702,6 +705,7 @@ int mdt_client_del(const struct lu_env *env, struct mdt_device *mdt)
         mutex_down(&med->med_lcd_lock);
         memset(lcd, 0, sizeof *lcd);
         rc = mdt_last_rcvd_write(env, mdt, lcd, &off, th);
+        med->med_lcd = NULL;
         mutex_up(&med->med_lcd_lock);
         mdt_trans_stop(env, mdt, th);
 
@@ -711,10 +715,13 @@ int mdt_client_del(const struct lu_env *env, struct mdt_device *mdt)
 
         CDEBUG(rc == 0 ? D_INFO : D_ERROR, "Zeroing out client idx %u in "
                "%s, rc %d\n",  med->med_lr_idx, LAST_RCVD, rc);
-        EXIT;
-free:
         OBD_FREE_PTR(lcd);
+        RETURN(0);
+free:
+        mutex_down(&med->med_lcd_lock);
         med->med_lcd = NULL;
+        mutex_up(&med->med_lcd_lock);
+        OBD_FREE_PTR(lcd);
         return 0;
 }
 
@@ -738,19 +745,21 @@ static int mdt_last_rcvd_update(struct mdt_thread_info *mti,
         LASSERT(mdt);
         med = &req->rq_export->exp_mdt_data;
         LASSERT(med);
+
+        mutex_down(&med->med_lcd_lock);
         lcd = med->med_lcd;
-        /* if the export has already been failed, we have no last_rcvd slot */
-        if (req->rq_export->exp_failed) {
+        /* if the export has already been disconnected, we have no last_rcvd slot,
+         * update server data with latest transno then */
+        if (lcd == NULL) {
+                mutex_up(&med->med_lcd_lock);
                 CWARN("commit transaction for disconnected client %s: rc %d\n",
                       req->rq_export->exp_client_uuid.uuid, rc);
-                if (rc == 0)
-                        rc = -ENOTCONN;
-                RETURN(rc);
+                err = mdt_last_rcvd_header_write(mti->mti_env, mdt, th);
+                RETURN(err);
         }
 
         off = med->med_lr_off;
         LASSERT(ergo(mti->mti_transno == 0, rc != 0));
-        mutex_down(&med->med_lcd_lock);
         if (lustre_msg_get_opc(req->rq_reqmsg) == MDS_CLOSE ||
             lustre_msg_get_opc(req->rq_reqmsg) == MDS_DONE_WRITING) {
                 if (mti->mti_transno != 0)
@@ -866,8 +875,6 @@ static int mdt_txn_stop_cb(const struct lu_env *env,
 
         req->rq_transno = mti->mti_transno;
         lustre_msg_set_transno(req->rq_repmsg, mti->mti_transno);
-        lustre_msg_set_last_xid(req->rq_repmsg,
-                         lcd_last_xid(req->rq_export->exp_mdt_data.med_lcd));
         /* save transno for the commit callback */
         txi->txi_transno = mti->mti_transno;