diff options
-rw-r--r-- | mm/msync.c | 49 |
1 files changed, 26 insertions, 23 deletions
diff --git a/mm/msync.c b/mm/msync.c index 8a66f5d5d4f0..ee9bd6759833 100644 --- a/mm/msync.c +++ b/mm/msync.c | |||
@@ -132,35 +132,14 @@ static int msync_interval(struct vm_area_struct *vma, unsigned long addr, | |||
132 | unsigned long end, int flags, | 132 | unsigned long end, int flags, |
133 | unsigned long *nr_pages_dirtied) | 133 | unsigned long *nr_pages_dirtied) |
134 | { | 134 | { |
135 | int ret = 0; | ||
136 | struct file *file = vma->vm_file; | 135 | struct file *file = vma->vm_file; |
137 | 136 | ||
138 | if ((flags & MS_INVALIDATE) && (vma->vm_flags & VM_LOCKED)) | 137 | if ((flags & MS_INVALIDATE) && (vma->vm_flags & VM_LOCKED)) |
139 | return -EBUSY; | 138 | return -EBUSY; |
140 | 139 | ||
141 | if (file && (vma->vm_flags & VM_SHARED)) { | 140 | if (file && (vma->vm_flags & VM_SHARED)) |
142 | *nr_pages_dirtied = msync_page_range(vma, addr, end); | 141 | *nr_pages_dirtied = msync_page_range(vma, addr, end); |
143 | 142 | return 0; | |
144 | if (flags & MS_SYNC) { | ||
145 | struct address_space *mapping = file->f_mapping; | ||
146 | int err; | ||
147 | |||
148 | ret = filemap_fdatawrite(mapping); | ||
149 | if (file->f_op && file->f_op->fsync) { | ||
150 | /* | ||
151 | * We don't take i_mutex here because mmap_sem | ||
152 | * is already held. | ||
153 | */ | ||
154 | err = file->f_op->fsync(file,file->f_dentry,1); | ||
155 | if (err && !ret) | ||
156 | ret = err; | ||
157 | } | ||
158 | err = filemap_fdatawait(mapping); | ||
159 | if (!ret) | ||
160 | ret = err; | ||
161 | } | ||
162 | } | ||
163 | return ret; | ||
164 | } | 143 | } |
165 | 144 | ||
166 | asmlinkage long sys_msync(unsigned long start, size_t len, int flags) | 145 | asmlinkage long sys_msync(unsigned long start, size_t len, int flags) |
@@ -233,6 +212,30 @@ asmlinkage long sys_msync(unsigned long start, size_t len, int flags) | |||
233 | fput(file); | 212 | fput(file); |
234 | down_read(¤t->mm->mmap_sem); | 213 | down_read(¤t->mm->mmap_sem); |
235 | vma = find_vma(current->mm, start); | 214 | vma = find_vma(current->mm, start); |
215 | } else if ((flags & MS_SYNC) && file && | ||
216 | (vma->vm_flags & VM_SHARED)) { | ||
217 | struct address_space *mapping; | ||
218 | int err; | ||
219 | |||
220 | get_file(file); | ||
221 | up_read(¤t->mm->mmap_sem); | ||
222 | mapping = file->f_mapping; | ||
223 | error = filemap_fdatawrite(mapping); | ||
224 | if (file->f_op && file->f_op->fsync) { | ||
225 | mutex_lock(&mapping->host->i_mutex); | ||
226 | err = file->f_op->fsync(file,file->f_dentry,1); | ||
227 | mutex_unlock(&mapping->host->i_mutex); | ||
228 | if (err && !error) | ||
229 | error = err; | ||
230 | } | ||
231 | err = filemap_fdatawait(mapping); | ||
232 | if (err && !error) | ||
233 | error = err; | ||
234 | fput(file); | ||
235 | down_read(¤t->mm->mmap_sem); | ||
236 | if (error) | ||
237 | goto out_unlock; | ||
238 | vma = find_vma(current->mm, start); | ||
236 | } else { | 239 | } else { |
237 | vma = vma->vm_next; | 240 | vma = vma->vm_next; |
238 | } | 241 | } |