diff options
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/ops_address.c | 2 | ||||
-rw-r--r-- | fs/gfs2/ops_file.c | 2 | ||||
-rw-r--r-- | fs/gfs2/ops_vm.c | 36 |
3 files changed, 21 insertions, 19 deletions
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index 26c888890c24..ce90032c010e 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c | |||
@@ -251,7 +251,7 @@ static int gfs2_readpage(struct file *file, struct page *page) | |||
251 | if (file) { | 251 | if (file) { |
252 | gf = file->private_data; | 252 | gf = file->private_data; |
253 | if (test_bit(GFF_EXLOCK, &gf->f_flags)) | 253 | if (test_bit(GFF_EXLOCK, &gf->f_flags)) |
254 | /* gfs2_sharewrite_nopage has grabbed the ip->i_gl already */ | 254 | /* gfs2_sharewrite_fault has grabbed the ip->i_gl already */ |
255 | goto skip_lock; | 255 | goto skip_lock; |
256 | } | 256 | } |
257 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|LM_FLAG_TRY_1CB, &gh); | 257 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|LM_FLAG_TRY_1CB, &gh); |
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index bad0b24cb773..581ac11b2656 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/ops_file.c | |||
@@ -364,7 +364,7 @@ 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; | 367 | vma->vm_flags |= VM_CAN_INVALIDATE|VM_CAN_NONLINEAR; |
368 | 368 | ||
369 | gfs2_glock_dq_uninit(&i_gh); | 369 | gfs2_glock_dq_uninit(&i_gh); |
370 | 370 | ||
diff --git a/fs/gfs2/ops_vm.c b/fs/gfs2/ops_vm.c index d5a98cbfebdc..e9fe6eb74e75 100644 --- a/fs/gfs2/ops_vm.c +++ b/fs/gfs2/ops_vm.c | |||
@@ -27,13 +27,13 @@ | |||
27 | #include "trans.h" | 27 | #include "trans.h" |
28 | #include "util.h" | 28 | #include "util.h" |
29 | 29 | ||
30 | static struct page *gfs2_private_nopage(struct vm_area_struct *area, | 30 | static struct page *gfs2_private_fault(struct vm_area_struct *vma, |
31 | unsigned long address, int *type) | 31 | struct fault_data *fdata) |
32 | { | 32 | { |
33 | struct gfs2_inode *ip = GFS2_I(area->vm_file->f_mapping->host); | 33 | struct gfs2_inode *ip = GFS2_I(vma->vm_file->f_mapping->host); |
34 | 34 | ||
35 | set_bit(GIF_PAGED, &ip->i_flags); | 35 | set_bit(GIF_PAGED, &ip->i_flags); |
36 | return filemap_nopage(area, address, type); | 36 | return filemap_fault(vma, fdata); |
37 | } | 37 | } |
38 | 38 | ||
39 | static int alloc_page_backing(struct gfs2_inode *ip, struct page *page) | 39 | static int alloc_page_backing(struct gfs2_inode *ip, struct page *page) |
@@ -104,16 +104,14 @@ out: | |||
104 | return error; | 104 | return error; |
105 | } | 105 | } |
106 | 106 | ||
107 | static struct page *gfs2_sharewrite_nopage(struct vm_area_struct *area, | 107 | static struct page *gfs2_sharewrite_fault(struct vm_area_struct *vma, |
108 | unsigned long address, int *type) | 108 | struct fault_data *fdata) |
109 | { | 109 | { |
110 | struct file *file = area->vm_file; | 110 | struct file *file = vma->vm_file; |
111 | struct gfs2_file *gf = file->private_data; | 111 | struct gfs2_file *gf = file->private_data; |
112 | struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); | 112 | struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); |
113 | struct gfs2_holder i_gh; | 113 | struct gfs2_holder i_gh; |
114 | struct page *result = NULL; | 114 | struct page *result = NULL; |
115 | unsigned long index = ((address - area->vm_start) >> PAGE_CACHE_SHIFT) + | ||
116 | area->vm_pgoff; | ||
117 | int alloc_required; | 115 | int alloc_required; |
118 | int error; | 116 | int error; |
119 | 117 | ||
@@ -124,23 +122,27 @@ static struct page *gfs2_sharewrite_nopage(struct vm_area_struct *area, | |||
124 | set_bit(GIF_PAGED, &ip->i_flags); | 122 | set_bit(GIF_PAGED, &ip->i_flags); |
125 | set_bit(GIF_SW_PAGED, &ip->i_flags); | 123 | set_bit(GIF_SW_PAGED, &ip->i_flags); |
126 | 124 | ||
127 | error = gfs2_write_alloc_required(ip, (u64)index << PAGE_CACHE_SHIFT, | 125 | error = gfs2_write_alloc_required(ip, |
128 | PAGE_CACHE_SIZE, &alloc_required); | 126 | (u64)fdata->pgoff << PAGE_CACHE_SHIFT, |
129 | if (error) | 127 | PAGE_CACHE_SIZE, &alloc_required); |
128 | if (error) { | ||
129 | fdata->type = VM_FAULT_OOM; /* XXX: are these right? */ | ||
130 | goto out; | 130 | goto out; |
131 | } | ||
131 | 132 | ||
132 | set_bit(GFF_EXLOCK, &gf->f_flags); | 133 | set_bit(GFF_EXLOCK, &gf->f_flags); |
133 | result = filemap_nopage(area, address, type); | 134 | result = filemap_fault(vma, fdata); |
134 | clear_bit(GFF_EXLOCK, &gf->f_flags); | 135 | clear_bit(GFF_EXLOCK, &gf->f_flags); |
135 | if (!result || result == NOPAGE_OOM) | 136 | if (!result) |
136 | goto out; | 137 | goto out; |
137 | 138 | ||
138 | if (alloc_required) { | 139 | if (alloc_required) { |
139 | error = alloc_page_backing(ip, result); | 140 | error = alloc_page_backing(ip, result); |
140 | if (error) { | 141 | if (error) { |
141 | if (area->vm_flags & VM_CAN_INVALIDATE) | 142 | if (vma->vm_flags & VM_CAN_INVALIDATE) |
142 | unlock_page(result); | 143 | unlock_page(result); |
143 | page_cache_release(result); | 144 | page_cache_release(result); |
145 | fdata->type = VM_FAULT_OOM; | ||
144 | result = NULL; | 146 | result = NULL; |
145 | goto out; | 147 | goto out; |
146 | } | 148 | } |
@@ -154,10 +156,10 @@ out: | |||
154 | } | 156 | } |
155 | 157 | ||
156 | struct vm_operations_struct gfs2_vm_ops_private = { | 158 | struct vm_operations_struct gfs2_vm_ops_private = { |
157 | .nopage = gfs2_private_nopage, | 159 | .fault = gfs2_private_fault, |
158 | }; | 160 | }; |
159 | 161 | ||
160 | struct vm_operations_struct gfs2_vm_ops_sharewrite = { | 162 | struct vm_operations_struct gfs2_vm_ops_sharewrite = { |
161 | .nopage = gfs2_sharewrite_nopage, | 163 | .fault = gfs2_sharewrite_fault, |
162 | }; | 164 | }; |
163 | 165 | ||