diff options
author | Eric W. Biederman <ebiederm@aristanetworks.com> | 2010-09-20 03:56:27 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-10-22 13:16:43 -0400 |
commit | a6849fa1f7d7d7adbeb6a696beeabfa078acf173 (patch) | |
tree | e87b4051d0b1fce3a88abf68bfd8d7315db0a52a | |
parent | 5fc6e9cbce3342379719fc0f8294c45bb888f5cc (diff) |
sysfs: Fail bin file mmap if vma close is implemented.
It is not reasonably possible to wrap vma->close(). To correctly
wrap close would imply calling close on any vmas that remain when
sysfs_remove_bin_file is called. Finding the proper lists walking
them getting the locking right etc, requires deep knowledge of the
mm subsystem and as such would require assistence from the mm
subsystem to implement. That assistence does not currently exist.
Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | fs/sysfs/bin.c | 26 |
1 files changed, 8 insertions, 18 deletions
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c index 4e321f7353fa..d31d7b7d5426 100644 --- a/fs/sysfs/bin.c +++ b/fs/sysfs/bin.c | |||
@@ -190,23 +190,6 @@ static void bin_vma_open(struct vm_area_struct *vma) | |||
190 | sysfs_put_active(attr_sd); | 190 | sysfs_put_active(attr_sd); |
191 | } | 191 | } |
192 | 192 | ||
193 | static void bin_vma_close(struct vm_area_struct *vma) | ||
194 | { | ||
195 | struct file *file = vma->vm_file; | ||
196 | struct bin_buffer *bb = file->private_data; | ||
197 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; | ||
198 | |||
199 | if (!bb->vm_ops || !bb->vm_ops->close) | ||
200 | return; | ||
201 | |||
202 | if (!sysfs_get_active(attr_sd)) | ||
203 | return; | ||
204 | |||
205 | bb->vm_ops->close(vma); | ||
206 | |||
207 | sysfs_put_active(attr_sd); | ||
208 | } | ||
209 | |||
210 | static int bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | 193 | static int bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
211 | { | 194 | { |
212 | struct file *file = vma->vm_file; | 195 | struct file *file = vma->vm_file; |
@@ -331,7 +314,6 @@ static int bin_migrate(struct vm_area_struct *vma, const nodemask_t *from, | |||
331 | 314 | ||
332 | static const struct vm_operations_struct bin_vm_ops = { | 315 | static const struct vm_operations_struct bin_vm_ops = { |
333 | .open = bin_vma_open, | 316 | .open = bin_vma_open, |
334 | .close = bin_vma_close, | ||
335 | .fault = bin_fault, | 317 | .fault = bin_fault, |
336 | .page_mkwrite = bin_page_mkwrite, | 318 | .page_mkwrite = bin_page_mkwrite, |
337 | .access = bin_access, | 319 | .access = bin_access, |
@@ -377,6 +359,14 @@ static int mmap(struct file *file, struct vm_area_struct *vma) | |||
377 | if (bb->mmapped && bb->vm_ops != vma->vm_ops) | 359 | if (bb->mmapped && bb->vm_ops != vma->vm_ops) |
378 | goto out_put; | 360 | goto out_put; |
379 | 361 | ||
362 | /* | ||
363 | * It is not possible to successfully wrap close. | ||
364 | * So error if someone is trying to use close. | ||
365 | */ | ||
366 | rc = -EINVAL; | ||
367 | if (vma->vm_ops && vma->vm_ops->close) | ||
368 | goto out_put; | ||
369 | |||
380 | rc = 0; | 370 | rc = 0; |
381 | bb->mmapped = 1; | 371 | bb->mmapped = 1; |
382 | bb->vm_ops = vma->vm_ops; | 372 | bb->vm_ops = vma->vm_ops; |