aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@aristanetworks.com>2010-09-20 03:56:27 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-10-22 13:16:43 -0400
commita6849fa1f7d7d7adbeb6a696beeabfa078acf173 (patch)
treee87b4051d0b1fce3a88abf68bfd8d7315db0a52a /fs/sysfs
parent5fc6e9cbce3342379719fc0f8294c45bb888f5cc (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>
Diffstat (limited to 'fs/sysfs')
-rw-r--r--fs/sysfs/bin.c26
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
193static 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
210static int bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf) 193static 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
332static const struct vm_operations_struct bin_vm_ops = { 315static 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;