From: Jinshan Xiong Date: Fri, 13 Apr 2012 22:21:49 +0000 (-0700) Subject: LU-1323 llite: find_vma() should be protected by mmap_sem X-Git-Tag: 2.2.55~41 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=5eb306e7634ab825306b850226ef9b199a888759 LU-1323 llite: find_vma() should be protected by mmap_sem It had been wrongly protected by page_table_lock since 2004. Signed-off-by: Jinshan Xiong Change-Id: Id7b0341dc8c385ad57e195d94f4e76b6c5626515 Reviewed-on: http://review.whamcloud.com/2543 Tested-by: Hudson Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Oleg Drokin --- diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 0932b3c..8d0cf47 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -1039,7 +1039,8 @@ struct ll_lock_tree_node * ll_node_from_inode(struct inode *inode, __u64 start, __u64 end, ldlm_mode_t mode); void policy_from_vma(ldlm_policy_data_t *policy, struct vm_area_struct *vma, unsigned long addr, size_t count); -struct vm_area_struct *our_vma(unsigned long addr, size_t count); +struct vm_area_struct *our_vma(struct mm_struct *mm, unsigned long addr, + size_t count); static inline void ll_invalidate_page(struct page *vmpage) { diff --git a/lustre/llite/llite_mmap.c b/lustre/llite/llite_mmap.c index dc40818..00e0c1a 100644 --- a/lustre/llite/llite_mmap.c +++ b/lustre/llite/llite_mmap.c @@ -76,17 +76,15 @@ void policy_from_vma(ldlm_policy_data_t *policy, ~CFS_PAGE_MASK; } -struct vm_area_struct * our_vma(unsigned long addr, size_t count) +struct vm_area_struct *our_vma(struct mm_struct *mm, unsigned long addr, + size_t count) { - struct mm_struct *mm = current->mm; struct vm_area_struct *vma, *ret = NULL; ENTRY; - /* No MM (e.g. NFS)? No vmas too. */ - if (!mm) - RETURN(NULL); + /* mmap_sem must have been held by caller. */ + LASSERT(!down_write_trylock(&mm->mmap_sem)); - spin_lock(&mm->page_table_lock); for(vma = find_vma(mm, addr); vma != NULL && vma->vm_start < (addr + count); vma = vma->vm_next) { if (vma->vm_ops && vma->vm_ops == &ll_file_vm_ops && @@ -95,7 +93,6 @@ struct vm_area_struct * our_vma(unsigned long addr, size_t count) break; } } - spin_unlock(&mm->page_table_lock); RETURN(ret); } diff --git a/lustre/llite/vvp_io.c b/lustre/llite/vvp_io.c index 2f83fc2..d45cc26 100644 --- a/lustre/llite/vvp_io.c +++ b/lustre/llite/vvp_io.c @@ -130,6 +130,7 @@ static int vvp_mmap_locks(const struct lu_env *env, struct ccc_io *vio, struct cl_io *io) { struct ccc_thread_info *cti = ccc_env_info(env); + struct mm_struct *mm = current->mm; struct vm_area_struct *vma; struct cl_lock_descr *descr = &cti->cti_descr; ldlm_policy_data_t policy; @@ -147,6 +148,10 @@ static int vvp_mmap_locks(const struct lu_env *env, if (vio->cui_iov == NULL) /* nfs or loop back device write */ RETURN(0); + /* No MM (e.g. NFS)? No vmas too. */ + if (mm == NULL) + RETURN(0); + for (seg = 0; seg < vio->cui_nrsegs; seg++) { const struct iovec *iv = &vio->cui_iov[seg]; @@ -157,12 +162,14 @@ static int vvp_mmap_locks(const struct lu_env *env, count += addr & (~CFS_PAGE_MASK); addr &= CFS_PAGE_MASK; - while((vma = our_vma(addr, count)) != NULL) { + + down_read(&mm->mmap_sem); + while((vma = our_vma(mm, addr, count)) != NULL) { struct inode *inode = vma->vm_file->f_dentry->d_inode; int flags = CEF_MUST; if (ll_file_nolock(vma->vm_file)) { - /* + /* * For no lock case, a lockless lock will be * generated. */ @@ -197,6 +204,7 @@ static int vvp_mmap_locks(const struct lu_env *env, count -= vma->vm_end - addr; addr = vma->vm_end; } + up_read(&mm->mmap_sem); } RETURN(0); }