Whamcloud - gitweb
LU-4019 ofd: setattr don't udpate lvbo with object referenced 95/7795/2
authorAlex Zhuravlev <alexey.zhuravlev@intel.com>
Sat, 28 Sep 2013 13:58:45 +0000 (17:58 +0400)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 1 Oct 2013 17:19:23 +0000 (17:19 +0000)
we shouldn't allow recursive lu_object_find() while object
can be destroyed. so release the reference to the object
before calling to ldlm_res_lvbo_update() which lookups the
object on its own.

Signed-off-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Change-Id: If34d89834e352b6d0b8129a6fb4377317833a78a
Reviewed-on: http://review.whamcloud.com/7795
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Mike Pershin <mike.pershin@intel.com>
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/ofd/ofd_obd.c

index c0a6fcd..8bcbd06 100644 (file)
@@ -887,12 +887,6 @@ int ofd_setattr(const struct lu_env *env, struct obd_export *exp,
        if (rc)
                GOTO(out_unlock, rc);
 
        if (rc)
                GOTO(out_unlock, rc);
 
-       res = ldlm_resource_get(ns, NULL, &info->fti_resid, LDLM_EXTENT, 0);
-       if (res != NULL) {
-               ldlm_res_lvbo_update(res, NULL, 0);
-               ldlm_resource_putref(res);
-       }
-
        ofd_info2oti(info, oti);
 
        ofd_counter_incr(exp, LPROC_OFD_STATS_SETATTR, oti->oti_jobid, 1);
        ofd_info2oti(info, oti);
 
        ofd_counter_incr(exp, LPROC_OFD_STATS_SETATTR, oti->oti_jobid, 1);
@@ -900,6 +894,19 @@ int ofd_setattr(const struct lu_env *env, struct obd_export *exp,
 out_unlock:
        ofd_object_put(env, fo);
 out:
 out_unlock:
        ofd_object_put(env, fo);
 out:
+       if (rc == 0) {
+               /* we do not call this before to avoid lu_object_find() in
+                *  ->lvbo_update() holding another reference on the object.
+                * otherwise concurrent destroy can make the object unavailable
+                * for 2nd lu_object_find() waiting for the first reference
+                * to go... deadlock! */
+               res = ldlm_resource_get(ns, NULL, &info->fti_resid, LDLM_EXTENT, 0);
+               if (res != NULL) {
+                       ldlm_res_lvbo_update(res, NULL, 0);
+                       ldlm_resource_putref(res);
+               }
+       }
+
        return rc;
 }
 
        return rc;
 }