1ccd979bdSMark Fasheh /* -*- mode: c; c-basic-offset: 8; -*- 2ccd979bdSMark Fasheh * vim: noexpandtab sw=8 ts=8 sts=0: 3ccd979bdSMark Fasheh * 4ccd979bdSMark Fasheh * mmap.c 5ccd979bdSMark Fasheh * 6ccd979bdSMark Fasheh * Code to deal with the mess that is clustered mmap. 7ccd979bdSMark Fasheh * 8ccd979bdSMark Fasheh * Copyright (C) 2002, 2004 Oracle. All rights reserved. 9ccd979bdSMark Fasheh * 10ccd979bdSMark Fasheh * This program is free software; you can redistribute it and/or 11ccd979bdSMark Fasheh * modify it under the terms of the GNU General Public 12ccd979bdSMark Fasheh * License as published by the Free Software Foundation; either 13ccd979bdSMark Fasheh * version 2 of the License, or (at your option) any later version. 14ccd979bdSMark Fasheh * 15ccd979bdSMark Fasheh * This program is distributed in the hope that it will be useful, 16ccd979bdSMark Fasheh * but WITHOUT ANY WARRANTY; without even the implied warranty of 17ccd979bdSMark Fasheh * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18ccd979bdSMark Fasheh * General Public License for more details. 19ccd979bdSMark Fasheh * 20ccd979bdSMark Fasheh * You should have received a copy of the GNU General Public 21ccd979bdSMark Fasheh * License along with this program; if not, write to the 22ccd979bdSMark Fasheh * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 23ccd979bdSMark Fasheh * Boston, MA 021110-1307, USA. 24ccd979bdSMark Fasheh */ 25ccd979bdSMark Fasheh 26ccd979bdSMark Fasheh #include <linux/fs.h> 27ccd979bdSMark Fasheh #include <linux/types.h> 28ccd979bdSMark Fasheh #include <linux/slab.h> 29ccd979bdSMark Fasheh #include <linux/highmem.h> 30ccd979bdSMark Fasheh #include <linux/pagemap.h> 31ccd979bdSMark Fasheh #include <linux/uio.h> 32ccd979bdSMark Fasheh #include <linux/signal.h> 33ccd979bdSMark Fasheh #include <linux/rbtree.h> 34ccd979bdSMark Fasheh 35ccd979bdSMark Fasheh #define MLOG_MASK_PREFIX ML_FILE_IO 36ccd979bdSMark Fasheh #include <cluster/masklog.h> 37ccd979bdSMark Fasheh 38ccd979bdSMark Fasheh #include "ocfs2.h" 39ccd979bdSMark Fasheh 40ccd979bdSMark Fasheh #include "dlmglue.h" 41ccd979bdSMark Fasheh #include "file.h" 42ccd979bdSMark Fasheh #include "inode.h" 43ccd979bdSMark Fasheh #include "mmap.h" 44ccd979bdSMark Fasheh 45ccd979bdSMark Fasheh static struct page *ocfs2_nopage(struct vm_area_struct * area, 46ccd979bdSMark Fasheh unsigned long address, 47ccd979bdSMark Fasheh int *type) 48ccd979bdSMark Fasheh { 49ccd979bdSMark Fasheh struct page *page = NOPAGE_SIGBUS; 50ccd979bdSMark Fasheh sigset_t blocked, oldset; 51ccd979bdSMark Fasheh int ret; 52ccd979bdSMark Fasheh 532b388c67SJoel Becker mlog_entry("(area=%p, address=%lu, type=%p)\n", area, address, 542b388c67SJoel Becker type); 55ccd979bdSMark Fasheh 56ccd979bdSMark Fasheh /* The best way to deal with signals in this path is 57ccd979bdSMark Fasheh * to block them upfront, rather than allowing the 58ccd979bdSMark Fasheh * locking paths to return -ERESTARTSYS. */ 59ccd979bdSMark Fasheh sigfillset(&blocked); 60ccd979bdSMark Fasheh 61ccd979bdSMark Fasheh /* We should technically never get a bad ret return 62ccd979bdSMark Fasheh * from sigprocmask */ 63ccd979bdSMark Fasheh ret = sigprocmask(SIG_BLOCK, &blocked, &oldset); 64ccd979bdSMark Fasheh if (ret < 0) { 65ccd979bdSMark Fasheh mlog_errno(ret); 66ccd979bdSMark Fasheh goto out; 67ccd979bdSMark Fasheh } 68ccd979bdSMark Fasheh 69ccd979bdSMark Fasheh page = filemap_nopage(area, address, type); 70ccd979bdSMark Fasheh 71ccd979bdSMark Fasheh ret = sigprocmask(SIG_SETMASK, &oldset, NULL); 72ccd979bdSMark Fasheh if (ret < 0) 73ccd979bdSMark Fasheh mlog_errno(ret); 74ccd979bdSMark Fasheh out: 75ccd979bdSMark Fasheh mlog_exit_ptr(page); 76ccd979bdSMark Fasheh return page; 77ccd979bdSMark Fasheh } 78ccd979bdSMark Fasheh 79ccd979bdSMark Fasheh static struct vm_operations_struct ocfs2_file_vm_ops = { 80ccd979bdSMark Fasheh .nopage = ocfs2_nopage, 81ccd979bdSMark Fasheh }; 82ccd979bdSMark Fasheh 83870f4817SChristoph Hellwig int ocfs2_mmap(struct file *file, struct vm_area_struct *vma) 84ccd979bdSMark Fasheh { 85*25899deeSTiger Yang int ret = 0, lock_level = 0; 86*25899deeSTiger Yang 87ccd979bdSMark Fasheh /* We don't want to support shared writable mappings yet. */ 88ccd979bdSMark Fasheh if (((vma->vm_flags & VM_SHARED) || (vma->vm_flags & VM_MAYSHARE)) 89ccd979bdSMark Fasheh && ((vma->vm_flags & VM_WRITE) || (vma->vm_flags & VM_MAYWRITE))) { 90ccd979bdSMark Fasheh mlog(0, "disallow shared writable mmaps %lx\n", vma->vm_flags); 91ccd979bdSMark Fasheh /* This is -EINVAL because generic_file_readonly_mmap 92ccd979bdSMark Fasheh * returns it in a similar situation. */ 93ccd979bdSMark Fasheh return -EINVAL; 94ccd979bdSMark Fasheh } 95ccd979bdSMark Fasheh 96*25899deeSTiger Yang ret = ocfs2_meta_lock_atime(file->f_dentry->d_inode, 97*25899deeSTiger Yang file->f_vfsmnt, &lock_level); 98*25899deeSTiger Yang if (ret < 0) { 99*25899deeSTiger Yang mlog_errno(ret); 100*25899deeSTiger Yang goto out; 101*25899deeSTiger Yang } 102*25899deeSTiger Yang ocfs2_meta_unlock(file->f_dentry->d_inode, lock_level); 103*25899deeSTiger Yang out: 104ccd979bdSMark Fasheh vma->vm_ops = &ocfs2_file_vm_ops; 105ccd979bdSMark Fasheh return 0; 106ccd979bdSMark Fasheh } 107ccd979bdSMark Fasheh 108