Whamcloud - gitweb
git://git.whamcloud.com
/
fs
/
lustre-release.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
| inline |
side by side
b=19188
[fs/lustre-release.git]
/
lustre
/
llite
/
vvp_page.c
diff --git
a/lustre/llite/vvp_page.c
b/lustre/llite/vvp_page.c
index
2432c50
..
f543f59
100644
(file)
--- a/
lustre/llite/vvp_page.c
+++ b/
lustre/llite/vvp_page.c
@@
-83,9
+83,32
@@
static void vvp_page_own(const struct lu_env *env,
{
struct ccc_page *vpg = cl2ccc_page(slice);
cfs_page_t *vmpage = vpg->cpg_page;
+ int count = 0;
LASSERT(vmpage != NULL);
- lock_page(vmpage);
+
+ /* DEBUG CODE FOR #18881 */
+ while (TestSetPageLocked(vmpage)) {
+ cfs_schedule_timeout(CFS_TASK_INTERRUPTIBLE,
+ cfs_time_seconds(1)/10);
+ if (++count > 600) {
+ CL_PAGE_DEBUG(D_ERROR, env,
+ cl_page_top(slice->cpl_page),
+ "XXX page %p blocked on acquiring the"
+ " lock. process %s/%p, flags %lx,io %p\n",
+ vmpage, current->comm, current,
+ vmpage->flags, _);
+ libcfs_debug_dumpstack(NULL);
+ LCONSOLE_WARN("Reproduced bug #18881,please contact:"
+ "jay <jinshan.xiong@sun.com>, thanks\n");
+
+ lock_page(vmpage);
+ break;
+ }
+ }
+ /* DEBUG CODE END */
+
+ /* lock_page(vmpage); */
wait_on_page_writeback(vmpage);
}
@@
-209,6
+232,7
@@
static int vvp_page_prep_write(const struct lu_env *env,
if (clear_page_dirty_for_io(vmpage)) {
set_page_writeback(vmpage);
+ vvp_write_pending(cl2ccc(slice->cpl_obj), cl2ccc_page(slice));
result = 0;
} else
result = -EALREADY;
@@
-243,15
+267,22
@@
static void vvp_page_completion_common(const struct lu_env *env,
struct cl_sync_io *anchor = cp->cpg_sync_io;
LINVRNT(cl_page_is_vmlocked(env, clp));
- KLASSERT(!PageWriteback(vmpage));
-
- vvp_vmpage_error(inode, vmpage, ioret);
if (anchor != NULL) {
cp->cpg_sync_io = NULL;
cl_sync_io_note(anchor, ioret);
- } else if (clp->cp_type == CPT_CACHEABLE)
+ } else if (clp->cp_type == CPT_CACHEABLE) {
+ /*
+ * Only mark the page error only when it's a cacheable page
+ * and NOT a sync io.
+ *
+ * For sync IO and direct IO(CPT_TRANSIENT), the error is able
+ * to be seen by application, so we don't need to mark a page
+ * as error at all.
+ */
+ vvp_vmpage_error(inode, vmpage, ioret);
unlock_page(vmpage);
+ }
}
static void vvp_page_completion_read(const struct lu_env *env,
@@
-285,14
+316,18
@@
static void vvp_page_completion_write_common(const struct lu_env *env,
{
struct ccc_page *cp = cl2ccc_page(slice);
- if (ioret == 0) {
- cp->cpg_write_queued = 0;
- /*
- * Only ioret == 0, write succeed, then this page could be
- * deleted from the pending_writing count.
- */
- vvp_write_complete(cl2ccc(slice->cpl_obj), cp);
- }
+ /*
+ * TODO: Actually it makes sense to add the page into oap pending
+ * list again and so that we don't need to take the page out from
+ * SoM write pending list, if we just meet a recoverable error,
+ * -ENOMEM, etc.
+ * To implement this, we just need to return a non zero value in
+ * ->cpo_completion method. The underlying transfer should be notified
+ * and then re-add the page into pending transfer queue. -jay
+ */
+ cp->cpg_write_queued = 0;
+ vvp_write_complete(cl2ccc(slice->cpl_obj), cp);
+
vvp_page_completion_common(env, cp, ioret);
}
@@
-311,18
+346,16
@@
static void vvp_page_completion_write(const struct lu_env *env,
CL_PAGE_HEADER(D_PAGE, env, pg, "completing WRITE with %d\n", ioret);
- end_page_writeback(vmpage);
- LASSERT(!PageWriteback(vmpage));
-
vvp_page_completion_write_common(env, slice, ioret);
+ end_page_writeback(vmpage);
EXIT;
}
/**
* Implements cl_page_operations::cpo_make_ready() method.
*
- * This is called to yank
page from the transfer page and to send it out as a
- * part of transfer. This function try-locks the page. If try-lock failed,
+ * This is called to yank
a page from the transfer cache and to send it out as
+ *
a
part of transfer. This function try-locks the page. If try-lock failed,
* page is owned by some concurrent IO, and should be skipped (this is bad,
* but hopefully rare situation, as it usually results in transfer being
* shorter than possible).
@@
-352,7
+385,8
@@
static int vvp_page_make_ready(const struct lu_env *env,
* 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
@@
-386,14
+420,6
@@
static int vvp_page_print(const struct lu_env *env,
return 0;
}
-static int osc_page_cancel(const struct lu_env *env,
- const struct cl_page_slice *slice)
-{
- struct ccc_page *vp = cl2ccc_page(slice);
- LASSERT(vp->cpg_sync_io != NULL);
- return 0;
-}
-
static const struct cl_page_operations vvp_page_ops = {
.cpo_own = vvp_page_own,
.cpo_assume = vvp_page_assume,
@@
-408,7
+434,6
@@
static const struct cl_page_operations vvp_page_ops = {
.cpo_fini = vvp_page_fini,
.cpo_print = vvp_page_print,
.cpo_is_under_lock = ccc_page_is_under_lock,
- .cpo_cancel = osc_page_cancel,
.io = {
[CRT_READ] = {
.cpo_prep = vvp_page_prep_read,
@@
-518,7
+543,6
@@
static const struct cl_page_operations vvp_transient_page_ops = {
.cpo_is_vmlocked = vvp_transient_page_is_vmlocked,
.cpo_print = vvp_page_print,
.cpo_is_under_lock = ccc_page_is_under_lock,
- .cpo_cancel = osc_page_cancel,
.io = {
[CRT_READ] = {
.cpo_prep = ccc_transient_page_prep,
@@
-539,7
+563,7
@@
struct cl_page *vvp_page_init(const struct lu_env *env, struct cl_object *obj,
CLOBINVRNT(env, obj, ccc_object_invariant(obj));
- OBD_SLAB_ALLOC_PTR
(cpg, vvp_page_kmem
);
+ OBD_SLAB_ALLOC_PTR
_GFP(cpg, vvp_page_kmem, CFS_ALLOC_IO
);
if (cpg != NULL) {
cpg->cpg_page = vmpage;
page_cache_get(vmpage);