From 86586a487771c2903072cc18fb46771943dc1bdf Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Fri, 21 Jun 2013 09:29:55 -0500 Subject: [PATCH] LU-3487 llite: handle io init failure in ll_fault_io_init() In ll_fault_io_init(), if cl_io_init() has failed then cleanup and return an ERR_PTR(). This fixes an oops in the page fault handling code when a partially initialized io is used. In ll_page_mkwrite0() do not call cl_io_fini() on an ERR_PTR(). Signed-off-by: John L. Hammond Change-Id: I04b1c1f3071413ba3fa53bbbfcb83fe325ed9050 Reviewed-on: http://review.whamcloud.com/6735 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Lai Siyao Reviewed-by: Jinshan Xiong Reviewed-by: Oleg Drokin --- lustre/llite/llite_mmap.c | 64 ++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/lustre/llite/llite_mmap.c b/lustre/llite/llite_mmap.c index aa26615..a42cb46 100644 --- a/lustre/llite/llite_mmap.c +++ b/lustre/llite/llite_mmap.c @@ -103,16 +103,17 @@ struct vm_area_struct *our_vma(struct mm_struct *mm, unsigned long addr, * \return other error codes from cl_io_init. */ struct cl_io *ll_fault_io_init(struct vm_area_struct *vma, - struct lu_env **env_ret, - struct cl_env_nest *nest, - pgoff_t index, unsigned long *ra_flags) + struct lu_env **env_ret, + struct cl_env_nest *nest, + pgoff_t index, unsigned long *ra_flags) { - struct file *file = vma->vm_file; - struct inode *inode = file->f_dentry->d_inode; - struct cl_io *io; - struct cl_fault_io *fio; - struct lu_env *env; - ENTRY; + struct file *file = vma->vm_file; + struct inode *inode = file->f_dentry->d_inode; + struct cl_io *io; + struct cl_fault_io *fio; + struct lu_env *env; + int rc; + ENTRY; *env_ret = NULL; if (ll_file_nolock(file)) @@ -152,20 +153,25 @@ struct cl_io *ll_fault_io_init(struct vm_area_struct *vma, CDEBUG(D_MMAP, "vm_flags: %lx (%lu %d)\n", vma->vm_flags, fio->ft_index, fio->ft_executable); - if (cl_io_init(env, io, CIT_FAULT, io->ci_obj) == 0) { - struct ccc_io *cio = ccc_env_io(env); - struct ll_file_data *fd = LUSTRE_FPRIVATE(file); - - LASSERT(cio->cui_cl.cis_io == io); - - /* mmap lock must be MANDATORY - * it has to cache pages. */ - io->ci_lockreq = CILR_MANDATORY; - - cio->cui_fd = fd; - } + rc = cl_io_init(env, io, CIT_FAULT, io->ci_obj); + if (rc == 0) { + struct ccc_io *cio = ccc_env_io(env); + struct ll_file_data *fd = LUSTRE_FPRIVATE(file); + + LASSERT(cio->cui_cl.cis_io == io); + + /* mmap lock must be MANDATORY it has to cache + * pages. */ + io->ci_lockreq = CILR_MANDATORY; + cio->cui_fd = fd; + } else { + LASSERT(rc < 0); + cl_io_fini(env, io); + cl_env_nested_put(nest, env); + io = ERR_PTR(rc); + } - return io; + return io; } /* Sharing code of page_mkwrite method for rhel5 and rhel6 */ @@ -190,7 +196,7 @@ static int ll_page_mkwrite0(struct vm_area_struct *vma, struct page *vmpage, result = io->ci_result; if (result < 0) - GOTO(out, result); + GOTO(out_io, result); io->u.ci_fault.ft_mkwrite = 1; io->u.ci_fault.ft_writable = 1; @@ -252,14 +258,14 @@ static int ll_page_mkwrite0(struct vm_area_struct *vma, struct page *vmpage, } EXIT; +out_io: + cl_io_fini(env, io); + cl_env_nested_put(&nest, env); out: - cl_io_fini(env, io); - cl_env_nested_put(&nest, env); + CDEBUG(D_MMAP, "%s mkwrite with %d\n", cfs_current()->comm, result); + LASSERT(ergo(result == 0, PageLocked(vmpage))); - CDEBUG(D_MMAP, "%s mkwrite with %d\n", cfs_current()->comm, result); - - LASSERT(ergo(result == 0, PageLocked(vmpage))); - return(result); + return result; } -- 1.8.3.1