+static int osc_page_addref_lock(const struct lu_env *env,
+ struct osc_page *opg,
+ struct cl_lock *lock)
+{
+ struct osc_lock *olock;
+ int rc;
+
+ LASSERT(opg->ops_lock == NULL);
+
+ olock = osc_lock_at(lock);
+ if (cfs_atomic_inc_return(&olock->ols_pageref) <= 0) {
+ cfs_atomic_dec(&olock->ols_pageref);
+ cl_lock_put(env, lock);
+ rc = 1;
+ } else {
+ opg->ops_lock = lock;
+ rc = 0;
+ }
+ return rc;
+}
+
+static void osc_page_putref_lock(const struct lu_env *env,
+ struct osc_page *opg)
+{
+ struct cl_lock *lock = opg->ops_lock;
+ struct osc_lock *olock;
+
+ LASSERT(lock != NULL);
+ olock = osc_lock_at(lock);
+
+ cfs_atomic_dec(&olock->ols_pageref);
+ opg->ops_lock = NULL;
+
+ /*
+ * Note: usually this won't be the last reference of the lock, but if
+ * it is, then all the lock_put do is at most just freeing some memory,
+ * so it would be OK that caller is holding spinlocks.
+ */
+ LASSERT(cfs_atomic_read(&lock->cll_ref) > 1 || olock->ols_hold == 0);
+ cl_lock_put(env, lock);
+}
+