Whamcloud - gitweb
b=21178
authorjxiong <jxiong>
Wed, 25 Nov 2009 01:27:52 +0000 (01:27 +0000)
committerjxiong <jxiong>
Wed, 25 Nov 2009 01:27:52 +0000 (01:27 +0000)
r=wangdi,ericm

Fix a race condition in cl_sync_io_note.

lustre/obdclass/cl_io.c
lustre/obdclass/cl_page.c

index e386396..d9c6d51 100644 (file)
@@ -1633,23 +1633,16 @@ int cl_sync_io_wait(const struct lu_env *env, struct cl_io *io,
                           atomic_read(&anchor->csi_sync_nr) == 0,
                           &lwi);
         if (rc < 0) {
                           atomic_read(&anchor->csi_sync_nr) == 0,
                           &lwi);
         if (rc < 0) {
-                int rc2;
-
                 CERROR("SYNC IO failed with error: %d, try to cancel "
                 CERROR("SYNC IO failed with error: %d, try to cancel "
-                       "the remaining page\n", rc);
-
-                rc2 = cl_io_cancel(env, io, queue);
-                if (rc2 < 0) {
-                        lwi = (struct l_wait_info) { 0 };
-                        /* Too bad, some pages are still in IO. */
-                        CERROR("Failed to cancel transfer error: %d, mostly "
-                               "because of they are still being transferred, "
-                               "waiting for %i pages\n",
-                               rc2, atomic_read(&anchor->csi_sync_nr));
-                        (void)l_wait_event(anchor->csi_waitq,
-                                     atomic_read(&anchor->csi_sync_nr) == 0,
-                                     &lwi);
-                }
+                       "%d remaining pages\n",
+                       rc, atomic_read(&anchor->csi_sync_nr));
+
+                (void)cl_io_cancel(env, io, queue);
+
+                lwi = (struct l_wait_info) { 0 };
+                (void)l_wait_event(anchor->csi_waitq,
+                                   atomic_read(&anchor->csi_sync_nr) == 0,
+                                   &lwi);
         } else {
                 rc = anchor->csi_sync_rc;
         }
         } else {
                 rc = anchor->csi_sync_rc;
         }
@@ -1673,6 +1666,7 @@ void cl_sync_io_note(struct cl_sync_io *anchor, int ioret)
          * ->{prepare,commit}_write(). Completion is used to signal the end of
          * IO.
          */
          * ->{prepare,commit}_write(). Completion is used to signal the end of
          * IO.
          */
+        LASSERT(atomic_read(&anchor->csi_sync_nr) > 0);
         if (atomic_dec_and_test(&anchor->csi_sync_nr))
                 cfs_waitq_broadcast(&anchor->csi_waitq);
         EXIT;
         if (atomic_dec_and_test(&anchor->csi_sync_nr))
                 cfs_waitq_broadcast(&anchor->csi_waitq);
         EXIT;
index 55887f9..b277cc5 100644 (file)
@@ -1320,6 +1320,8 @@ EXPORT_SYMBOL(cl_page_prep);
 void cl_page_completion(const struct lu_env *env,
                         struct cl_page *pg, enum cl_req_type crt, int ioret)
 {
 void cl_page_completion(const struct lu_env *env,
                         struct cl_page *pg, enum cl_req_type crt, int ioret)
 {
+        struct cl_sync_io *anchor = pg->cp_sync_io;
+
         PASSERT(env, pg, crt < CRT_NR);
         /* cl_page::cp_req already cleared by the caller (osc_completion()) */
         PASSERT(env, pg, pg->cp_req == NULL);
         PASSERT(env, pg, crt < CRT_NR);
         /* cl_page::cp_req already cleared by the caller (osc_completion()) */
         PASSERT(env, pg, pg->cp_req == NULL);
@@ -1337,9 +1339,10 @@ void cl_page_completion(const struct lu_env *env,
         CL_PAGE_INVOID_REVERSE(env, pg, CL_PAGE_OP(io[crt].cpo_completion),
                                (const struct lu_env *,
                                 const struct cl_page_slice *, int), ioret);
         CL_PAGE_INVOID_REVERSE(env, pg, CL_PAGE_OP(io[crt].cpo_completion),
                                (const struct lu_env *,
                                 const struct cl_page_slice *, int), ioret);
-        if (pg->cp_sync_io) {
-                cl_sync_io_note(pg->cp_sync_io, ioret);
+        if (anchor) {
+                LASSERT(pg->cp_sync_io == anchor);
                 pg->cp_sync_io = NULL;
                 pg->cp_sync_io = NULL;
+                cl_sync_io_note(anchor, ioret);
         }
 
         /* Don't assert the page writeback bit here because the lustre file
         }
 
         /* Don't assert the page writeback bit here because the lustre file