Whamcloud - gitweb
LU-6386 tgt: don't update client data with smaller transno 13/14113/6
authorMikhail Pershin <mike.pershin@intel.com>
Thu, 1 Oct 2015 18:34:27 +0000 (21:34 +0300)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 14 Oct 2015 04:36:37 +0000 (04:36 +0000)
Fix tgt_last_rcvd_update() to don't update transaction number
in client slot with smaller value.

Also patch removes outdated code about ted_lcd == NULL case.
This is not possible now, because lcd is set to NULL only
upon export destroy. This check was needed in past when that
lcd was set to NULL during export disconnect and some activity
was still possible on this export.

Signed-off-by: Mikhail Pershin <mike.pershin@intel.com>
Change-Id: I34717ea91493785beadcf725d49c4c9265b63f7c
Reviewed-on: http://review.whamcloud.com/14113
Tested-by: Jenkins
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: wangdi <di.wang@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/target/tgt_lastrcvd.c

index a152f05..878246e 100644 (file)
@@ -1131,7 +1131,7 @@ static int tgt_last_rcvd_update(const struct lu_env *env, struct lu_target *tgt,
        struct tg_export_data   *ted;
        __u64                   *transno_p;
        int                      rc = 0;
-       bool                     lw_client, update = false;
+       bool                     lw_client;
 
        ENTRY;
 
@@ -1190,27 +1190,21 @@ static int tgt_last_rcvd_update(const struct lu_env *env, struct lu_target *tgt,
                spin_lock(&tgt->lut_translock);
                if (tti->tti_transno > tgt->lut_lsd.lsd_last_transno) {
                        tgt->lut_lsd.lsd_last_transno = tti->tti_transno;
-                       update = true;
+                       spin_unlock(&tgt->lut_translock);
+                       /* Although lightweight (LW) connections have no slot
+                        * in the last_rcvd, we still want to maintain
+                        * the in-memory lsd_client_data structure in order to
+                        * properly handle reply reconstruction. */
+                       rc = tgt_server_data_write(env, tgt, th);
+               } else {
+                       spin_unlock(&tgt->lut_translock);
                }
-               spin_unlock(&tgt->lut_translock);
-               /* Although lightweight (LW) connections have no slot in
-                * last_rcvd, we still want to maintain the in-memory
-                * lsd_client_data structure in order to properly handle reply
-                * reconstruction. */
        } else if (ted->ted_lr_off == 0) {
                CERROR("%s: client idx %d has offset %lld\n",
                       tgt_name(tgt), ted->ted_lr_idx, ted->ted_lr_off);
                RETURN(-EINVAL);
        }
 
-       /* if the export has already been disconnected, we have no last_rcvd
-        * slot, update server data with latest transno then */
-       if (ted->ted_lcd == NULL) {
-               CWARN("commit transaction for disconnected client %s: rc %d\n",
-                     exp->exp_client_uuid.uuid, rc);
-               GOTO(srv_update, rc = 0);
-       }
-
        /* Target that supports multiple reply data */
        if (tgt_is_multimodrpcs_client(exp)) {
                struct tg_reply_data    *trd;
@@ -1220,7 +1214,7 @@ static int tgt_last_rcvd_update(const struct lu_env *env, struct lu_target *tgt,
 
                OBD_ALLOC_PTR(trd);
                if (unlikely(trd == NULL))
-                       GOTO(srv_update, rc = -ENOMEM);
+                       RETURN(-ENOMEM);
 
                /* fill reply data information */
                lrd = &trd->trd_reply;
@@ -1251,12 +1245,14 @@ static int tgt_last_rcvd_update(const struct lu_env *env, struct lu_target *tgt,
                }
 
                rc = tgt_add_reply_data(env, tgt, ted, trd, th, write_update);
-               GOTO(srv_update, rc);
+               if (rc < 0)
+                       OBD_FREE_PTR(trd);
+               return rc;
        }
 
        /* Enough for update replay, let's return */
        if (req == NULL)
-               GOTO(srv_update, rc);
+               RETURN(rc);
 
        mutex_lock(&ted->ted_lcd_lock);
        LASSERT(ergo(tti->tti_transno == 0, th->th_result != 0));
@@ -1284,21 +1280,27 @@ static int tgt_last_rcvd_update(const struct lu_env *env, struct lu_target *tgt,
 
        /* Update transno in slot only if non-zero number, i.e. no errors */
        if (likely(tti->tti_transno != 0)) {
-               if (*transno_p > tti->tti_transno &&
-                   !tgt->lut_no_reconstruct) {
-                       CERROR("%s: trying to overwrite bigger transno:"
-                              "on-disk: "LPU64", new: "LPU64" replay: %d. "
-                              "see LU-617.\n", tgt_name(tgt), *transno_p,
-                              tti->tti_transno, req_is_replay(req));
-                       if (req_is_replay(req)) {
-                               spin_lock(&req->rq_export->exp_lock);
-                               req->rq_export->exp_vbr_failed = 1;
-                               spin_unlock(&req->rq_export->exp_lock);
+               /* Don't overwrite bigger transaction number with lower one.
+                * That is not sign of problem in all cases, but in any case
+                * this value should be monotonically increased only. */
+               if (*transno_p > tti->tti_transno) {
+                       if (!tgt->lut_no_reconstruct) {
+                               CERROR("%s: trying to overwrite bigger transno:"
+                                      "on-disk: "LPU64", new: "LPU64" replay: "
+                                      "%d. See LU-617.\n", tgt_name(tgt),
+                                      *transno_p, tti->tti_transno,
+                                      req_is_replay(req));
+                               if (req_is_replay(req)) {
+                                       spin_lock(&req->rq_export->exp_lock);
+                                       req->rq_export->exp_vbr_failed = 1;
+                                       spin_unlock(&req->rq_export->exp_lock);
+                               }
+                               mutex_unlock(&ted->ted_lcd_lock);
+                               RETURN(req_is_replay(req) ? -EOVERFLOW : 0);
                        }
-                       mutex_unlock(&ted->ted_lcd_lock);
-                       RETURN(req_is_replay(req) ? -EOVERFLOW : 0);
+               } else {
+                       *transno_p = tti->tti_transno;
                }
-               *transno_p = tti->tti_transno;
        }
 
        if (!lw_client) {
@@ -1310,11 +1312,7 @@ static int tgt_last_rcvd_update(const struct lu_env *env, struct lu_target *tgt,
                }
        }
        mutex_unlock(&ted->ted_lcd_lock);
-       EXIT;
-srv_update:
-       if (update)
-               rc = tgt_server_data_write(env, tgt, th);
-       return rc;
+       RETURN(rc);
 }
 
 /*