diff options
Diffstat (limited to 'fs/gfs2/ops_vm.c')
-rw-r--r-- | fs/gfs2/ops_vm.c | 47 |
1 files changed, 23 insertions, 24 deletions
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 | ||
30 | static struct page *gfs2_private_fault(struct vm_area_struct *vma, | 30 | static 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 | ||
39 | static int alloc_page_backing(struct gfs2_inode *ip, struct page *page) | 38 | static 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 | ||
107 | static struct page *gfs2_sharewrite_fault(struct vm_area_struct *vma, | 106 | static 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 | ||
152 | out: | 151 | out_unlock: |
153 | gfs2_glock_dq_uninit(&i_gh); | 152 | gfs2_glock_dq_uninit(&i_gh); |
154 | 153 | out: | |
155 | return result; | 154 | return ret; |
156 | } | 155 | } |
157 | 156 | ||
158 | struct vm_operations_struct gfs2_vm_ops_private = { | 157 | struct vm_operations_struct gfs2_vm_ops_private = { |