Whamcloud - gitweb
LU-12503 llite: file write pos mimatch 21/36021/3
authorBobi Jam <bobijam@whamcloud.com>
Wed, 27 Nov 2019 08:48:49 +0000 (16:48 +0800)
committerOleg Drokin <green@whamcloud.com>
Sat, 14 Dec 2019 05:56:28 +0000 (05:56 +0000)
In vvp_io_write_start(), after data were successfully written, but
for some reason (e.g. out of quota), the data does not or got
partially commited, so that the file's write position (kiocb->ki_pos)
would be pushed forward falsely, and in the next iteration of write
loop, it fails the assertion

ASSERTION( io->u.ci_rw.rw_iocb.ki_pos == range->cir_pos )

This patch corrects ki_pos if this scenario happens.

Signed-off-by: Bobi Jam <bobijam@whamcloud.com>
Change-Id: Ib85b1a777da24cc935e5976beab2390052b4cec3
Reviewed-on: https://review.whamcloud.com/36021
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: Wang Shilong <wshilong@ddn.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/llite/vvp_io.c

index 8f8b724..3cc9531 100644 (file)
@@ -1146,6 +1146,8 @@ static int vvp_io_write_start(const struct lu_env *env,
        loff_t                   pos = io->u.ci_wr.wr.crw_pos;
        size_t                   cnt = io->u.ci_wr.wr.crw_count;
        bool                     lock_inode = !IS_NOSEC(inode);
+       size_t nob = io->ci_nob;
+       size_t written = 0;
 
        ENTRY;
 
@@ -1215,6 +1217,7 @@ static int vvp_io_write_start(const struct lu_env *env,
                if (unlikely(lock_inode))
                        inode_unlock(inode);
 
+               written = result;
                if (result > 0 || result == -EIOCBQUEUED)
 #ifdef HAVE_GENERIC_WRITE_SYNC_2ARGS
                        result = generic_write_sync(vio->vui_iocb, result);
@@ -1240,6 +1243,16 @@ static int vvp_io_write_start(const struct lu_env *env,
                        io->ci_nob += result;
                }
        }
+       if (vio->vui_iocb->ki_pos != (pos + io->ci_nob - nob)) {
+               CDEBUG(D_VFSTRACE, "%s: write position mismatch: "
+                      "ki_pos %lld vs. pos %lld, written %ld, commit %ld "
+                      "rc %ld\n",
+                      file_dentry(file)->d_name.name,
+                      vio->vui_iocb->ki_pos, pos + io->ci_nob - nob,
+                      written, io->ci_nob - nob, result);
+               /* rewind ki_pos to where it has successfully committed */
+               vio->vui_iocb->ki_pos = pos + io->ci_nob - nob;
+       }
        if (result > 0) {
                ll_file_set_flag(ll_i2info(inode), LLIF_DATA_MODIFIED);