Whamcloud - gitweb
LU-7593 target: take ted_lcd_lock after transaction started 29/23129/3
authorFan Yong <fan.yong@intel.com>
Wed, 27 Jul 2016 14:55:00 +0000 (22:55 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 25 Oct 2016 02:24:21 +0000 (02:24 +0000)
Otherwise the thread1 may be blocked during the transaction start
in tgt_client_data_update() with 'ted_lcd_lock' held because another
thread2 may be blocked by such lock in tgt_txn_stop_cb() but with
transaction handle started. That is deadlock.

Signed-off-by: Fan Yong <fan.yong@intel.com>
Change-Id: Id623d171e43beaa54ae4a9718fb4dc52c474df01
Reviewed-on: http://review.whamcloud.com/23129
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Tested-by: Jenkins
Reviewed-by: Mike Pershin <mike.pershin@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/target/tgt_lastrcvd.c

index ac6841a..c3811cd 100644 (file)
@@ -513,7 +513,6 @@ static int tgt_client_data_update(const struct lu_env *env,
                RETURN(PTR_ERR(th));
 
        tti_buf_lcd(tti);
-       mutex_lock(&ted->ted_lcd_lock);
        rc = dt_declare_record_write(env, tgt->lut_last_rcvd,
                                     &tti->tti_buf,
                                     ted->ted_lr_off, th);
@@ -523,6 +522,9 @@ static int tgt_client_data_update(const struct lu_env *env,
        rc = dt_trans_start_local(env, tgt->lut_bottom, th);
        if (rc)
                GOTO(out, rc);
+
+       mutex_lock(&ted->ted_lcd_lock);
+
        /*
         * Until this operations will be committed the sync is needed
         * for this export. This should be done _after_ starting the
@@ -541,9 +543,11 @@ static int tgt_client_data_update(const struct lu_env *env,
 
        tti->tti_off = ted->ted_lr_off;
        rc = tgt_client_data_write(env, tgt, ted->ted_lcd, &tti->tti_off, th);
+
+       mutex_unlock(&ted->ted_lcd_lock);
+
        EXIT;
 out:
-       mutex_unlock(&ted->ted_lcd_lock);
        dt_trans_stop(env, tgt->lut_bottom, th);
        CDEBUG(D_INFO, "%s: update last_rcvd client data for UUID = %s, "
               "last_transno = %llu: rc = %d\n", tgt->lut_obd->obd_name,