Whamcloud - gitweb
LU-1129 obdfilter: handle race condition of recreating objects
authorYu Jian <yujian@whamcloud.com>
Fri, 13 Jul 2012 09:45:53 +0000 (17:45 +0800)
committerOleg Drokin <green@whamcloud.com>
Thu, 19 Jul 2012 04:08:07 +0000 (00:08 -0400)
During OST recovery, a race can happen while handling replayed
OST_WRITE request during the MDS->OST orphan recovery period to
recreate missing objects, which can trigger ASSERTION(diff >= 0)
failure.

This patch handles the above issue by adding obd->obd_recovering
into the assertion to check whether the OST is in recovery or not.
If it's in recovery and diff < 0, then no assertion failure occurs,
the object has been recreated. If the OST is not in recovery and
diff < 0, then the assertion failure occurs.

Signed-off-by: Yu Jian <yujian@whamcloud.com>
Change-Id: If486bc8221cf4b9d53b6de53e8ec14a4f3174b45
Reviewed-on: http://review.whamcloud.com/3391
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Mike Pershin <tappro@whamcloud.com>
Reviewed-by: Jinshan Xiong <jinshan.xiong@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/obdfilter/filter.c

index 422db94..eb74491 100644 (file)
@@ -3785,8 +3785,15 @@ static int filter_handle_precreate(struct obd_export *exp, struct obdo *oa,
                 CDEBUG(D_RPCTRACE, "filter_last_id() = "LPU64" -> diff = %d\n",
                        filter_last_id(filter, group), diff);
 
-                LASSERTF(diff >= 0,"%s: "LPU64" - "LPU64" = %d\n",obd->obd_name,
-                         oa->o_id, filter_last_id(filter, group), diff);
+               /*
+                * Check obd->obd_recovering to handle the race condition
+                * while recreating missing precreated objects through
+                * filter_preprw_write() and mds_lov_clear_orphans()
+                * at the same time.
+                */
+               LASSERTF(ergo(!obd->obd_recovering, diff >= 0),
+                        "%s: "LPU64" - "LPU64" = %d\n", obd->obd_name,
+                        oa->o_id, filter_last_id(filter, group), diff);
         }
 
         if (diff > 0) {