Whamcloud - gitweb
LU-4529 quota: call qsd_op_end() after trasn stop 68/8968/3
authorNiu Yawei <yawei.niu@intel.com>
Thu, 23 Jan 2014 04:09:54 +0000 (23:09 -0500)
committerOleg Drokin <oleg.drokin@intel.com>
Sat, 22 Feb 2014 08:02:32 +0000 (08:02 +0000)
qsd_op_end() shouldn't be called before the transaction stopped,
because qsd_op_end() is a quite heavy operation which could
probably allocate memory with standard allocator flag (__GFP_IO),
and allocating memory could result in dirty flush on other
filesystems, that will lead to opening transaction on different
journal and trigger the assert in jbd2_journal_start():
J_ASSERT(handle->h_transaction->t_journal == journal) at the end.

Signed-off-by: Niu Yawei <yawei.niu@intel.com>
Change-Id: I4ea3ff011fa7e44460b9912050e90b174813e01a
Reviewed-on: http://review.whamcloud.com/8968
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Fan Yong <fan.yong@intel.com>
Reviewed-by: Johann Lombardi <johann.lombardi@intel.com>
lustre/osd-ldiskfs/osd_handler.c

index 3fd2e4c..3ffec10 100644 (file)
@@ -1102,19 +1102,17 @@ static int osd_seq_exists(const struct lu_env *env,
 static int osd_trans_stop(const struct lu_env *env, struct dt_device *dt,
                          struct thandle *th)
 {
 static int osd_trans_stop(const struct lu_env *env, struct dt_device *dt,
                          struct thandle *th)
 {
-        int                     rc = 0;
-        struct osd_thandle     *oh;
-        struct osd_thread_info *oti = osd_oti_get(env);
-        struct osd_iobuf       *iobuf = &oti->oti_iobuf;
+       int                     rc = 0;
+       struct osd_thandle     *oh;
+       struct osd_thread_info *oti = osd_oti_get(env);
+       struct osd_iobuf       *iobuf = &oti->oti_iobuf;
        struct qsd_instance    *qsd = oti->oti_dev->od_quota_slave;
        struct qsd_instance    *qsd = oti->oti_dev->od_quota_slave;
-        ENTRY;
+       struct lquota_trans    *qtrans;
+       ENTRY;
 
 
-        oh = container_of0(th, struct osd_thandle, ot_super);
+       oh = container_of0(th, struct osd_thandle, ot_super);
 
 
-       if (qsd != NULL)
-               /* inform the quota slave device that the transaction is
-                * stopping */
-               qsd_op_end(env, qsd, oh->ot_quota_trans);
+       qtrans = oh->ot_quota_trans;
        oh->ot_quota_trans = NULL;
 
         if (oh->ot_handle != NULL) {
        oh->ot_quota_trans = NULL;
 
         if (oh->ot_handle != NULL) {
@@ -1146,6 +1144,9 @@ static int osd_trans_stop(const struct lu_env *env, struct dt_device *dt,
                thandle_put(&oh->ot_super);
         }
 
                thandle_put(&oh->ot_super);
         }
 
+       /* inform the quota slave device that the transaction is stopping */
+       qsd_op_end(env, qsd, qtrans);
+
        /* as we want IO to journal and data IO be concurrent, we don't block
         * awaiting data IO completion in osd_do_bio(), instead we wait here
         * once transaction is submitted to the journal. all reqular requests
        /* as we want IO to journal and data IO be concurrent, we don't block
         * awaiting data IO completion in osd_do_bio(), instead we wait here
         * once transaction is submitted to the journal. all reqular requests