Whamcloud - gitweb
LU-185 LBUG: (cl_page.c:1362:cl_page_completion()) ...
authorJinshan Xiong <jay@whamcloud.com>
Wed, 6 Apr 2011 00:24:53 +0000 (17:24 -0700)
committerOleg Drokin <green@whamcloud.com>
Tue, 3 May 2011 21:35:27 +0000 (14:35 -0700)
!(pg->cp_flags & CPF_READ_COMPLETED) ASSERTION(0) failed

The root cause of this issue is that the application is doing regular and
direct IO on the same time. This will cause a ra page is issued for read
again.

Change-Id: I11bb46d334db52fa3faf3922b70ac831391a8217
Signed-off-by: Jinshan Xiong <jay@whamcloud.com>
Reviewed-on: http://review.whamcloud.com/404
Tested-by: Hudson
Reviewed-by: wangdi <di.wang@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/llite/rw26.c

index d2137f7..25ade0e 100644 (file)
@@ -232,6 +232,8 @@ ssize_t ll_direct_rw_pages(const struct lu_env *env, struct cl_io *io,
         int page_count      = pv->ldp_nr;
         struct page **pages = pv->ldp_pages;
         long page_size      = cl_page_size(obj);
+        bool do_io;
+        int  io_pages       = 0;
         ENTRY;
 
         queue = &io->ci_queue;
@@ -239,6 +241,7 @@ ssize_t ll_direct_rw_pages(const struct lu_env *env, struct cl_io *io,
         for (i = 0; i < page_count; i++) {
                 if (pv->ldp_offsets)
                     file_offset = pv->ldp_offsets[i];
+
                 LASSERT(!(file_offset & (page_size - 1)));
                 clp = cl_page_find(env, obj, cl_index(obj, file_offset),
                                    pv->ldp_pages[i], CPT_TRANSIENT);
@@ -247,14 +250,17 @@ ssize_t ll_direct_rw_pages(const struct lu_env *env, struct cl_io *io,
                         break;
                 }
 
+                rc = cl_page_own(env, io, clp);
+                if (rc) {
+                        LASSERT(clp->cp_state == CPS_FREEING);
+                        cl_page_put(env, clp);
+                        break;
+                }
+
+                do_io = true;
+
                 /* check the page type: if the page is a host page, then do
                  * write directly */
-                /*
-                 * Very rare case that the host pages can be found for
-                 * directIO case, since linux kernel truncated all covered
-                 * pages before getting here. So, to make the OST happy(to
-                 * write a contiguous region), all pages are issued
-                 * here. -jay */
                 if (clp->cp_type == CPT_CACHEABLE) {
                         cfs_page_t *vmpage = cl_page_vmpage(env, clp);
                         cfs_page_t *src_page;
@@ -275,43 +281,41 @@ ssize_t ll_direct_rw_pages(const struct lu_env *env, struct cl_io *io,
                          * cl_io_submit()->...->vvp_page_prep_write(). */
                         if (rw == WRITE)
                                 set_page_dirty(vmpage);
+
+                        if (rw == READ) {
+                                /* do not issue the page for read, since it
+                                 * may reread a ra page which has NOT uptodate
+                                 * bit set. */
+                                cl_page_disown(env, io, clp);
+                                do_io = false;
+                        }
+                }
+
+                if (likely(do_io)) {
+                        cl_2queue_add(queue, clp);
+
                         /*
-                         * If direct-io read finds up-to-date page in the
-                         * cache, just copy it to the user space. Page will be
-                         * filtered out by vvp_page_prep_read(). This
-                         * preserves an invariant, that page is read at most
-                         * once, see cl_page_flags::CPF_READ_COMPLETED.
+                         * Set page clip to tell transfer formation engine
+                         * that page has to be sent even if it is beyond KMS.
                          */
-                }
+                        cl_page_clip(env, clp, 0, min(size, page_size));
 
-                rc = cl_page_own(env, io, clp);
-                if (rc) {
-                        LASSERT(clp->cp_state == CPS_FREEING);
-                        cl_page_put(env, clp);
-                        break;
+                        ++io_pages;
                 }
 
-                cl_2queue_add(queue, clp);
-
-                /* drop the reference count for cl_page_find, so that the page
-                 * will be freed in cl_2queue_fini. */
+                /* drop the reference count for cl_page_find */
                 cl_page_put(env, clp);
-                /*
-                 * Set page clip to tell transfer formation engine that page
-                 * has to be sent even if it is beyond KMS.
-                 */
-                cl_page_clip(env, clp, 0, min(size, page_size));
                 size -= page_size;
                 file_offset += page_size;
         }
 
-        if (rc == 0) {
+        if (rc == 0 && io_pages) {
                 rc = cl_io_submit_sync(env, io,
                                        rw == READ ? CRT_READ : CRT_WRITE,
                                        queue, CRP_NORMAL, 0);
-                if (rc == 0)
-                        rc = pv->ldp_size;
         }
+        if (rc == 0)
+                rc = pv->ldp_size;
 
         cl_2queue_discard(env, io, queue);
         cl_2queue_disown(env, io, queue);