Whamcloud - gitweb
b=23127 osc lock granted fix
authorVitaly Fertman <Vitaly.Fertman@sun.com>
Fri, 6 Aug 2010 08:26:39 +0000 (12:26 +0400)
committerMikhail Pershin <tappro@sun.com>
Fri, 13 Aug 2010 06:05:53 +0000 (10:05 +0400)
enqueue reply & completion ast race makes it possible to grant lock
twice losing intermediate osc_unuse

lustre/include/obd_support.h
lustre/ldlm/ldlm_lockd.c
lustre/osc/osc_lock.c
lustre/osc/osc_request.c
lustre/tests/sanityn.sh

index 11c6122..5529026 100644 (file)
@@ -327,6 +327,7 @@ int obd_alloc_fail(const void *ptr, const char *name, const char *type,
 #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
 #define OBD_FAIL_OSC_OBJECT_CONTENTION   0x40e
 #define OBD_FAIL_OSC_CP_CANCEL_RACE      0x40f
+#define OBD_FAIL_OSC_CP_ENQ_RACE         0x410
 
 #define OBD_FAIL_PTLRPC                  0x500
 #define OBD_FAIL_PTLRPC_ACK              0x501
index f59a29f..81075ee 100644 (file)
@@ -1561,6 +1561,10 @@ static void ldlm_handle_cp_callback(struct ptlrpc_request *req,
 
         LDLM_DEBUG(lock, "callback handler finished, about to run_ast_work");
 
+        /* Let Enqueue to call osc_lock_upcall() and initialize
+         * l_ast_data */
+        OBD_FAIL_TIMEOUT(OBD_FAIL_OSC_CP_ENQ_RACE, 2);
+
         ldlm_run_ast_work(&ast_list, LDLM_WORK_CP_AST);
 
         LDLM_DEBUG_NOLOCK("client completion callback handler END (lock %p)",
index e2ea260..254d02e 100644 (file)
@@ -408,7 +408,7 @@ static void osc_lock_granted(const struct lu_env *env, struct osc_lock *olck,
         LASSERT(dlmlock->l_granted_mode == dlmlock->l_req_mode);
 
         ENTRY;
-        if (olck->ols_state != OLS_GRANTED) {
+        if (olck->ols_state < OLS_GRANTED) {
                 lock  = olck->ols_cl.cls_lock;
                 ext   = &dlmlock->l_policy_data.l_extent;
                 descr = &osc_env_info(env)->oti_descr;
index 0f2212b..2ba487b 100644 (file)
@@ -3227,6 +3227,9 @@ static int osc_enqueue_interpret(const struct lu_env *env,
          * osc_enqueue_fini(). */
         ldlm_lock_addref(&handle, mode);
 
+        /* Let CP AST to grant the lock first. */
+        OBD_FAIL_TIMEOUT(OBD_FAIL_OSC_CP_ENQ_RACE, 1);
+
         /* Complete obtaining the lock procedure. */
         rc = ldlm_cli_enqueue_fini(aa->oa_exp, req, aa->oa_ei->ei_type, 1,
                                    mode, aa->oa_flags, aa->oa_lvb,
index 2058aa8..dcb2fe9 100644 (file)
@@ -1849,6 +1849,19 @@ test_46h() {
 }
 run_test 46h "pdirops: link vs readdir =============="
 
+test_50() {
+        trunc_size=4096
+        dd if=/dev/zero of=$DIR1/$tfile bs=1K count=10
+#define OBD_FAIL_OSC_CP_ENQ_RACE         0x410
+        do_facet client "lctl set_param fail_loc=0x410"
+        $TRUNCATE $DIR2/$tfile $trunc_size
+        do_facet client "lctl set_param fail_loc=0x0"
+        sleep 3
+        size=`stat -c %s $DIR2/$tfile`
+        [ $size -eq $trunc_size ] || error "wrong size"
+}
+run_test 50 "osc lvb attrs: enqueue vs. CP AST =============="
+
 log "cleanup: ======================================================"
 
 [ "$(mount | grep $MOUNT2)" ] && umount $MOUNT2