X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fldlm%2Fldlm_extent.c;h=03172d693b76dcc3096b29fe66356fd2ce03c491;hb=15385c3b934b511a1452327c701fbb6adad71416;hp=5825ca0842dcf82e72ef2feef48e4e315ca28817;hpb=b6d9eaa3ba57f4200a80d98addbaf90bd3ed1338;p=fs%2Flustre-release.git diff --git a/lustre/ldlm/ldlm_extent.c b/lustre/ldlm/ldlm_extent.c index 5825ca0..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, @@ -216,7 +217,7 @@ ldlm_extent_internal_policy_waiting(struct ldlm_lock *req, continue; /* We grow extents downwards only as far as they don't overlap - * with already-granted locks, on the assumtion that clients + * with already-granted locks, on the assumption that clients * will be writing beyond the initial requested end and would * then need to enqueue a new lock beyond previous request. * l_req_extent->end strictly < req_start, checked above. */ @@ -284,6 +285,9 @@ static int ldlm_check_contention(struct ldlm_lock *lock, int contended_locks) struct ldlm_resource *res = lock->l_resource; cfs_time_t now = cfs_time_current(); + if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_SET_CONTENTION)) + return 1; + CDEBUG(D_DLMTRACE, "contended locks = %d\n", contended_locks); if (contended_locks > res->lr_namespace->ns_contended_locks) res->lr_contention_time = now; @@ -620,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; } @@ -704,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); @@ -782,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); @@ -795,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)); } } @@ -847,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); @@ -874,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];