Whamcloud - gitweb
LU-2910 clio: restore iov when restart io
authorNiu Yawei <niu@whamcloud.com>
Fri, 8 Mar 2013 04:58:11 +0000 (23:58 -0500)
committerOleg Drokin <oleg.drokin@intel.com>
Fri, 15 Mar 2013 05:29:31 +0000 (01:29 -0400)
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 <yawei.niu@intel.com>
Change-Id: I5d737cfa083ae3b3d9f040a2dc36d6b8693b548b
Reviewed-on: http://review.whamcloud.com/5652
Reviewed-by: Jinshan Xiong <jinshan.xiong@intel.com>
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Bobi Jam <bobijam@gmail.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/lclient/lcommon_cl.c
lustre/llite/file.c

index 41ebae9..a6d5d58 100644 (file)
@@ -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;
+       }
 }
 
 /**
index d763cf7..723b8e8 100644 (file)
@@ -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)