X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fldlm%2Fldlm_extent.c;h=03172d693b76dcc3096b29fe66356fd2ce03c491;hb=15385c3b934b511a1452327c701fbb6adad71416;hp=3b6543e1b842fc29ece5a9643ca83462694a0403;hpb=61b90c37deb75e918f044dc2c129d7c858b005a5;p=fs%2Flustre-release.git diff --git a/lustre/ldlm/ldlm_extent.c b/lustre/ldlm/ldlm_extent.c index 3b6543e..03172d6 100644 --- a/lustre/ldlm/ldlm_extent.c +++ b/lustre/ldlm/ldlm_extent.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include "ldlm_internal.h" @@ -64,7 +65,7 @@ static void ldlm_extent_internal_policy_fixup(struct ldlm_lock *req, __u64 req_start = req->l_req_extent.start; __u64 req_end = req->l_req_extent.end; __u64 req_align, mask; - + if (conflicting > 32 && (req_mode == LCK_PW || req_mode == LCK_CW)) { if (req_end < req_start + LDLM_MAX_GROWN_EXTENT) new_ex->end = min(req_start + LDLM_MAX_GROWN_EXTENT, @@ -623,9 +624,9 @@ static void discard_bl_list(struct list_head *bl_list) lock->l_flags &= ~LDLM_FL_AST_SENT; LASSERT(lock->l_bl_ast_run == 0); LASSERT(lock->l_blocking_lock); - LDLM_LOCK_PUT(lock->l_blocking_lock); + LDLM_LOCK_RELEASE(lock->l_blocking_lock); lock->l_blocking_lock = NULL; - LDLM_LOCK_PUT(lock); + LDLM_LOCK_RELEASE(lock); } EXIT; } @@ -707,16 +708,31 @@ int ldlm_process_extent_lock(struct ldlm_lock *lock, int *flags, int first_enq, ldlm_resource_add_lock(res, &res->lr_waiting, lock); unlock_res(res); rc = ldlm_run_ast_work(&rpc_list, LDLM_WORK_BL_AST); - lock_res(res); + if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_OST_FAIL_RACE) && + !ns_is_client(res->lr_namespace)) + class_fail_export(lock->l_export); + + lock_res(res); if (rc == -ERESTART) { + + /* 15715: The lock was granted and destroyed after + * resource lock was dropped. Interval node was freed + * in ldlm_lock_destroy. Anyway, this always happens + * when a client is being evicted. So it would be + * ok to return an error. -jay */ + if (lock->l_destroyed) { + *err = -EAGAIN; + GOTO(out, rc = -EAGAIN); + } + /* lock was granted while resource was unlocked. */ if (lock->l_granted_mode == lock->l_req_mode) { /* bug 11300: if the lock has been granted, * break earlier because otherwise, we will go * to restart and ldlm_resource_unlink will be * called and it causes the interval node to be - * freed. Then we will fail at + * freed. Then we will fail at * ldlm_extent_add_lock() */ *flags &= ~(LDLM_FL_BLOCK_GRANTED | LDLM_FL_BLOCK_CONV | LDLM_FL_BLOCK_WAIT); @@ -785,7 +801,7 @@ struct ldlm_interval *ldlm_interval_alloc(struct ldlm_lock *lock) ENTRY; LASSERT(lock->l_resource->lr_type == LDLM_EXTENT); - OBD_SLAB_ALLOC(node, ldlm_interval_slab, CFS_ALLOC_IO, sizeof(*node)); + OBD_SLAB_ALLOC_PTR_GFP(node, ldlm_interval_slab, CFS_ALLOC_IO); if (node == NULL) RETURN(NULL); @@ -798,6 +814,7 @@ void ldlm_interval_free(struct ldlm_interval *node) { if (node) { LASSERT(list_empty(&node->li_group)); + LASSERT(!interval_is_intree(&node->li_node)); OBD_SLAB_FREE(node, ldlm_interval_slab, sizeof(*node)); } } @@ -850,6 +867,7 @@ void ldlm_extent_add_lock(struct ldlm_resource *res, node = lock->l_tree_node; LASSERT(node != NULL); + LASSERT(!interval_is_intree(&node->li_node)); idx = lock_mode_to_index(lock->l_granted_mode); LASSERT(lock->l_granted_mode == 1 << idx); @@ -877,14 +895,13 @@ void ldlm_extent_add_lock(struct ldlm_resource *res, void ldlm_extent_unlink_lock(struct ldlm_lock *lock) { struct ldlm_resource *res = lock->l_resource; - struct ldlm_interval *node; + struct ldlm_interval *node = lock->l_tree_node; struct ldlm_interval_tree *tree; int idx; - if (lock->l_granted_mode != lock->l_req_mode) + if (!node || !interval_is_intree(&node->li_node)) /* duplicate unlink */ return; - LASSERT(lock->l_tree_node != NULL); idx = lock_mode_to_index(lock->l_granted_mode); LASSERT(lock->l_granted_mode == 1 << idx); tree = &res->lr_itree[idx];