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