From: John L. Hammond <john.hamm...@intel.com>

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().

Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3487
Lustre-change: http://review.whamcloud.com/6735
Signed-off-by: John L. Hammond <john.hamm...@intel.com>
Reviewed-by: Lai Siyao <lai.si...@intel.com>
Reviewed-by: Jinshan Xiong <jinshan.xi...@intel.com>
Reviewed-by: Oleg Drokin <oleg.dro...@intel.com>
Signed-off-by: Peng Tao <tao.p...@emc.com>
Signed-off-by: Andreas Dilger <andreas.dil...@intel.com>
---
 drivers/staging/lustre/lustre/llite/llite_mmap.c |   36 +++++++++++++---------
 1 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/llite_mmap.c 
b/drivers/staging/lustre/lustre/llite/llite_mmap.c
index d9590d8..8aa1dae 100644
--- a/drivers/staging/lustre/lustre/llite/llite_mmap.c
+++ b/drivers/staging/lustre/lustre/llite/llite_mmap.c
@@ -107,11 +107,12 @@ struct cl_io *ll_fault_io_init(struct vm_area_struct *vma,
                               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;
+       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;
@@ -152,17 +153,22 @@ 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) {
+       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. */
+               /* mmap lock must be MANDATORY it has to cache
+                * pages. */
                io->ci_lockreq = CILR_MANDATORY;
-
-               cio->cui_fd  = fd;
+               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;
@@ -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:
+out_io:
        cl_io_fini(env, io);
        cl_env_nested_put(&nest, env);
-
+out:
        CDEBUG(D_MMAP, "%s mkwrite with %d\n", current->comm, result);
-
        LASSERT(ergo(result == 0, PageLocked(vmpage)));
-       return(result);
+
+       return result;
 }
 
 
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to