-static void osc_lock_cancel(const struct lu_env *env,
- const struct cl_lock_slice *slice)
-{
- struct cl_lock *lock = slice->cls_lock;
- struct osc_lock *olck = cl2osc_lock(slice);
- struct ldlm_lock *dlmlock = olck->ols_lock;
- int result = 0;
- int discard;
-
- LASSERT(cl_lock_is_mutexed(lock));
- LINVRNT(osc_lock_invariant(olck));
-
- if (dlmlock != NULL) {
- int do_cancel;
-
- discard = !!(dlmlock->l_flags & LDLM_FL_DISCARD_DATA);
- if (olck->ols_state >= OLS_GRANTED)
- result = osc_lock_flush(olck, discard);
- osc_lock_unhold(olck);
-
- lock_res_and_lock(dlmlock);
- /* Now that we're the only user of dlm read/write reference,
- * mostly the ->l_readers + ->l_writers should be zero.
- * However, there is a corner case.
- * See bug 18829 for details.*/
- do_cancel = (dlmlock->l_readers == 0 &&
- dlmlock->l_writers == 0);
- dlmlock->l_flags |= LDLM_FL_CBPENDING;
- unlock_res_and_lock(dlmlock);
- if (do_cancel)
- result = ldlm_cli_cancel(&olck->ols_handle);
- if (result < 0)
- CL_LOCK_DEBUG(D_ERROR, env, lock,
- "lock %p cancel failure with error(%d)\n",
- lock, result);
- }
- olck->ols_state = OLS_CANCELLED;
- olck->ols_flags &= ~LDLM_FL_LVB_READY;
- osc_lock_detach(env, olck);
-}
-
-#ifdef INVARIANT_CHECK
-static int check_cb(const struct lu_env *env, struct cl_io *io,
- struct cl_page *page, void *cbdata)
-{
- struct cl_lock *lock = cbdata;
-
- if (lock->cll_descr.cld_mode == CLM_READ) {
- struct cl_lock *tmp;
- tmp = cl_lock_at_page(env, lock->cll_descr.cld_obj,
- page, lock, 1, 0);
- if (tmp != NULL) {
- cl_lock_put(env, tmp);
- return CLP_GANG_OKAY;
- }
- }
-
- CL_LOCK_DEBUG(D_ERROR, env, lock, "still has pages\n");
- CL_PAGE_DEBUG(D_ERROR, env, page, "\n");
- return CLP_GANG_ABORT;
-}
-
-/**
- * Returns true iff there are pages under \a olck not protected by other
- * locks.
- */
-static int osc_lock_has_pages(struct osc_lock *olck)
-{
- struct cl_lock *lock;
- struct cl_lock_descr *descr;
- struct cl_object *obj;
- struct osc_object *oob;
- struct cl_env_nest nest;
- struct cl_io *io;
- struct lu_env *env;
- int result;
-
- env = cl_env_nested_get(&nest);
- if (IS_ERR(env))
- return 0;
-
- obj = olck->ols_cl.cls_obj;
- oob = cl2osc(obj);
- io = &oob->oo_debug_io;
- lock = olck->ols_cl.cls_lock;
- descr = &lock->cll_descr;
-
- mutex_lock(&oob->oo_debug_mutex);
-
- io->ci_obj = cl_object_top(obj);
- io->ci_ignore_layout = 1;
- cl_io_init(env, io, CIT_MISC, io->ci_obj);
- do {
- result = cl_page_gang_lookup(env, obj, io,
- descr->cld_start, descr->cld_end,
- check_cb, (void *)lock);
- if (result == CLP_GANG_ABORT)
- break;
- if (result == CLP_GANG_RESCHED)
- cfs_cond_resched();
- } while (result != CLP_GANG_OKAY);
- cl_io_fini(env, io);
- mutex_unlock(&oob->oo_debug_mutex);
- cl_env_nested_put(&nest, env);
-
- return (result == CLP_GANG_ABORT);
-}
-#else
-static int osc_lock_has_pages(struct osc_lock *olck)
-{
- return 0;
-}
-#endif /* INVARIANT_CHECK */
-
-static void osc_lock_delete(const struct lu_env *env,
- const struct cl_lock_slice *slice)