}
static void failed_lock_cleanup(struct ldlm_namespace *ns,
- struct ldlm_lock *lock,
- struct lustre_handle *lockh, int mode)
+ struct ldlm_lock *lock, int mode)
{
int need_cancel = 0;
* bl_ast and -EINVAL reply is sent to server anyways.
* bug 17645 */
lock->l_flags |= LDLM_FL_LOCAL_ONLY | LDLM_FL_FAILED |
- LDLM_FL_ATOMIC_CB;
+ LDLM_FL_ATOMIC_CB | LDLM_FL_CBPENDING;
need_cancel = 1;
}
unlock_res_and_lock(lock);
- if (need_cancel) {
+ if (need_cancel)
LDLM_DEBUG(lock,
"setting FL_LOCAL_ONLY | LDLM_FL_FAILED | "
- "LDLM_FL_ATOMIC_CB");
- ldlm_lock_decref_and_cancel(lockh, mode);
- } else {
+ "LDLM_FL_ATOMIC_CB | LDLM_FL_CBPENDING");
+ else
LDLM_DEBUG(lock, "lock was granted or failed in race");
- ldlm_lock_decref(lockh, mode);
- }
+
+ ldlm_lock_decref_internal(lock, mode);
/* XXX - HACK because we shouldn't call ldlm_lock_destroy()
* from llite/file.c/ll_file_flock(). */
+ /* This code makes for the fact that we do not have blocking handler on
+ * a client for flock locks. As such this is the place where we must
+ * completely kill failed locks. (interrupted and those that
+ * were waiting to be granted when server evicted us. */
if (lock->l_resource->lr_type == LDLM_FLOCK) {
- ldlm_lock_destroy(lock);
+ lock_res_and_lock(lock);
+ ldlm_resource_unlink_lock(lock);
+ ldlm_lock_destroy_nolock(lock);
+ unlock_res_and_lock(lock);
}
}
int err = lock->l_completion_ast(lock, *flags, NULL);
if (!rc)
rc = err;
- if (rc && type != LDLM_FLOCK) /* bug 9425, bug 10250 */
+ if (rc)
cleanup_phase = 1;
}
}
EXIT;
cleanup:
if (cleanup_phase == 1 && rc)
- failed_lock_cleanup(ns, lock, lockh, mode);
+ failed_lock_cleanup(ns, lock, mode);
/* Put lock 2 times, the second reference is held by ldlm_cli_enqueue */
LDLM_LOCK_PUT(lock);
LDLM_LOCK_RELEASE(lock);
LUSTRE_DLM_VERSION,
LDLM_ENQUEUE);
if (req == NULL) {
- failed_lock_cleanup(ns, lock, lockh, einfo->ei_mode);
+ failed_lock_cleanup(ns, lock, einfo->ei_mode);
LDLM_LOCK_RELEASE(lock);
RETURN(-ENOMEM);
}
* Inform pool about current CLV to see it via proc.
*/
ldlm_pool_set_clv(pl, lv);
- return (slv == 1 || lv < slv) ?
+ return (slv == 0 || lv < slv) ?
LDLM_POLICY_KEEP_LOCK : LDLM_POLICY_CANCEL_LOCK;
}
* in a thread and this function will return after the thread has been
* asked to call the callback. when called with LDLM_SYNC the blocking
* callback will be performed in this function. */
-int ldlm_cancel_lru(struct ldlm_namespace *ns, int nr, ldlm_sync_t sync,
+int ldlm_cancel_lru(struct ldlm_namespace *ns, int nr, ldlm_sync_t mode,
int flags)
{
CFS_LIST_HEAD(cancels);
ENTRY;
#ifndef __KERNEL__
- sync = LDLM_SYNC; /* force to be sync in user space */
+ mode = LDLM_SYNC; /* force to be sync in user space */
#endif
count = ldlm_cancel_lru_local(ns, &cancels, nr, 0, 0, flags);
- if (sync == LDLM_ASYNC) {
- rc = ldlm_bl_to_thread_list(ns, NULL, &cancels, count);
- if (rc == 0)
- RETURN(count);
- }
- /* If an error occured in ASYNC mode, or this is SYNC mode,
- * cancel the list. */
- ldlm_cli_cancel_list(&cancels, count, NULL, 0);
- RETURN(count);
+ rc = ldlm_bl_to_thread_list(ns, NULL, &cancels, count, mode);
+ if (rc == 0)
+ RETURN(count);
+
+ RETURN(0);
}
/* Find and cancel locally unused locks found on resource, matched to the
RETURN(rc);
}
-/* non-blocking function to manipulate a lock whose cb_data is being put away.*/
-void ldlm_resource_iterate(struct ldlm_namespace *ns,
- const struct ldlm_res_id *res_id,
- ldlm_iterator_t iter, void *data)
+/* non-blocking function to manipulate a lock whose cb_data is being put away.
+ * return 0: find no resource
+ * > 0: must be LDLM_ITER_STOP/LDLM_ITER_CONTINUE.
+ * < 0: errors
+ */
+int ldlm_resource_iterate(struct ldlm_namespace *ns,
+ const struct ldlm_res_id *res_id,
+ ldlm_iterator_t iter, void *data)
{
struct ldlm_resource *res;
+ int rc;
ENTRY;
if (ns == NULL) {
}
res = ldlm_resource_get(ns, NULL, res_id, 0, 0);
- if (res == NULL) {
- EXIT;
- return;
- }
+ if (res == NULL)
+ RETURN(0);
LDLM_RESOURCE_ADDREF(res);
- ldlm_resource_foreach(res, iter, data);
+ rc = ldlm_resource_foreach(res, iter, data);
LDLM_RESOURCE_DELREF(res);
ldlm_resource_putref(res);
- EXIT;
+ RETURN(rc);
}
/* Lock replay */