X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fllite%2Fllite_mmap.c;h=c95566101f9ebefc8527159fd3dc84e20df07f3a;hp=ae43a0734d29481e20c230eea4126f9dbb87be0e;hb=84a795f90412ee575703476728f1522c06de4a2c;hpb=5467a860213d454759bdfad91503691d6692b317 diff --git a/lustre/llite/llite_mmap.c b/lustre/llite/llite_mmap.c index ae43a07..c955661 100644 --- a/lustre/llite/llite_mmap.c +++ b/lustre/llite/llite_mmap.c @@ -69,9 +69,6 @@ vma->vm_file->f_dentry->d_inode->i_ino, \ vma->vm_file->f_dentry->d_iname, ## arg); \ -struct page *ll_nopage(struct vm_area_struct *vma, unsigned long address, - int *type); - static struct vm_operations_struct ll_file_vm_ops; void policy_from_vma(ldlm_policy_data_t *policy, @@ -206,8 +203,8 @@ struct page *ll_nopage(struct vm_area_struct *vma, unsigned long address, struct lu_env *env; struct cl_env_nest nest; struct cl_io *io; - struct page *page = NOPAGE_SIGBUS; - struct vvp_io *vio = NULL; + struct page *page; + struct vvp_io *vio; unsigned long ra_flags; pgoff_t pg_offset; int result; @@ -223,22 +220,27 @@ struct page *ll_nopage(struct vm_area_struct *vma, unsigned long address, goto out_err; vio = vvp_env_io(env); - vio->u.fault.ft_vma = vma; + vio->u.fault.ft_vmpage = NULL; vio->u.fault.nopage.ft_address = address; vio->u.fault.nopage.ft_type = type; result = cl_io_loop(env, io); -out_err: - if (result == 0) { - LASSERT(io->u.ci_fault.ft_page != NULL); - page = vio->u.fault.ft_vmpage; - } else { - if (result == -ENOMEM) - page = NOPAGE_OOM; + page = vio->u.fault.ft_vmpage; + if (page != NULL) { + LASSERT(PageLocked(page)); + unlock_page(page); + + if (result != 0) + page_cache_release(page); } + LASSERT(ergo(result == 0, io->u.ci_fault.ft_page != NULL)); +out_err: + if (result != 0) + page = result == -ENOMEM ? NOPAGE_OOM : NOPAGE_SIGBUS; + vma->vm_flags &= ~VM_RAND_READ; vma->vm_flags |= ra_flags; @@ -263,7 +265,7 @@ int ll_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct lu_env *env; struct cl_io *io; - struct vvp_io *vio = NULL; + struct vvp_io *vio; unsigned long ra_flags; struct cl_env_nest nest; int result; @@ -279,13 +281,22 @@ int ll_fault(struct vm_area_struct *vma, struct vm_fault *vmf) goto out_err; vio = vvp_env_io(env); - vio->u.fault.ft_vma = vma; + vio->u.fault.ft_vmpage = NULL; vio->u.fault.fault.ft_vmf = vmf; result = cl_io_loop(env, io); - fault_ret = vio->u.fault.fault.ft_flags; + if (unlikely(result != 0 && vio->u.fault.ft_vmpage != NULL)) { + struct page *vmpage = vio->u.fault.ft_vmpage; + + LASSERT((vio->u.fault.fault.ft_flags & VM_FAULT_LOCKED) && + PageLocked(vmpage)); + unlock_page(vmpage); + page_cache_release(vmpage); + vmf->page = NULL; + } + fault_ret = vio->u.fault.fault.ft_flags; out_err: if (result != 0) fault_ret |= VM_FAULT_ERROR;