From: Qian Yingjin Date: Sat, 31 Jul 2021 07:45:56 +0000 (+0800) Subject: LU-14709 pcc: VM_WRITE should not trigger layout write X-Git-Tag: 2.14.55~40 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=373475a4f448c8e26a4dd7a3f88e7e962bc0b6e2 LU-14709 pcc: VM_WRITE should not trigger layout write 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 Change-Id: I1cbfef8a4ed7e2c718324fd8a21bafd6157b5f0c Reviewed-by: Patrick Farrell Reviewed-by: Andreas Dilger Reviewed-on: https://review.whamcloud.com/44483 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Bobi Jam Reviewed-by: Oleg Drokin --- diff --git a/lustre/include/cl_object.h b/lustre/include/cl_object.h index 4825804..145e683 100644 --- a/lustre/include/cl_object.h +++ b/lustre/include/cl_object.h @@ -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; } -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). */ diff --git a/lustre/llite/llite_mmap.c b/lustre/llite/llite_mmap.c index 4600c76..963aa07 100644 --- a/lustre/llite/llite_mmap.c +++ b/lustre/llite/llite_mmap.c @@ -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 mkwrite - whether it is mmap write. * * \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); @@ -102,6 +104,11 @@ restart: 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, @@ -112,9 +119,6 @@ restart: 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); @@ -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)); - 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)); @@ -164,9 +168,6 @@ static int ll_page_mkwrite0(struct vm_area_struct *vma, struct page *vmpage, 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; @@ -299,7 +300,7 @@ static vm_fault_t ll_fault0(struct vm_area_struct *vma, struct vm_fault *vmf) 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)); diff --git a/lustre/llite/vvp_io.c b/lustre/llite/vvp_io.c index b7b953d..7530254 100644 --- a/lustre/llite/vvp_io.c +++ b/lustre/llite/vvp_io.c @@ -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) || - 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, diff --git a/lustre/lov/lov_io.c b/lustre/lov/lov_io.c index 927bbed..56706b4 100644 --- a/lustre/lov/lov_io.c +++ b/lustre/lov/lov_io.c @@ -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) || - 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); /* @@ -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) || - (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); /* diff --git a/lustre/tests/mmap_sanity.c b/lustre/tests/mmap_sanity.c index 6b17d52..a55936c 100644 --- a/lustre/tests/mmap_sanity.c +++ b/lustre/tests/mmap_sanity.c @@ -467,7 +467,7 @@ static int cancel_lru_locks(char *filter) 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; @@ -806,6 +806,67 @@ out: 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; @@ -889,6 +950,12 @@ struct test_case tests[] = { .node_cnt = 1 }, { + .tc = 10, + .desc = "mmap test10: mtime not change for readonly mmap access", + .test_fn = mmap_tst10, + .node_cnt = 1 + }, + { .tc = 0 } };