xref: /openbmc/linux/fs/ocfs2/mmap.c (revision ccd979bdbce9fba8412beb3f1de68a9d0171b12c)
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