From: zam Date: Wed, 27 May 2009 09:58:54 +0000 (+0000) Subject: Branch b_release_1_6_7 X-Git-Tag: v1_6_7_2~3 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=5e411e93c75d1af94004e1b3e11ddc6f842c0205;p=fs%2Flustre-release.git Branch b_release_1_6_7 b=19039 i=vitaly.fertman i=oleg.drokin ldlm_lock_enqueue: don't enqueue a destroyed lock. --- diff --git a/lustre/include/obd_support.h b/lustre/include/obd_support.h index e446d23..2e36ec3 100644 --- a/lustre/include/obd_support.h +++ b/lustre/include/obd_support.h @@ -234,6 +234,7 @@ extern unsigned int obd_alloc_fail_rate; #define OBD_FAIL_LDLM_OST_FAIL_RACE 0x316 #define OBD_FAIL_LDLM_INTR_CP_AST 0x317 #define OBD_FAIL_LDLM_CP_BL_RACE 0x318 +#define OBD_FAIL_LDLM_ENQUEUE_LOCAL 0x319 #define OBD_FAIL_OSC 0x400 #define OBD_FAIL_OSC_BRW_READ_BULK 0x401 diff --git a/lustre/ldlm/ldlm_extent.c b/lustre/ldlm/ldlm_extent.c index 22c42c1..d4a94a3 100644 --- a/lustre/ldlm/ldlm_extent.c +++ b/lustre/ldlm/ldlm_extent.c @@ -859,6 +859,7 @@ void ldlm_extent_add_lock(struct ldlm_resource *res, int idx; LASSERT(lock->l_granted_mode == lock->l_req_mode); + LASSERT(!lock->l_destroyed); node = lock->l_tree_node; LASSERT(node != NULL); diff --git a/lustre/ldlm/ldlm_lock.c b/lustre/ldlm/ldlm_lock.c index f37f834..f2d1045 100644 --- a/lustre/ldlm/ldlm_lock.c +++ b/lustre/ldlm/ldlm_lock.c @@ -1208,8 +1208,13 @@ ldlm_error_t ldlm_lock_enqueue(struct ldlm_namespace *ns, if (!local && (*flags & LDLM_FL_REPLAY) && res->lr_type == LDLM_EXTENT) OBD_SLAB_ALLOC(node, ldlm_interval_slab, CFS_ALLOC_IO, sizeof(*node)); + if(res->lr_type == LDLM_EXTENT) + OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_ENQUEUE_LOCAL, 30); lock_res_and_lock(lock); + if (lock->l_destroyed) + GOTO(out, rc = -EAGAIN); + if (local && lock->l_req_mode == lock->l_granted_mode) { /* The server returned a blocked lock, but it was granted * before we got a chance to actually enqueue it. We don't @@ -1649,6 +1654,10 @@ struct ldlm_resource *ldlm_lock_convert(struct ldlm_lock *lock, int new_mode, "new_mode %u, granted %u\n", new_mode, lock->l_granted_mode); lock_res_and_lock(lock); + if (unlikely(lock->l_destroyed != 0)) { + unlock_res_and_lock(lock); + RETURN(NULL); + } res = lock->l_resource; ns = res->lr_namespace; diff --git a/lustre/tests/recovery-small.sh b/lustre/tests/recovery-small.sh index 715990c..552c8c9 100755 --- a/lustre/tests/recovery-small.sh +++ b/lustre/tests/recovery-small.sh @@ -403,6 +403,29 @@ test_20b() { # bug 2986 - ldlm_handle_enqueue error during open } run_test 20b "ldlm_handle_enqueue error (should return error)" +test_20c() { + # bug 19039 -- a race between ldlm_enqueue and lock + # destroying when the client export is disconnected + + local ddpid + + mkdir -p $DIR/$tdir + rm -f $DIR/$tdir/$tfile + # OBD_FAIL_LDLM_ENQUEUE_LOCAL 0x319 + do_facet ost1 lctl set_param fail_loc=0x80000319 + lfs setstripe -c 1 -o 0 $DIR/$tdir/$tfile + dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M conv=notrunc count=1 & + ddpid=$! + sleep 3 + kill $ddpid + stop ost1 + sleep 30 + start ost1 $(ostdevname 1) $OST_MOUNT_OPTS + rm -rf $DIR/$tdir + return 0 +} +run_test 20c "ldlm_lock_enqueue is called for a destroyed lock (shouldn't LBUG)" + test_21a() { mkdir -p $DIR/$tdir-1 mkdir -p $DIR/$tdir-2