From 716ea58abaa87687dbf2d4cd1b524dd6b4aac45d Mon Sep 17 00:00:00 2001 From: Vitaly Fertman Date: Fri, 6 Aug 2010 12:26:39 +0400 Subject: [PATCH] b=23127 osc lock granted fix enqueue reply & completion ast race makes it possible to grant lock twice losing intermediate osc_unuse --- lustre/include/obd_support.h | 1 + lustre/ldlm/ldlm_lockd.c | 4 ++++ lustre/osc/osc_lock.c | 2 +- lustre/osc/osc_request.c | 3 +++ lustre/tests/sanityn.sh | 13 +++++++++++++ 5 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lustre/include/obd_support.h b/lustre/include/obd_support.h index 11c6122..5529026 100644 --- a/lustre/include/obd_support.h +++ b/lustre/include/obd_support.h @@ -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 diff --git a/lustre/ldlm/ldlm_lockd.c b/lustre/ldlm/ldlm_lockd.c index f59a29f..81075ee 100644 --- a/lustre/ldlm/ldlm_lockd.c +++ b/lustre/ldlm/ldlm_lockd.c @@ -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)", diff --git a/lustre/osc/osc_lock.c b/lustre/osc/osc_lock.c index e2ea260..254d02e 100644 --- a/lustre/osc/osc_lock.c +++ b/lustre/osc/osc_lock.c @@ -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; diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 0f2212b..2ba487b 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -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, diff --git a/lustre/tests/sanityn.sh b/lustre/tests/sanityn.sh index 2058aa8..dcb2fe9 100644 --- a/lustre/tests/sanityn.sh +++ b/lustre/tests/sanityn.sh @@ -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 -- 1.8.3.1