static void osc_completion(const struct lu_env *env, struct osc_object *osc,
struct osc_async_page *oap, enum cl_req_type crt,
int rc);
+static void osc_dio_completion(const struct lu_env *env, struct osc_object *osc,
+ struct osc_async_page *oap, enum cl_req_type crt,
+ int brw_flags, int rc);
static int osc_make_ready(const struct lu_env *env, struct osc_async_page *oap,
int cmd);
static int osc_refresh_count(const struct lu_env *env, struct osc_object *osc,
}
--ext->oe_nr_pages;
- osc_completion(env, osc, oap, crt, rc);
+ if (ext->oe_odp.odp_cdp)
+ osc_dio_completion(env, osc, oap, crt,
+ ext->oe_odp.odp_brw_flags, rc);
+ else
+ osc_completion(env, osc, oap, crt, rc);
}
EASSERT(ext->oe_nr_pages == 0, ext);
return PAGE_SIZE;
}
-/* this must be called holding the loi list lock to give coverage to exit_cache,
- * async_flag maintenance
- */
-static void osc_completion(const struct lu_env *env, struct osc_object *osc,
- struct osc_async_page *oap, enum cl_req_type crt,
- int rc)
+static void osc_dio_completion(const struct lu_env *env, struct osc_object *osc,
+ struct osc_async_page *oap, enum cl_req_type crt,
+ int brw_flags, int rc)
{
- struct osc_page *opg = oap2osc_page(oap);
- struct cl_page *page = oap2cl_page(oap);
+ struct cl_page *page = oap2cl_page(oap);
int srvlock;
- int cptype = page->cp_type;
ENTRY;
- if (cptype != CPT_TRANSIENT) {
- /* As the transfer for this page is done, clear the flags */
- oap->oap_async_flags = 0;
-
- LASSERTF(equi(page->cp_state == CPS_PAGEIN,
- crt == CRT_READ),
- "cp_state:%u, crt:%d\n", page->cp_state, crt);
- LASSERTF(equi(page->cp_state == CPS_PAGEOUT,
- crt == CRT_WRITE),
- "cp_state:%u, crt:%d\n", page->cp_state, crt);
- LASSERT(opg->ops_transfer_pinned);
- /* Clear opg->ops_transfer_pinned before VM lock is released.*/
- opg->ops_transfer_pinned = 0;
- }
-
- srvlock = oap->oap_brw_flags & OBD_BRW_SRVLOCK;
+ srvlock = brw_flags & OBD_BRW_SRVLOCK;
/* statistic */
if (rc == 0 && srvlock) {
stats->os_lockless_writes += bytes;
}
+ /* for transient pages, the last reference can be destroyed by
+ * cl_page_complete, so do not reference the page after this
+ */
+ cl_page_complete(env, page, crt, rc);
+
+ EXIT;
+}
+
+/* this must be called holding the loi list lock to give coverage to exit_cache,
+ * async_flag maintenance
+ */
+static void osc_completion(const struct lu_env *env, struct osc_object *osc,
+ struct osc_async_page *oap, enum cl_req_type crt,
+ int rc)
+{
+ struct osc_page *opg = oap2osc_page(oap);
+ struct cl_page *page = oap2cl_page(oap);
+
+ ENTRY;
+
+ /* As the transfer for this page is done, clear the flags */
+ oap->oap_async_flags = 0;
+
+ LASSERTF(equi(page->cp_state == CPS_PAGEIN,
+ crt == CRT_READ),
+ "cp_state:%u, crt:%d\n", page->cp_state, crt);
+ LASSERTF(equi(page->cp_state == CPS_PAGEOUT,
+ crt == CRT_WRITE),
+ "cp_state:%u, crt:%d\n", page->cp_state, crt);
+ LASSERT(opg->ops_transfer_pinned);
+ /* Clear opg->ops_transfer_pinned before VM lock is released.*/
+ opg->ops_transfer_pinned = 0;
+
/*
* This has to be the last operation with the page, as locks are
* released in cl_page_completion() and nothing except for the
*/
lu_ref_del(&page->cp_reference, "transfer", page);
- /* for transient pages, the last reference can be destroyed by
- * cl_page_complete, so do not reference the page after this
- */
cl_page_complete(env, page, crt, rc);
- if (cptype != CPT_TRANSIENT)
- cl_page_put(env, page);
+ cl_page_put(env, page);
EXIT;
return;
oap = &opg->ops_oap;
list_del_init(&oap->oap_pending_item);
- osc_completion(env, obj, oap, crt, -ENOMEM);
+ osc_dio_completion(env, obj, oap, crt, brw_flags,
+ -ENOMEM);
}
RETURN(-ENOMEM);
}