1d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* 2d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * GPL HEADER START 3d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * 4d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * 6d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * This program is free software; you can redistribute it and/or modify 7d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * it under the terms of the GNU General Public License version 2 only, 8d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * as published by the Free Software Foundation. 9d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * 10d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * This program is distributed in the hope that it will be useful, but 11d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * WITHOUT ANY WARRANTY; without even the implied warranty of 12d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * General Public License version 2 for more details (a copy is included 14d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * in the LICENSE file that accompanied this code). 15d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * 16d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * You should have received a copy of the GNU General Public License 17d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * version 2 along with this program; If not, see 18d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf 19d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * 20d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 21d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * CA 95054 USA or visit www.sun.com if you need additional information or 22d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * have any questions. 23d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * 24d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * GPL HEADER END 25d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */ 26d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* 27d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 28d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Use is subject to license terms. 29d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * 30d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Copyright (c) 2011, 2012, Intel Corporation. 31d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */ 32d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* 33d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * This file is part of Lustre, http://www.lustre.org/ 34d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Lustre is a trademark of Sun Microsystems, Inc. 35d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */ 36d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 37d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#include <linux/kernel.h> 38d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#include <linux/mm.h> 39d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#include <linux/string.h> 40d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#include <linux/stat.h> 41d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#include <linux/errno.h> 42d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#include <linux/unistd.h> 43d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#include <asm/uaccess.h> 44d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 45d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#include <linux/fs.h> 46d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#include <linux/pagemap.h> 47d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 48d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#define DEBUG_SUBSYSTEM S_LLITE 49d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 5067a235f5e5893bc7dc86cf0e867fdb3f9041df18Greg Kroah-Hartman#include "../include/lustre_lite.h" 51d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#include "llite_internal.h" 5267a235f5e5893bc7dc86cf0e867fdb3f9041df18Greg Kroah-Hartman#include "../include/linux/lustre_compat25.h" 53d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 542d95f10e50da3eadd3f0a54f8b4b03db37ce879cJohn L. Hammondstatic const struct vm_operations_struct ll_file_vm_ops; 55d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 56d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid policy_from_vma(ldlm_policy_data_t *policy, 57d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct vm_area_struct *vma, unsigned long addr, 58d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao size_t count) 59d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{ 60d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao policy->l_extent.start = ((addr - vma->vm_start) & CFS_PAGE_MASK) + 61d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao (vma->vm_pgoff << PAGE_CACHE_SHIFT); 62d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao policy->l_extent.end = (policy->l_extent.start + count - 1) | 63d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao ~CFS_PAGE_MASK; 64d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao} 65d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 66d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostruct vm_area_struct *our_vma(struct mm_struct *mm, unsigned long addr, 67d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao size_t count) 68d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{ 69d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct vm_area_struct *vma, *ret = NULL; 70d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 71d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao /* mmap_sem must have been held by caller. */ 72d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao LASSERT(!down_write_trylock(&mm->mmap_sem)); 73d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 74a58a38ac0d94ccafdc1ae3c0ece750cbb9ca34c9Greg Donald for (vma = find_vma(mm, addr); 75d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao vma != NULL && vma->vm_start < (addr + count); vma = vma->vm_next) { 76d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao if (vma->vm_ops && vma->vm_ops == &ll_file_vm_ops && 77d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao vma->vm_flags & VM_SHARED) { 78d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao ret = vma; 79d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao break; 80d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao } 81d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao } 820a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman return ret; 83d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao} 84d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 85d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/** 86d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * API independent part for page fault initialization. 87d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param vma - virtual memory area addressed to page fault 88d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param env - corespondent lu_env to processing 89d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param nest - nested level 90d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param index - page index corespondent to fault. 91d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \parm ra_flags - vma readahead flags. 92d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * 93d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \return allocated and initialized env for fault operation. 94d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval EINVAL if env can't allocated 95d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \return other error codes from cl_io_init. 96d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */ 972d95f10e50da3eadd3f0a54f8b4b03db37ce879cJohn L. Hammondstatic struct cl_io * 982d95f10e50da3eadd3f0a54f8b4b03db37ce879cJohn L. Hammondll_fault_io_init(struct vm_area_struct *vma, struct lu_env **env_ret, 992d95f10e50da3eadd3f0a54f8b4b03db37ce879cJohn L. Hammond struct cl_env_nest *nest, pgoff_t index, 1002d95f10e50da3eadd3f0a54f8b4b03db37ce879cJohn L. Hammond unsigned long *ra_flags) 101d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{ 1028a48df7080b2fa0aed2b8df74437a39217c1eb8cJohn L. Hammond struct file *file = vma->vm_file; 1038a48df7080b2fa0aed2b8df74437a39217c1eb8cJohn L. Hammond struct inode *inode = file->f_dentry->d_inode; 1048a48df7080b2fa0aed2b8df74437a39217c1eb8cJohn L. Hammond struct cl_io *io; 1058a48df7080b2fa0aed2b8df74437a39217c1eb8cJohn L. Hammond struct cl_fault_io *fio; 1068a48df7080b2fa0aed2b8df74437a39217c1eb8cJohn L. Hammond struct lu_env *env; 1078a48df7080b2fa0aed2b8df74437a39217c1eb8cJohn L. Hammond int rc; 108d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 109d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *env_ret = NULL; 110d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao if (ll_file_nolock(file)) 1110a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman return ERR_PTR(-EOPNOTSUPP); 112d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 113d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao /* 114d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * page fault can be called when lustre IO is 115d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * already active for the current thread, e.g., when doing read/write 116d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * against user level buffer mapped from Lustre buffer. To avoid 117d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * stomping on existing context, optionally force an allocation of a new 118d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * one. 119d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */ 120d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao env = cl_env_nested_get(nest); 121d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao if (IS_ERR(env)) 1220a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman return ERR_PTR(-EINVAL); 123d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 124d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *env_ret = env; 125d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 126d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao io = ccc_env_thread_io(env); 127d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao io->ci_obj = ll_i2info(inode)->lli_clob; 128d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao LASSERT(io->ci_obj != NULL); 129d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 130d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao fio = &io->u.ci_fault; 131d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao fio->ft_index = index; 132d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao fio->ft_executable = vma->vm_flags&VM_EXEC; 133d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 134d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao /* 135d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * disable VM_SEQ_READ and use VM_RAND_READ to make sure that 136d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * the kernel will not read other pages not covered by ldlm in 137d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * filemap_nopage. we do our readahead in ll_readpage. 138d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */ 139d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao if (ra_flags != NULL) 140d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *ra_flags = vma->vm_flags & (VM_RAND_READ|VM_SEQ_READ); 141d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao vma->vm_flags &= ~VM_SEQ_READ; 142d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao vma->vm_flags |= VM_RAND_READ; 143d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 144d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao CDEBUG(D_MMAP, "vm_flags: %lx (%lu %d)\n", vma->vm_flags, 145d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao fio->ft_index, fio->ft_executable); 146d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 1478a48df7080b2fa0aed2b8df74437a39217c1eb8cJohn L. Hammond rc = cl_io_init(env, io, CIT_FAULT, io->ci_obj); 1488a48df7080b2fa0aed2b8df74437a39217c1eb8cJohn L. Hammond if (rc == 0) { 149d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct ccc_io *cio = ccc_env_io(env); 150d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct ll_file_data *fd = LUSTRE_FPRIVATE(file); 151d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 152d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao LASSERT(cio->cui_cl.cis_io == io); 153d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 1548a48df7080b2fa0aed2b8df74437a39217c1eb8cJohn L. Hammond /* mmap lock must be MANDATORY it has to cache 1558a48df7080b2fa0aed2b8df74437a39217c1eb8cJohn L. Hammond * pages. */ 156d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao io->ci_lockreq = CILR_MANDATORY; 1578a48df7080b2fa0aed2b8df74437a39217c1eb8cJohn L. Hammond cio->cui_fd = fd; 1588a48df7080b2fa0aed2b8df74437a39217c1eb8cJohn L. Hammond } else { 1598a48df7080b2fa0aed2b8df74437a39217c1eb8cJohn L. Hammond LASSERT(rc < 0); 1608a48df7080b2fa0aed2b8df74437a39217c1eb8cJohn L. Hammond cl_io_fini(env, io); 1618a48df7080b2fa0aed2b8df74437a39217c1eb8cJohn L. Hammond cl_env_nested_put(nest, env); 1628a48df7080b2fa0aed2b8df74437a39217c1eb8cJohn L. Hammond io = ERR_PTR(rc); 163d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao } 164d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 165d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao return io; 166d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao} 167d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 168d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* Sharing code of page_mkwrite method for rhel5 and rhel6 */ 169d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int ll_page_mkwrite0(struct vm_area_struct *vma, struct page *vmpage, 170d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao bool *retry) 171d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{ 172d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct lu_env *env; 173d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct cl_io *io; 174d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct vvp_io *vio; 175d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct cl_env_nest nest; 176d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao int result; 177d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao sigset_t set; 178d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct inode *inode; 179d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct ll_inode_info *lli; 180d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 181d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao LASSERT(vmpage != NULL); 182d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 183d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao io = ll_fault_io_init(vma, &env, &nest, vmpage->index, NULL); 18434e1f2bb1e7ab87c2b950189f7ccae57a72f25a8Julia Lawall if (IS_ERR(io)) { 18534e1f2bb1e7ab87c2b950189f7ccae57a72f25a8Julia Lawall result = PTR_ERR(io); 18634e1f2bb1e7ab87c2b950189f7ccae57a72f25a8Julia Lawall goto out; 18734e1f2bb1e7ab87c2b950189f7ccae57a72f25a8Julia Lawall } 188d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 189d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao result = io->ci_result; 190d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao if (result < 0) 19134e1f2bb1e7ab87c2b950189f7ccae57a72f25a8Julia Lawall goto out_io; 192d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 193d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao io->u.ci_fault.ft_mkwrite = 1; 194d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao io->u.ci_fault.ft_writable = 1; 195d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 196d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao vio = vvp_env_io(env); 197d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao vio->u.fault.ft_vma = vma; 198d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao vio->u.fault.ft_vmpage = vmpage; 199d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 200d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao set = cfs_block_sigsinv(sigmask(SIGKILL) | sigmask(SIGTERM)); 201d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 202d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao /* we grab lli_trunc_sem to exclude truncate case. 203d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Otherwise, we could add dirty pages into osc cache 204d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * while truncate is on-going. */ 205d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao inode = ccc_object_inode(io->ci_obj); 206d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao lli = ll_i2info(inode); 207d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao down_read(&lli->lli_trunc_sem); 208d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 209d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao result = cl_io_loop(env, io); 210d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 211d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao up_read(&lli->lli_trunc_sem); 212d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 213d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao cfs_restore_sigs(set); 214d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 215d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao if (result == 0) { 216d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct inode *inode = vma->vm_file->f_dentry->d_inode; 217d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct ll_inode_info *lli = ll_i2info(inode); 218d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 219d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao lock_page(vmpage); 220d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao if (vmpage->mapping == NULL) { 221d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao unlock_page(vmpage); 222d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 223d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao /* page was truncated and lock was cancelled, return 224d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * ENODATA so that VM_FAULT_NOPAGE will be returned 225d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * to handle_mm_fault(). */ 226d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao if (result == 0) 227d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao result = -ENODATA; 228d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao } else if (!PageDirty(vmpage)) { 229d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao /* race, the page has been cleaned by ptlrpcd after 230d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * it was unlocked, it has to be added into dirty 231d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * cache again otherwise this soon-to-dirty page won't 232d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * consume any grants, even worse if this page is being 233d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * transferred because it will break RPC checksum. 234d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */ 235d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao unlock_page(vmpage); 236d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 237d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao CDEBUG(D_MMAP, "Race on page_mkwrite %p/%lu, page has " 238d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao "been written out, retry.\n", 239d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao vmpage, vmpage->index); 240d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 241d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *retry = true; 242d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao result = -EAGAIN; 243d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao } 244d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 245d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao if (result == 0) { 246d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao spin_lock(&lli->lli_lock); 247d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao lli->lli_flags |= LLIF_DATA_MODIFIED; 248d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao spin_unlock(&lli->lli_lock); 249d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao } 250d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao } 251d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 2528a48df7080b2fa0aed2b8df74437a39217c1eb8cJohn L. Hammondout_io: 253d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao cl_io_fini(env, io); 254d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao cl_env_nested_put(&nest, env); 2558a48df7080b2fa0aed2b8df74437a39217c1eb8cJohn L. Hammondout: 256d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao CDEBUG(D_MMAP, "%s mkwrite with %d\n", current->comm, result); 257d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao LASSERT(ergo(result == 0, PageLocked(vmpage))); 2588a48df7080b2fa0aed2b8df74437a39217c1eb8cJohn L. Hammond 2598a48df7080b2fa0aed2b8df74437a39217c1eb8cJohn L. Hammond return result; 260d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao} 261d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 262d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 263d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 264d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic inline int to_fault_error(int result) 265d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{ 266a58a38ac0d94ccafdc1ae3c0ece750cbb9ca34c9Greg Donald switch (result) { 267d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao case 0: 268d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao result = VM_FAULT_LOCKED; 269d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao break; 270d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao case -EFAULT: 271d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao result = VM_FAULT_NOPAGE; 272d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao break; 273d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao case -ENOMEM: 274d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao result = VM_FAULT_OOM; 275d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao break; 276d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao default: 277d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao result = VM_FAULT_SIGBUS; 278d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao break; 279d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao } 280d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao return result; 281d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao} 282d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 283d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/** 284d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Lustre implementation of a vm_operations_struct::fault() method, called by 285d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * VM to server page fault (both in kernel and user space). 286d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * 287d0a0acc3ccf5a45c976fe94b15a1f9e9c4c78414Masanari Iida * \param vma - is virtual area struct related to page fault 288d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param vmf - structure which describe type and address where hit fault 289d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * 290d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \return allocated and filled _locked_ page for address 291d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval VM_FAULT_ERROR on general error 292d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval NOPAGE_OOM not have memory for allocate new page 293d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */ 294d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int ll_fault0(struct vm_area_struct *vma, struct vm_fault *vmf) 295d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{ 296d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct lu_env *env; 297d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct cl_io *io; 298d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct vvp_io *vio = NULL; 299d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct page *vmpage; 300d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao unsigned long ra_flags; 301d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct cl_env_nest nest; 302d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao int result; 303d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao int fault_ret = 0; 304d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 305d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao io = ll_fault_io_init(vma, &env, &nest, vmf->pgoff, &ra_flags); 306d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao if (IS_ERR(io)) 3070a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman return to_fault_error(PTR_ERR(io)); 308d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 309d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao result = io->ci_result; 310d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao if (result == 0) { 311d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao vio = vvp_env_io(env); 312d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao vio->u.fault.ft_vma = vma; 313d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao vio->u.fault.ft_vmpage = NULL; 314d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao vio->u.fault.fault.ft_vmf = vmf; 3156aa5107281ea065b9a7818a1c640e022d41a421bPaul Cassella vio->u.fault.fault.ft_flags = 0; 3166aa5107281ea065b9a7818a1c640e022d41a421bPaul Cassella vio->u.fault.fault.ft_flags_valid = 0; 317d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 318d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao result = cl_io_loop(env, io); 319d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 3206aa5107281ea065b9a7818a1c640e022d41a421bPaul Cassella /* ft_flags are only valid if we reached 3216aa5107281ea065b9a7818a1c640e022d41a421bPaul Cassella * the call to filemap_fault */ 3226aa5107281ea065b9a7818a1c640e022d41a421bPaul Cassella if (vio->u.fault.fault.ft_flags_valid) 3236aa5107281ea065b9a7818a1c640e022d41a421bPaul Cassella fault_ret = vio->u.fault.fault.ft_flags; 3246aa5107281ea065b9a7818a1c640e022d41a421bPaul Cassella 325d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao vmpage = vio->u.fault.ft_vmpage; 326d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao if (result != 0 && vmpage != NULL) { 327d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao page_cache_release(vmpage); 328d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao vmf->page = NULL; 329d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao } 330d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao } 331d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao cl_io_fini(env, io); 332d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao cl_env_nested_put(&nest, env); 333d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 334d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao vma->vm_flags |= ra_flags; 335d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao if (result != 0 && !(fault_ret & VM_FAULT_RETRY)) 336d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao fault_ret |= to_fault_error(result); 337d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 338d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao CDEBUG(D_MMAP, "%s fault %d/%d\n", 339d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao current->comm, fault_ret, result); 3400a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman return fault_ret; 341d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao} 342d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 343d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int ll_fault(struct vm_area_struct *vma, struct vm_fault *vmf) 344d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{ 345d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao int count = 0; 346d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao bool printed = false; 347d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao int result; 348d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao sigset_t set; 349d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 350d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao /* Only SIGKILL and SIGTERM is allowed for fault/nopage/mkwrite 351d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * so that it can be killed by admin but not cause segfault by 352d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * other signals. */ 353d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao set = cfs_block_sigsinv(sigmask(SIGKILL) | sigmask(SIGTERM)); 354d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 355d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taorestart: 356d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao result = ll_fault0(vma, vmf); 357d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao LASSERT(!(result & VM_FAULT_LOCKED)); 358d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao if (result == 0) { 359d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct page *vmpage = vmf->page; 360d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 361d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao /* check if this page has been truncated */ 362d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao lock_page(vmpage); 363d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao if (unlikely(vmpage->mapping == NULL)) { /* unlucky */ 364d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao unlock_page(vmpage); 365d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao page_cache_release(vmpage); 366d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao vmf->page = NULL; 367d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 368d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao if (!printed && ++count > 16) { 369d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao CWARN("the page is under heavy contention," 370d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao "maybe your app(%s) needs revising :-)\n", 371d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao current->comm); 372d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao printed = true; 373d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao } 374d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 375d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao goto restart; 376d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao } 377d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 37834d1f637cbf04eb88db10605338ccc6f8e9dedb8Georgiana Rodica Chelu result = VM_FAULT_LOCKED; 379d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao } 380d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao cfs_restore_sigs(set); 381d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao return result; 382d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao} 383d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 384d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int ll_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) 385d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{ 386d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao int count = 0; 387d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao bool printed = false; 388d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao bool retry; 389d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao int result; 390d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 391d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao do { 392d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao retry = false; 393d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao result = ll_page_mkwrite0(vma, vmf->page, &retry); 394d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 395d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao if (!printed && ++count > 16) { 396d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao CWARN("app(%s): the page %lu of file %lu is under heavy" 397d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao " contention.\n", 398d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao current->comm, vmf->pgoff, 399d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao vma->vm_file->f_dentry->d_inode->i_ino); 400d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao printed = true; 401d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao } 402d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao } while (retry); 403d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 404a58a38ac0d94ccafdc1ae3c0ece750cbb9ca34c9Greg Donald switch (result) { 405d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao case 0: 406d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao LASSERT(PageLocked(vmf->page)); 407d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao result = VM_FAULT_LOCKED; 408d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao break; 409d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao case -ENODATA: 410d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao case -EFAULT: 411d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao result = VM_FAULT_NOPAGE; 412d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao break; 413d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao case -ENOMEM: 414d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao result = VM_FAULT_OOM; 415d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao break; 416d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao case -EAGAIN: 417d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao result = VM_FAULT_RETRY; 418d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao break; 419d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao default: 420d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao result = VM_FAULT_SIGBUS; 421d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao break; 422d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao } 423d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 424d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao return result; 425d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao} 426d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 427d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/** 428d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * To avoid cancel the locks covering mmapped region for lock cache pressure, 429d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * we track the mapped vma count in ccc_object::cob_mmap_cnt. 430d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */ 431aff9d8e80489e2abe446094680009f6a23e8e6d7Greg Donaldstatic void ll_vm_open(struct vm_area_struct *vma) 432d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{ 433d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct inode *inode = vma->vm_file->f_dentry->d_inode; 434d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct ccc_object *vob = cl_inode2ccc(inode); 435d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 436d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao LASSERT(vma->vm_file); 437d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao LASSERT(atomic_read(&vob->cob_mmap_cnt) >= 0); 438d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao atomic_inc(&vob->cob_mmap_cnt); 439d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao} 440d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 441d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/** 442d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Dual to ll_vm_open(). 443d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */ 444d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic void ll_vm_close(struct vm_area_struct *vma) 445d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{ 446d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct inode *inode = vma->vm_file->f_dentry->d_inode; 447d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct ccc_object *vob = cl_inode2ccc(inode); 448d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 449d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao LASSERT(vma->vm_file); 450d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao atomic_dec(&vob->cob_mmap_cnt); 451d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao LASSERT(atomic_read(&vob->cob_mmap_cnt) >= 0); 452d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao} 453d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 454d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* XXX put nice comment here. talk about __free_pte -> dirty pages and 455d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * nopage's reference passing to the pte */ 456d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint ll_teardown_mmaps(struct address_space *mapping, __u64 first, __u64 last) 457d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{ 458d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao int rc = -ENOENT; 459d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 460b0f5aad587ea1fc3563d056609ee54a961ee1256Greg Kroah-Hartman LASSERTF(last > first, "last %llu first %llu\n", last, first); 461d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao if (mapping_mapped(mapping)) { 462d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao rc = 0; 463d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao unmap_mapping_range(mapping, first + PAGE_CACHE_SIZE - 1, 464d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao last - first + 1, 0); 465d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao } 466d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 4670a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman return rc; 468d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao} 469d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 4702d95f10e50da3eadd3f0a54f8b4b03db37ce879cJohn L. Hammondstatic const struct vm_operations_struct ll_file_vm_ops = { 471d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao .fault = ll_fault, 472d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao .page_mkwrite = ll_page_mkwrite, 473d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao .open = ll_vm_open, 474d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao .close = ll_vm_close, 475d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}; 476d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 477aff9d8e80489e2abe446094680009f6a23e8e6d7Greg Donaldint ll_file_mmap(struct file *file, struct vm_area_struct *vma) 478d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{ 479d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao struct inode *inode = file->f_dentry->d_inode; 480d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao int rc; 481d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 482d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao if (ll_file_nolock(file)) 4830a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman return -EOPNOTSUPP; 484d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 485d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_MAP, 1); 486d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao rc = generic_file_mmap(file, vma); 487d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao if (rc == 0) { 488d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao vma->vm_ops = &ll_file_vm_ops; 489d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao vma->vm_ops->open(vma); 490d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao /* update the inode's size and mtime */ 491d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao rc = ll_glimpse_size(inode); 492d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao } 493d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao 4940a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman return rc; 495d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao} 496