aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/ops_file.c2
-rw-r--r--fs/gfs2/ops_vm.c47
2 files changed, 23 insertions, 26 deletions
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index 581ac11b2656..1a5e8e893d75 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -364,8 +364,6 @@ static int gfs2_mmap(struct file *file, struct vm_area_struct *vma)
364 else 364 else
365 vma->vm_ops = &gfs2_vm_ops_private; 365 vma->vm_ops = &gfs2_vm_ops_private;
366 366
367 vma->vm_flags |= VM_CAN_INVALIDATE|VM_CAN_NONLINEAR;
368
369 gfs2_glock_dq_uninit(&i_gh); 367 gfs2_glock_dq_uninit(&i_gh);
370 368
371 return error; 369 return error;
diff --git a/fs/gfs2/ops_vm.c b/fs/gfs2/ops_vm.c
index e9fe6eb74e75..dc287d2e3a66 100644
--- a/fs/gfs2/ops_vm.c
+++ b/fs/gfs2/ops_vm.c
@@ -27,13 +27,12 @@
27#include "trans.h" 27#include "trans.h"
28#include "util.h" 28#include "util.h"
29 29
30static struct page *gfs2_private_fault(struct vm_area_struct *vma, 30static int gfs2_private_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
31 struct fault_data *fdata)
32{ 31{
33 struct gfs2_inode *ip = GFS2_I(vma->vm_file->f_mapping->host); 32 struct gfs2_inode *ip = GFS2_I(vma->vm_file->f_mapping->host);
34 33
35 set_bit(GIF_PAGED, &ip->i_flags); 34 set_bit(GIF_PAGED, &ip->i_flags);
36 return filemap_fault(vma, fdata); 35 return filemap_fault(vma, vmf);
37} 36}
38 37
39static int alloc_page_backing(struct gfs2_inode *ip, struct page *page) 38static int alloc_page_backing(struct gfs2_inode *ip, struct page *page)
@@ -104,55 +103,55 @@ out:
104 return error; 103 return error;
105} 104}
106 105
107static struct page *gfs2_sharewrite_fault(struct vm_area_struct *vma, 106static int gfs2_sharewrite_fault(struct vm_area_struct *vma,
108 struct fault_data *fdata) 107 struct vm_fault *vmf)
109{ 108{
110 struct file *file = vma->vm_file; 109 struct file *file = vma->vm_file;
111 struct gfs2_file *gf = file->private_data; 110 struct gfs2_file *gf = file->private_data;
112 struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); 111 struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
113 struct gfs2_holder i_gh; 112 struct gfs2_holder i_gh;
114 struct page *result = NULL;
115 int alloc_required; 113 int alloc_required;
116 int error; 114 int error;
115 int ret = VM_FAULT_MINOR;
117 116
118 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); 117 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh);
119 if (error) 118 if (error)
120 return NULL; 119 goto out;
121 120
122 set_bit(GIF_PAGED, &ip->i_flags); 121 set_bit(GIF_PAGED, &ip->i_flags);
123 set_bit(GIF_SW_PAGED, &ip->i_flags); 122 set_bit(GIF_SW_PAGED, &ip->i_flags);
124 123
125 error = gfs2_write_alloc_required(ip, 124 error = gfs2_write_alloc_required(ip,
126 (u64)fdata->pgoff << PAGE_CACHE_SHIFT, 125 (u64)vmf->pgoff << PAGE_CACHE_SHIFT,
127 PAGE_CACHE_SIZE, &alloc_required); 126 PAGE_CACHE_SIZE, &alloc_required);
128 if (error) { 127 if (error) {
129 fdata->type = VM_FAULT_OOM; /* XXX: are these right? */ 128 ret = VM_FAULT_OOM; /* XXX: are these right? */
130 goto out; 129 goto out_unlock;
131 } 130 }
132 131
133 set_bit(GFF_EXLOCK, &gf->f_flags); 132 set_bit(GFF_EXLOCK, &gf->f_flags);
134 result = filemap_fault(vma, fdata); 133 ret = filemap_fault(vma, vmf);
135 clear_bit(GFF_EXLOCK, &gf->f_flags); 134 clear_bit(GFF_EXLOCK, &gf->f_flags);
136 if (!result) 135 if (ret & (VM_FAULT_ERROR | FAULT_RET_NOPAGE))
137 goto out; 136 goto out_unlock;
138 137
139 if (alloc_required) { 138 if (alloc_required) {
140 error = alloc_page_backing(ip, result); 139 /* XXX: do we need to drop page lock around alloc_page_backing?*/
140 error = alloc_page_backing(ip, vmf->page);
141 if (error) { 141 if (error) {
142 if (vma->vm_flags & VM_CAN_INVALIDATE) 142 if (ret & FAULT_RET_LOCKED)
143 unlock_page(result); 143 unlock_page(vmf->page);
144 page_cache_release(result); 144 page_cache_release(vmf->page);
145 fdata->type = VM_FAULT_OOM; 145 ret = VM_FAULT_OOM;
146 result = NULL; 146 goto out_unlock;
147 goto out;
148 } 147 }
149 set_page_dirty(result); 148 set_page_dirty(vmf->page);
150 } 149 }
151 150
152out: 151out_unlock:
153 gfs2_glock_dq_uninit(&i_gh); 152 gfs2_glock_dq_uninit(&i_gh);
154 153out:
155 return result; 154 return ret;
156} 155}
157 156
158struct vm_operations_struct gfs2_vm_ops_private = { 157struct vm_operations_struct gfs2_vm_ops_private = {