- cfs_page_t *vmpage = cl2vm_page(slice);
- struct cl_page *pg = slice->cpl_page;
- int result;
-
- result = -EAGAIN;
- /* we're trying to write, but the page is locked.. come back later */
- if (!TestSetPageLocked(vmpage)) {
- if (pg->cp_state == CPS_CACHED) {
- /*
- * We can cancel IO if page wasn't dirty after all.
- */
- clear_page_dirty_for_io(vmpage);
- /*
- * This actually clears the dirty bit in the radix
- * tree.
- */
- set_page_writeback(vmpage);
- vvp_write_pending(cl2ccc(slice->cpl_obj),
- cl2ccc_page(slice));
- CL_PAGE_HEADER(D_PAGE, env, pg, "readied\n");
- result = 0;
- } else
- /*
- * Page was concurrently truncated.
- */
- LASSERT(pg->cp_state == CPS_FREEING);
- }
- RETURN(result);
+ struct page *vmpage = cl2vm_page(slice);
+ struct cl_page *pg = slice->cpl_page;
+ int result = 0;
+
+ lock_page(vmpage);
+ if (clear_page_dirty_for_io(vmpage)) {
+ LASSERT(pg->cp_state == CPS_CACHED);
+ /* This actually clears the dirty bit in the radix
+ * tree. */
+ set_page_writeback(vmpage);
+ vvp_write_pending(cl2ccc(slice->cpl_obj),
+ cl2ccc_page(slice));
+ CL_PAGE_HEADER(D_PAGE, env, pg, "readied\n");
+ } else if (pg->cp_state == CPS_PAGEOUT) {
+ /* is it possible for osc_flush_async_page() to already
+ * make it ready? */
+ result = -EALREADY;
+ } else {
+ CL_PAGE_DEBUG(D_ERROR, env, pg, "Unexpecting page state %d.\n",
+ pg->cp_state);
+ LBUG();
+ }
+ unlock_page(vmpage);
+ RETURN(result);
+}
+
+static int vvp_page_is_under_lock(const struct lu_env *env,
+ const struct cl_page_slice *slice,
+ struct cl_io *io, pgoff_t *max_index)
+{
+ ENTRY;
+
+ if (io->ci_type == CIT_READ || io->ci_type == CIT_WRITE ||
+ io->ci_type == CIT_FAULT) {
+ struct ccc_io *cio = ccc_env_io(env);
+
+ if (unlikely(cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED))
+ *max_index = CL_PAGE_EOF;
+ }
+ RETURN(0);