X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fldlm%2Fldlm_request.c;h=3731f7dc0f56791fcbc9285c60175c99e34deb73;hb=4b5bb6b7cd2b2e7fad8dae3c5e1e7a0bdc488f62;hp=2b83255ce8bfe33efa7b173ebb64e4ca55d1d972;hpb=26f846563602a3275472079c2a360a88ac4db514;p=fs%2Flustre-release.git diff --git a/lustre/ldlm/ldlm_request.c b/lustre/ldlm/ldlm_request.c index 2b83255..3731f7d 100644 --- a/lustre/ldlm/ldlm_request.c +++ b/lustre/ldlm/ldlm_request.c @@ -12,6 +12,7 @@ #define DEBUG_SUBSYSTEM S_LDLM #include +#include int ldlm_completion_ast(struct ldlm_lock *lock, int flags) { @@ -107,7 +108,6 @@ int ldlm_cli_enqueue(struct lustre_handle *connh, __u32 data_len, struct lustre_handle *lockh) { - struct ptlrpc_connection *connection; struct ldlm_lock *lock; struct ldlm_request *body; struct ldlm_reply *reply; @@ -119,7 +119,6 @@ int ldlm_cli_enqueue(struct lustre_handle *connh, type, cookie, cookielen, mode, flags, completion, blocking, data, data_len, lockh); - connection = client_conn2cli(connh)->cl_conn; *flags = 0; lock = ldlm_lock_create(ns, parent_lock_handle, res_id, type, mode, @@ -132,7 +131,8 @@ int ldlm_cli_enqueue(struct lustre_handle *connh, ldlm_lock2handle(lock, lockh); if (req == NULL) { - req = ptlrpc_prep_req2(connh, LDLM_ENQUEUE, 1, &size, NULL); + req = ptlrpc_prep_req(class_conn2cliimp(connh), LDLM_ENQUEUE, 1, + &size, NULL); if (!req) GOTO(out, rc = -ENOMEM); req_passed_in = 0; @@ -159,8 +159,7 @@ int ldlm_cli_enqueue(struct lustre_handle *connh, req->rq_replen = lustre_msg_size(1, &size); } lock->l_connh = connh; - lock->l_connection = ptlrpc_connection_addref(connection); - lock->l_client = client_conn2cli(connh)->cl_client; + lock->l_export = NULL; rc = ptlrpc_queue_wait(req); /* FIXME: status check here? */ @@ -305,7 +304,8 @@ int ldlm_cli_convert(struct lustre_handle *lockh, int new_mode, int *flags) LDLM_DEBUG(lock, "client-side convert"); - req = ptlrpc_prep_req2(connh, LDLM_CONVERT, 1, &size, NULL); + req = ptlrpc_prep_req(class_conn2cliimp(connh), LDLM_CONVERT, 1, &size, + NULL); if (!req) GOTO(out, rc = -ENOMEM); @@ -360,8 +360,13 @@ int ldlm_cli_cancel(struct lustre_handle *lockh) if (lock->l_connh) { LDLM_DEBUG(lock, "client-side cancel"); - req = ptlrpc_prep_req2(lock->l_connh, LDLM_CANCEL, 1, &size, - NULL); + /* Set this flag to prevent others from getting new references*/ + l_lock(&lock->l_resource->lr_namespace->ns_lock); + lock->l_flags |= LDLM_FL_CBPENDING; + l_unlock(&lock->l_resource->lr_namespace->ns_lock); + + req = ptlrpc_prep_req(class_conn2cliimp(lock->l_connh), + LDLM_CANCEL, 1, &size, NULL); if (!req) GOTO(out, rc = -ENOMEM); @@ -394,3 +399,56 @@ int ldlm_cli_cancel(struct lustre_handle *lockh) LDLM_LOCK_PUT(lock); return rc; } + +/* Cancel all locks on a given resource that have 0 readers/writers */ +int ldlm_cli_cancel_unused(struct ldlm_namespace *ns, __u64 *res_id) +{ + struct ldlm_resource *res; + struct list_head *tmp, *next, list = LIST_HEAD_INIT(list); + struct ldlm_ast_work *w; + ENTRY; + + res = ldlm_resource_get(ns, NULL, res_id, 0, 0); + if (res == NULL) + RETURN(-EINVAL); + + l_lock(&ns->ns_lock); + list_for_each(tmp, &res->lr_granted) { + struct ldlm_lock *lock; + lock = list_entry(tmp, struct ldlm_lock, l_res_link); + + if (lock->l_readers || lock->l_writers) + continue; + + /* Setting the CBPENDING flag is a little misleading, but + * prevents an important race; namely, once CBPENDING is set, + * the lock can accumulate no more readers/writers. Since + * readers and writers are already zero here, ldlm_lock_decref + * won't see this flag and call l_blocking_ast */ + lock->l_flags |= LDLM_FL_CBPENDING; + + OBD_ALLOC(w, sizeof(*w)); + LASSERT(w); + + w->w_lock = LDLM_LOCK_GET(lock); + list_add(&w->w_list, &list); + } + l_unlock(&ns->ns_lock); + + list_for_each_safe(tmp, next, &list) { + struct lustre_handle lockh; + int rc; + w = list_entry(tmp, struct ldlm_ast_work, w_list); + + ldlm_lock2handle(w->w_lock, &lockh); + rc = ldlm_cli_cancel(&lockh); + if (rc != ELDLM_OK) + CERROR("ldlm_cli_cancel: %d\n", rc); + + LDLM_LOCK_PUT(w->w_lock); + list_del(&w->w_list); + OBD_FREE(w, sizeof(*w)); + } + + RETURN(0); +}