Whamcloud - gitweb
LU-14709 pcc: VM_WRITE should not trigger layout write 83/44483/7
authorQian Yingjin <qian@ddn.com>
Sat, 31 Jul 2021 07:45:56 +0000 (15:45 +0800)
committerOleg Drokin <green@whamcloud.com>
Fri, 17 Sep 2021 14:08:10 +0000 (14:08 +0000)
VM area marked with VM_WRITE means that pages may be written, but
mmap page write may never happen.
It should delay layout write until the actual modification on the
file happen in ->page_mkwrite().
Otherwise, it will trigger panic for PCC-RO sanity-pcc test_21f().

Fixes: f2d1c4ee4 ("LU-14647 flr: mmap write/punch does not stale other mirrors")
Signed-off-by: Qian Yingjin <qian@ddn.com>
Change-Id: I1cbfef8a4ed7e2c718324fd8a21bafd6157b5f0c
Reviewed-by: Patrick Farrell <pfarrell@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/44483
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Bobi Jam <bobijam@hotmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/cl_object.h
lustre/llite/llite_mmap.c
lustre/llite/vvp_io.c
lustre/lov/lov_io.c
lustre/tests/mmap_sanity.c

index 4825804..145e683 100644 (file)
@@ -2464,11 +2464,6 @@ static inline int cl_io_is_mkwrite(const struct cl_io *io)
        return io->ci_type == CIT_FAULT && io->u.ci_fault.ft_mkwrite;
 }
 
        return io->ci_type == CIT_FAULT && io->u.ci_fault.ft_mkwrite;
 }
 
-static inline int cl_io_is_fault_writable(const struct cl_io *io)
-{
-       return io->ci_type == CIT_FAULT && io->u.ci_fault.ft_writable;
-}
-
 /**
  * True, iff \a io is a truncate(2).
  */
 /**
  * True, iff \a io is a truncate(2).
  */
index 4600c76..963aa07 100644 (file)
@@ -77,11 +77,13 @@ struct vm_area_struct *our_vma(struct mm_struct *mm, unsigned long addr,
  * \param env - corespondent lu_env to processing
  * \param vma - virtual memory area addressed to page fault
  * \param index - page index corespondent to fault.
  * \param env - corespondent lu_env to processing
  * \param vma - virtual memory area addressed to page fault
  * \param index - page index corespondent to fault.
+ * \param mkwrite - whether it is mmap write.
  *
  * \return error codes from cl_io_init.
  */
 static struct cl_io *
  *
  * \return error codes from cl_io_init.
  */
 static struct cl_io *
-ll_fault_io_init(struct lu_env *env, struct vm_area_struct *vma, pgoff_t index)
+ll_fault_io_init(struct lu_env *env, struct vm_area_struct *vma,
+               pgoff_t index, bool mkwrite)
 {
        struct file            *file = vma->vm_file;
        struct inode           *inode = file_inode(file);
 {
        struct file            *file = vma->vm_file;
        struct inode           *inode = file_inode(file);
@@ -102,6 +104,11 @@ restart:
        fio->ft_index = index;
        fio->ft_executable = vma->vm_flags & VM_EXEC;
 
        fio->ft_index = index;
        fio->ft_executable = vma->vm_flags & VM_EXEC;
 
+       if (mkwrite) {
+               fio->ft_mkwrite = 1;
+               fio->ft_writable = 1;
+       }
+
        CDEBUG(D_MMAP,
               DFID": vma=%p start=%#lx end=%#lx vm_flags=%#lx idx=%lu\n",
               PFID(&ll_i2info(inode)->lli_fid), vma, vma->vm_start,
        CDEBUG(D_MMAP,
               DFID": vma=%p start=%#lx end=%#lx vm_flags=%#lx idx=%lu\n",
               PFID(&ll_i2info(inode)->lli_fid), vma, vma->vm_start,
@@ -112,9 +119,6 @@ restart:
        else if (vma->vm_flags & VM_RAND_READ)
                io->ci_rand_read = 1;
 
        else if (vma->vm_flags & VM_RAND_READ)
                io->ci_rand_read = 1;
 
-       if (vma->vm_flags & VM_WRITE)
-               fio->ft_writable = 1;
-
        rc = cl_io_init(env, io, CIT_FAULT, io->ci_obj);
        if (rc == 0) {
                struct vvp_io *vio = vvp_env_io(env);
        rc = cl_io_init(env, io, CIT_FAULT, io->ci_obj);
        if (rc == 0) {
                struct vvp_io *vio = vvp_env_io(env);
@@ -156,7 +160,7 @@ static int ll_page_mkwrite0(struct vm_area_struct *vma, struct page *vmpage,
        if (IS_ERR(env))
                RETURN(PTR_ERR(env));
 
        if (IS_ERR(env))
                RETURN(PTR_ERR(env));
 
-       io = ll_fault_io_init(env, vma, vmpage->index);
+       io = ll_fault_io_init(env, vma, vmpage->index, true);
        if (IS_ERR(io))
                GOTO(out, result = PTR_ERR(io));
 
        if (IS_ERR(io))
                GOTO(out, result = PTR_ERR(io));
 
@@ -164,9 +168,6 @@ static int ll_page_mkwrite0(struct vm_area_struct *vma, struct page *vmpage,
        if (result < 0)
                GOTO(out_io, result);
 
        if (result < 0)
                GOTO(out_io, result);
 
-       io->u.ci_fault.ft_mkwrite = 1;
-       io->u.ci_fault.ft_writable = 1;
-
        vio = vvp_env_io(env);
        vio->u.fault.ft_vma    = vma;
        vio->u.fault.ft_vmpage = vmpage;
        vio = vvp_env_io(env);
        vio->u.fault.ft_vma    = vma;
        vio->u.fault.ft_vmpage = vmpage;
@@ -299,7 +300,7 @@ static vm_fault_t ll_fault0(struct vm_area_struct *vma, struct vm_fault *vmf)
                fault_ret = 0;
        }
 
                fault_ret = 0;
        }
 
-       io = ll_fault_io_init(env, vma, vmf->pgoff);
+       io = ll_fault_io_init(env, vma, vmf->pgoff, false);
        if (IS_ERR(io))
                GOTO(out, result = PTR_ERR(io));
 
        if (IS_ERR(io))
                GOTO(out, result = PTR_ERR(io));
 
index b7b953d..7530254 100644 (file)
@@ -368,8 +368,7 @@ static void vvp_io_fini(const struct lu_env *env, const struct cl_io_slice *ios)
                io->ci_need_write_intent = 0;
 
                LASSERT(io->ci_type == CIT_WRITE || cl_io_is_fallocate(io) ||
                io->ci_need_write_intent = 0;
 
                LASSERT(io->ci_type == CIT_WRITE || cl_io_is_fallocate(io) ||
-                       cl_io_is_trunc(io) || cl_io_is_mkwrite(io) ||
-                       cl_io_is_fault_writable(io));
+                       cl_io_is_trunc(io) || cl_io_is_mkwrite(io));
 
                CDEBUG(D_VFSTRACE, DFID" write layout, type %u "DEXT"\n",
                       PFID(lu_object_fid(&obj->co_lu)), io->ci_type,
 
                CDEBUG(D_VFSTRACE, DFID" write layout, type %u "DEXT"\n",
                       PFID(lu_object_fid(&obj->co_lu)), io->ci_type,
index 927bbed..56706b4 100644 (file)
@@ -227,8 +227,7 @@ static int lov_io_mirror_write_intent(struct lov_io *lio,
        io->ci_need_write_intent = 0;
 
        if (!(io->ci_type == CIT_WRITE || cl_io_is_mkwrite(io) ||
        io->ci_need_write_intent = 0;
 
        if (!(io->ci_type == CIT_WRITE || cl_io_is_mkwrite(io) ||
-             cl_io_is_fallocate(io) || cl_io_is_trunc(io) ||
-             cl_io_is_fault_writable(io)))
+             cl_io_is_fallocate(io) || cl_io_is_trunc(io)))
                RETURN(0);
 
        /*
                RETURN(0);
 
        /*
@@ -582,8 +581,7 @@ static int lov_io_slice_init(struct lov_io *lio,
        /* check if it needs to instantiate layout */
        if (!(io->ci_type == CIT_WRITE || cl_io_is_mkwrite(io) ||
              cl_io_is_fallocate(io) ||
        /* check if it needs to instantiate layout */
        if (!(io->ci_type == CIT_WRITE || cl_io_is_mkwrite(io) ||
              cl_io_is_fallocate(io) ||
-             (cl_io_is_trunc(io) && io->u.ci_setattr.sa_attr.lvb_size > 0)) ||
-             cl_io_is_fault_writable(io))
+             (cl_io_is_trunc(io) && io->u.ci_setattr.sa_attr.lvb_size > 0)))
                GOTO(out, result = 0);
 
        /*
                GOTO(out, result = 0);
 
        /*
index 6b17d52..a55936c 100644 (file)
@@ -467,7 +467,7 @@ static int cancel_lru_locks(char *filter)
                return -EINVAL;
 
        for (i = 0; i < paths.gl_pathc; i++) {
                return -EINVAL;
 
        for (i = 0; i < paths.gl_pathc; i++) {
-               FILE *f = fopen(paths.gl_pathv[i], "r");
+               FILE *f = fopen(paths.gl_pathv[i], "r+");
 
                if (!f) {
                        rc = -errno;
 
                if (!f) {
                        rc = -errno;
@@ -806,6 +806,67 @@ out:
        return rc;
 }
 
        return rc;
 }
 
+static int mmap_tst10(char *mnt)
+{
+       char *buf = MAP_FAILED;
+       char *buffer[256];
+       struct stat st1, st2;
+       long off;
+       int fd = -1;
+       int rc = 0;
+
+       /* cancel unused locks */
+       rc = cancel_lru_locks("osc");
+       if (rc)
+               goto out;
+
+       fd = open(mmap_sanity, O_RDONLY);
+       if (fd == -1) {
+               perror("open");
+               rc = -errno;
+               goto out;
+       }
+
+       if (fstat(fd, &st1) != 0) {
+               perror("fstat");
+               rc = -errno;
+               goto out;
+       }
+
+       sleep(1);
+
+       buf = mmap(NULL, st1.st_size, PROT_READ | PROT_WRITE,
+                  MAP_PRIVATE | MAP_NORESERVE, fd, 0);
+       if (buf == MAP_FAILED) {
+               perror("mmap");
+               rc = -errno;
+               goto out;
+       }
+
+       /* read some data */
+       for (off = 0; off + 256 <= st1.st_size; off += 256)
+               memcpy(buffer, off + buf, 256);
+
+       if (fstat(fd, &st2) != 0) {
+               perror("fstat");
+               rc = -errno;
+               goto out;
+       }
+
+       if (st1.st_mtime != st2.st_mtime) {
+               fprintf(stderr, "before mmap read mtime(%ld) != after mtime=(%ld)\n",
+                       st1.st_mtime, st2.st_mtime);
+               rc = -EINVAL;
+               goto out;
+       }
+out:
+       if (buf != MAP_FAILED)
+               munmap(buf, st1.st_size);
+       if (fd != -1)
+               close(fd);
+       return rc;
+}
+
 static int remote_tst(int tc, char *mnt)
 {
        int rc = 0;
 static int remote_tst(int tc, char *mnt)
 {
        int rc = 0;
@@ -889,6 +950,12 @@ struct test_case tests[] = {
                .node_cnt       = 1
        },
        {
                .node_cnt       = 1
        },
        {
+               .tc             = 10,
+               .desc           = "mmap test10: mtime not change for readonly mmap access",
+               .test_fn        = mmap_tst10,
+               .node_cnt       = 1
+       },
+       {
                .tc             = 0
        }
 };
                .tc             = 0
        }
 };