From ae76dd2f1866c9350df8cb4e772c12cc0d3c4314 Mon Sep 17 00:00:00 2001 From: Niu Yawei Date: Thu, 7 Mar 2013 23:58:11 -0500 Subject: [PATCH] LU-2910 clio: restore iov when restart io The iovector needs be restored on restarted io. This patch also added some LASSERT and debug message to make it easier to debug this kind of problem later. Test-Parameters: testlist=racer Signed-off-by: Niu Yawei Change-Id: I5d737cfa083ae3b3d9f040a2dc36d6b8693b548b Reviewed-on: http://review.whamcloud.com/5652 Reviewed-by: Jinshan Xiong Tested-by: Hudson Tested-by: Maloo Reviewed-by: Bobi Jam Reviewed-by: Oleg Drokin --- lustre/lclient/lcommon_cl.c | 52 +++++++++++++++++++++++++++------------------ lustre/llite/file.c | 10 ++++++++- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/lustre/lclient/lcommon_cl.c b/lustre/lclient/lcommon_cl.c index 41ebae9..a6d5d58 100644 --- a/lustre/lclient/lcommon_cl.c +++ b/lustre/lclient/lcommon_cl.c @@ -789,6 +789,9 @@ void ccc_io_update_iov(const struct lu_env *env, } cio->cui_nrsegs = i + 1; + LASSERTF(cio->cui_tot_nrsegs >= cio->cui_nrsegs, + "tot_nrsegs: %lu, nrsegs: %lu\n", + cio->cui_tot_nrsegs, cio->cui_nrsegs); } int ccc_io_one_lock(const struct lu_env *env, struct cl_io *io, @@ -810,32 +813,39 @@ void ccc_io_advance(const struct lu_env *env, const struct cl_io_slice *ios, size_t nob) { - struct ccc_io *cio = cl2ccc_io(env, ios); - struct cl_io *io = ios->cis_io; - struct cl_object *obj = ios->cis_io->ci_obj; + struct ccc_io *cio = cl2ccc_io(env, ios); + struct cl_io *io = ios->cis_io; + struct cl_object *obj = ios->cis_io->ci_obj; - CLOBINVRNT(env, obj, ccc_object_invariant(obj)); + CLOBINVRNT(env, obj, ccc_object_invariant(obj)); - if (cl_is_normalio(env, io) && io->ci_continue) { - /* update the iov */ - LASSERT(cio->cui_tot_nrsegs >= cio->cui_nrsegs); - LASSERT(cio->cui_tot_count >= nob); + if (!cl_is_normalio(env, io)) + return; - cio->cui_iov += cio->cui_nrsegs; - cio->cui_tot_nrsegs -= cio->cui_nrsegs; - cio->cui_tot_count -= nob; + LASSERT(cio->cui_tot_nrsegs >= cio->cui_nrsegs); + LASSERT(cio->cui_tot_count >= nob); - if (cio->cui_iov_olen) { - struct iovec *iv; + cio->cui_iov += cio->cui_nrsegs; + cio->cui_tot_nrsegs -= cio->cui_nrsegs; + cio->cui_tot_count -= nob; - cio->cui_iov--; - cio->cui_tot_nrsegs++; - iv = &cio->cui_iov[0]; - iv->iov_base += iv->iov_len; - LASSERT(cio->cui_iov_olen > iv->iov_len); - iv->iov_len = cio->cui_iov_olen - iv->iov_len; - } - } + /* update the iov */ + if (cio->cui_iov_olen > 0) { + struct iovec *iv; + + cio->cui_iov--; + cio->cui_tot_nrsegs++; + iv = &cio->cui_iov[0]; + if (io->ci_continue) { + iv->iov_base += iv->iov_len; + LASSERT(cio->cui_iov_olen > iv->iov_len); + iv->iov_len = cio->cui_iov_olen - iv->iov_len; + } else { + /* restore the iov_len, in case of restart io. */ + iv->iov_len = cio->cui_iov_olen; + } + cio->cui_iov_olen = 0; + } } /** diff --git a/lustre/llite/file.c b/lustre/llite/file.c index d763cf7..723b8e8 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -920,8 +920,16 @@ restart: GOTO(out, result); out: cl_io_fini(env, io); - if (result == 0 && io->ci_need_restart) /* need to restart whole IO */ + /* If any bit been read/written (result != 0), we just return + * short read/write instead of restart io. */ + if (result == 0 && io->ci_need_restart) { + CDEBUG(D_VFSTRACE, "Restart %s on %s from %lld, count:%zd\n", + iot == CIT_READ ? "read" : "write", + file->f_dentry->d_name.name, *ppos, count); + LASSERTF(io->u.ci_rw.crw_count == count, "%zd != %zd\n", + io->u.ci_rw.crw_count, count); goto restart; + } if (iot == CIT_READ) { if (result >= 0) -- 1.8.3.1