From: jxiong Date: Wed, 25 Nov 2009 01:27:52 +0000 (+0000) Subject: b=21178 X-Git-Tag: GIT_EPOCH_B_HD_KDMU~64 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=020c0a8c6ac50ab1b7d0a240722b90c7c31b64c1 b=21178 r=wangdi,ericm Fix a race condition in cl_sync_io_note. --- diff --git a/lustre/obdclass/cl_io.c b/lustre/obdclass/cl_io.c index e386396..d9c6d51 100644 --- a/lustre/obdclass/cl_io.c +++ b/lustre/obdclass/cl_io.c @@ -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) { - int rc2; - 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; } @@ -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. */ + LASSERT(atomic_read(&anchor->csi_sync_nr) > 0); if (atomic_dec_and_test(&anchor->csi_sync_nr)) cfs_waitq_broadcast(&anchor->csi_waitq); EXIT; diff --git a/lustre/obdclass/cl_page.c b/lustre/obdclass/cl_page.c index 55887f9..b277cc5 100644 --- a/lustre/obdclass/cl_page.c +++ b/lustre/obdclass/cl_page.c @@ -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) { + 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); @@ -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); - 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; + cl_sync_io_note(anchor, ioret); } /* Don't assert the page writeback bit here because the lustre file